28
28
#include " clang/Rewrite/Core/RewriteBuffer.h"
29
29
#include " llvm/Support/FileSystem.h"
30
30
#include " swift/IDE/APIDigesterData.h"
31
+ #include " swift/Basic/Defer.h"
31
32
32
33
using namespace swift ;
33
34
using namespace swift ::migrator;
@@ -302,13 +303,12 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
302
303
return false ;
303
304
}
304
305
306
+ std::set<std::string> InsertedFunctions;
305
307
SourceLoc FileEndLoc;
306
- llvm::SmallSet<StringRef, 4 > InsertedFunctions;
307
-
308
308
APIDiffMigratorPass (EditorAdapter &Editor, SourceFile *SF,
309
- const MigratorOptions &Opts)
310
- : ASTMigratorPass(Editor, SF, Opts),
311
- FileEndLoc (SM.getRangeForBuffer(BufferID).getEnd()) {}
309
+ const MigratorOptions &Opts):
310
+ ASTMigratorPass (Editor, SF, Opts),
311
+ FileEndLoc (SM.getRangeForBuffer(BufferID).getEnd()) {}
312
312
313
313
void run () {
314
314
if (Opts.APIDigesterDataStorePaths .empty ())
@@ -702,52 +702,62 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
702
702
}
703
703
704
704
StringRef insertHelperFunction (NodeAnnotation Anno, StringRef NewType,
705
- SmallString<256 > &Buffer) {
705
+ SmallString<256 > &Buffer, bool FromString ) {
706
706
llvm::raw_svector_ostream OS (Buffer);
707
707
OS << " \n " ;
708
708
OS << " // Helper function inserted by Swift 4.2 migrator.\n " ;
709
709
OS << " fileprivate func " ;
710
710
unsigned FuncNameStart = Buffer.size ();
711
- OS << " convertTo" ;
711
+ OS << (FromString ? " convertTo" : " convertFrom " ) ;
712
712
SmallVector<std::string, 8 > Segs;
713
+ StringRef guard = " \t guard let input = input else { return nil }\n " ;
713
714
switch (Anno) {
714
715
case NodeAnnotation::OptionalArrayMemberUpdate:
715
716
Segs = {" Optional" , " Array" , " [String]?" };
716
717
Segs.push_back ((Twine (" [" ) + NewType +" ]?" ).str ());
717
- Segs.push_back (Twine (" \t guard let input = input else { return nil } \n "
718
- " \t return input.map { key in " + NewType + " ( key) }" ).str ());
718
+ Segs.push_back (( Twine (guard) + " \t return input.map { key in " + NewType + " (key) } " ). str ());
719
+ Segs. push_back (( Twine (guard) + " \t return input.map { key in key.rawValue }" ).str ());
719
720
break ;
720
721
case NodeAnnotation::OptionalDictionaryKeyUpdate:
721
722
Segs = {" Optional" , " Dictionary" , " [String: Any]?" };
722
723
Segs.push_back ((Twine (" [" ) + NewType +" : Any]?" ).str ());
723
- Segs.push_back ((Twine (" \t guard let input = input else { return nil }\n "
724
- " \t return Dictionary(uniqueKeysWithValues: input.map"
725
- " { key, value in (" ) + NewType + " (rawValue: key), value)})" ).str ());
724
+ Segs.push_back ((Twine (guard) +
725
+ " \t return Dictionary(uniqueKeysWithValues: input.map"
726
+ " { key, value in (" + NewType + " (rawValue: key), value)})" ).str ());
727
+ Segs.push_back ((Twine (guard) +
728
+ " \t return Dictionary(uniqueKeysWithValues: input.map"
729
+ " {key, value in (key.rawValue, value)})" ).str ());
726
730
break ;
727
731
case NodeAnnotation::ArrayMemberUpdate:
728
732
Segs = {" " , " Array" , " [String]" };
729
733
Segs.push_back ((Twine (" [" ) + NewType +" ]" ).str ());
730
- Segs.push_back (Twine (" \t return input.map { key in " + NewType +" (key) }" ).str ());
734
+ Segs.push_back ((Twine (" \t return input.map { key in " ) + NewType +" (key) }" ).str ());
735
+ Segs.push_back (" \t return input.map { key in key.rawValue }" );
731
736
break ;
732
737
case NodeAnnotation::DictionaryKeyUpdate:
733
738
Segs = {" " , " Dictionary" , " [String: Any]" };
734
739
Segs.push_back ((Twine (" [" ) + NewType +" : Any]" ).str ());
735
740
Segs.push_back ((Twine (" \t return Dictionary(uniqueKeysWithValues: input.map"
736
741
" { key, value in (" ) + NewType + " (rawValue: key), value)})" ).str ());
742
+ Segs.push_back (" \t return Dictionary(uniqueKeysWithValues: input.map"
743
+ " {key, value in (key.rawValue, value)})" );
737
744
break ;
738
745
case NodeAnnotation::SimpleStringRepresentableUpdate:
739
746
Segs = {" " , " " , " String" };
740
747
Segs.push_back (NewType);
741
- Segs.push_back (" // Not implemented" );
748
+ Segs.push_back ((Twine (" \t return " ) + NewType + " (rawValue: input)" ).str ());
749
+ Segs.push_back (" \t return input.rawValue" );
742
750
break ;
743
751
case NodeAnnotation::SimpleOptionalStringRepresentableUpdate:
744
752
Segs = {" Optional" , " " , " String?" };
745
753
Segs.push_back ((Twine (NewType) +" ?" ).str ());
746
- Segs.push_back (" // Not implemented" );
754
+ Segs.push_back ((Twine (guard) + " \t return " + NewType + " (rawValue: input)" ).str ());
755
+ Segs.push_back ((Twine (guard) + " \t return input.rawValue" ).str ());
747
756
break ;
748
757
default :
749
758
llvm_unreachable (" shouldn't handle this key." );
750
759
}
760
+ assert (Segs.size () == 6 );
751
761
OS << Segs[0 ];
752
762
SmallVector<StringRef, 4 > Parts;
753
763
NewType.split (Parts, ' .' );
@@ -756,15 +766,22 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
756
766
OS << Segs[1 ];
757
767
auto FuncName = Buffer.str ().substr (FuncNameStart);
758
768
if (!InsertedFunctions.count (FuncName)) {
759
- OS << " (_ input: " << Segs[2 ] << " ) -> " << Segs[3 ] << " {\n " ;
760
- OS << Segs[4 ] << " \n }\n " ;
769
+ if (FromString) {
770
+ OS << " (_ input: " << Segs[2 ] << " ) -> " << Segs[3 ] << " {\n " ;
771
+ OS << Segs[4 ] << " \n }\n " ;
772
+ } else {
773
+ OS << " (_ input: " << Segs[3 ] << " ) -> " << Segs[2 ] << " {\n " ;
774
+ OS << Segs[5 ] << " \n }\n " ;
775
+ }
761
776
Editor.insert (FileEndLoc, OS.str ());
762
777
InsertedFunctions.insert (FuncName);
763
778
}
764
779
return FuncName;
765
780
}
766
781
767
- void handleStringRepresentableArg (ValueDecl *FD, Expr *Arg) {
782
+ void handleStringRepresentableArg (ValueDecl *FD, Expr *Arg, Expr *Call) {
783
+ Editor.disableCache ();
784
+ SWIFT_DEFER { Editor.enableCache (); };
768
785
NodeAnnotation Kind;
769
786
StringRef NewAttributeType;
770
787
uint8_t ArgIdx;
@@ -781,18 +798,20 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
781
798
}
782
799
if (NewAttributeType.empty ())
783
800
return ;
801
+ SmallString<256 > Buffer;
802
+ auto FuncName = insertHelperFunction (Kind, NewAttributeType, Buffer,
803
+ /* FromString*/ ArgIdx);
784
804
if (ArgIdx) {
785
805
ArgIdx --;
786
806
auto AllArgs = getCallArgInfo (SM, Arg, LabelRangeEndAt::LabelNameOnly);
787
807
if (AllArgs.size () <= ArgIdx)
788
808
return ;
789
- SmallString<256 > Buffer;
790
- auto FuncName = insertHelperFunction (Kind, NewAttributeType, Buffer);
791
809
auto Exp = AllArgs[ArgIdx].ArgExp ;
792
810
Editor.insert (Exp->getStartLoc (), (Twine (FuncName) + " (" ).str ());
793
811
Editor.insertAfterToken (Exp->getEndLoc (), " )" );
794
812
} else {
795
- // FIXME: return value migration.
813
+ Editor.insert (Call->getStartLoc (), (Twine (FuncName) + " (" ).str ());
814
+ Editor.insertAfterToken (Call->getEndLoc (), " )" );
796
815
}
797
816
}
798
817
@@ -810,7 +829,7 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
810
829
handleFuncRename (FD, Fn, Args);
811
830
handleTypeHoist (FD, CE, Args);
812
831
handleSpecialCases (FD, CE, Args);
813
- handleStringRepresentableArg (FD, Args);
832
+ handleStringRepresentableArg (FD, Args, CE );
814
833
}
815
834
break ;
816
835
}
@@ -820,7 +839,7 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
820
839
handleFuncRename (FD, DSC->getFn (), Args);
821
840
handleFunctionCallToPropertyChange (FD, DSC->getFn (), Args);
822
841
handleSpecialCases (FD, CE, Args);
823
- handleStringRepresentableArg (FD, Args);
842
+ handleStringRepresentableArg (FD, Args, CE );
824
843
}
825
844
break ;
826
845
}
@@ -829,7 +848,7 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
829
848
if (auto FD = CCE->getFn ()->getReferencedDecl ().getDecl ()) {
830
849
auto *CE = CCE->getFn ();
831
850
handleFuncRename (FD, CE, Args);
832
- handleStringRepresentableArg (FD, Args);
851
+ handleStringRepresentableArg (FD, Args, CE );
833
852
}
834
853
break ;
835
854
}
0 commit comments