13
13
#ifndef SWIFT_IDE_CODECOMPLETION_H
14
14
#define SWIFT_IDE_CODECOMPLETION_H
15
15
16
+ #include " swift/AST/ASTDemangler.h"
16
17
#include " swift/AST/Identifier.h"
18
+ #include " swift/AST/USRGeneration.h"
17
19
#include " swift/Basic/Debug.h"
18
20
#include " swift/Basic/LLVM.h"
19
21
#include " swift/Basic/OptionSet.h"
@@ -697,7 +699,94 @@ enum class CodeCompletionResultKind : uint8_t {
697
699
MAX_VALUE = BuiltinOperator
698
700
};
699
701
700
- class CodeCompletionResult ;
702
+ // / The type returned by a code completion item. It is canonicalized and can be
703
+ // / instantiated in different \c ASTContexts.
704
+ class CodeCompletionResultType {
705
+
706
+ // / The USR of the type. Used to re-instantiate the type in different \c
707
+ // / ASTContexts.
708
+ std::string USR;
709
+
710
+ // / If a type has already been computed from the USR, it is cached here.
711
+ Type Ty;
712
+
713
+ // / The \c ASTContext in which \c Ty lives. Must be stored separately from
714
+ // / \c Ty because the \c ASTContext in which \c Ty lives might get destroyed,
715
+ // / thus making the pointer inside \c Ty invalid.
716
+ ASTContext *ContextOfTy;
717
+
718
+ // / Maps USRs to \c CodeCompletionResultTypes that have already been
719
+ // / constructed.
720
+ static llvm::StringMap<CodeCompletionResultType *> USRCache;
721
+
722
+ // / Maps Types to \c CodeCompletionResultTypes that have already been
723
+ // / constructed.
724
+ static llvm::DenseMap<Type, CodeCompletionResultType *> TypeCache;
725
+
726
+ CodeCompletionResultType (StringRef USR) : USR(USR) {}
727
+
728
+ public:
729
+ // / Create an \c CodeCompletionResultType from an \c ASTContext's \c Type.
730
+ static CodeCompletionResultType *fromType (Type Ty) {
731
+ auto ResFromType = TypeCache.find (Ty);
732
+ if (ResFromType != TypeCache.end ()) {
733
+ return ResFromType->second ;
734
+ }
735
+ CodeCompletionResultType *Res;
736
+ // FIXME: We can't compute USRs for archetypes. If the type contains an
737
+ // archetype, create a new CodeCompletionResultType so that multiple
738
+ // archetypes aren't unified to the same ASTContextIndependent type.
739
+ // Once we round-trip via the USR, this will produce a null type.
740
+ if (Ty && !Ty->hasArchetype ()) {
741
+ SmallString<32 > USR;
742
+ llvm::raw_svector_ostream OS (USR);
743
+ printTypeUSR (Ty, OS);
744
+ Res = CodeCompletionResultType::fromUSR (USR);
745
+ } else {
746
+ Res = new CodeCompletionResultType (" " );
747
+ }
748
+ // We already know the Type. Cache it so it doesn't have to be recomputed.
749
+ Res->Ty = Ty;
750
+ if (Ty) {
751
+ Res->ContextOfTy = &Ty->getASTContext ();
752
+ } else {
753
+ Res->ContextOfTy = nullptr ;
754
+ }
755
+
756
+ TypeCache[Ty] = Res;
757
+
758
+ return Res;
759
+ }
760
+
761
+ // / Create a type from a USR. The USR will only get demangled once a \c Type
762
+ // / inside an \c ASTContext is requested using \c getType.
763
+ static CodeCompletionResultType *fromUSR (StringRef USR) {
764
+ auto ResFromUSR = USRCache.find (USR);
765
+ if (ResFromUSR != USRCache.end ()) {
766
+ return ResFromUSR->second ;
767
+ }
768
+ auto Res = new CodeCompletionResultType (USR);
769
+
770
+ USRCache[USR] = Res;
771
+ return Res;
772
+ }
773
+
774
+ // / Return the \c Type within the given \p Ctx.
775
+ Type getType (ASTContext &Ctx) {
776
+ if (!Ty || ContextOfTy != &Ctx) {
777
+ if (USR.empty ()) {
778
+ Ty = Type ();
779
+ } else {
780
+ Ty = Demangle::getTypeForMangling (Ctx, USR);
781
+ }
782
+ }
783
+ return Ty;
784
+ }
785
+
786
+ // / Return the USR of this type, which identifies the type independent of the
787
+ // / \c ASTContext.
788
+ StringRef getUSR () const { return USR; }
789
+ };
701
790
702
791
// / The parts of a \c CodeCompletionResult that are not dependent on the context
703
792
// / it appears in and can thus be cached.
@@ -710,6 +799,13 @@ class ContextFreeCodeCompletionResult {
710
799
StringRef ModuleName;
711
800
StringRef BriefDocComment;
712
801
ArrayRef<StringRef> AssociatedUSRs;
802
+ // / The type of the element produced by the expression. Can be
803
+ // / - \c nullptr if the completion result doesn't produce something that's
804
+ // / valid inside an expression, e.g. a keyword
805
+ // / - A null type if the completion result produces something that's valid
806
+ // / inside an expression but the result type isn't known
807
+ // / - A proper type if the type produced by this completion result is known.
808
+ CodeCompletionResultType *ResultType;
713
809
714
810
ContextFreeNotRecommendedReason NotRecommended;
715
811
CodeCompletionDiagnosticSeverity DiagnosticSeverity : 3 ;
@@ -733,14 +829,16 @@ class ContextFreeCodeCompletionResult {
733
829
CodeCompletionOperatorKind KnownOperatorKind, bool IsSystem,
734
830
CodeCompletionString *CompletionString, StringRef ModuleName,
735
831
StringRef BriefDocComment, ArrayRef<StringRef> AssociatedUSRs,
832
+ CodeCompletionResultType *ResultType,
736
833
ContextFreeNotRecommendedReason NotRecommended,
737
834
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
738
835
StringRef DiagnosticMessage)
739
836
: Kind(Kind), AssociatedKind(AssociatedKind),
740
837
KnownOperatorKind (KnownOperatorKind), IsSystem(IsSystem),
741
838
CompletionString(CompletionString), ModuleName(ModuleName),
742
839
BriefDocComment(BriefDocComment), AssociatedUSRs(AssociatedUSRs),
743
- NotRecommended(NotRecommended), DiagnosticSeverity(DiagnosticSeverity),
840
+ ResultType(ResultType), NotRecommended(NotRecommended),
841
+ DiagnosticSeverity(DiagnosticSeverity),
744
842
DiagnosticMessage(DiagnosticMessage) {
745
843
assert ((NotRecommended == ContextFreeNotRecommendedReason::None) ==
746
844
(DiagnosticSeverity == CodeCompletionDiagnosticSeverity::None) &&
@@ -766,13 +864,14 @@ class ContextFreeCodeCompletionResult {
766
864
ContextFreeCodeCompletionResult (
767
865
CodeCompletionResultKind Kind, CodeCompletionString *CompletionString,
768
866
CodeCompletionOperatorKind KnownOperatorKind, StringRef BriefDocComment,
867
+ CodeCompletionResultType *ResultType,
769
868
ContextFreeNotRecommendedReason NotRecommended,
770
869
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
771
870
StringRef DiagnosticMessage)
772
871
: ContextFreeCodeCompletionResult(
773
872
Kind, /* AssociatedKind=*/ 0 , KnownOperatorKind,
774
873
/* IsSystem=*/ false , CompletionString, /* ModuleName=*/ " " ,
775
- BriefDocComment, /* AssociatedUSRs=*/ {}, NotRecommended,
874
+ BriefDocComment, /* AssociatedUSRs=*/ {}, ResultType, NotRecommended,
776
875
DiagnosticSeverity, DiagnosticMessage) {}
777
876
778
877
// / Constructs a \c Keyword result.
@@ -782,12 +881,14 @@ class ContextFreeCodeCompletionResult {
782
881
// / same \c CodeCompletionResultSink as the result itself.
783
882
ContextFreeCodeCompletionResult (CodeCompletionKeywordKind Kind,
784
883
CodeCompletionString *CompletionString,
785
- StringRef BriefDocComment)
884
+ StringRef BriefDocComment,
885
+ CodeCompletionResultType *ResultType)
786
886
: ContextFreeCodeCompletionResult(
787
887
CodeCompletionResultKind::Keyword, static_cast <uint8_t >(Kind),
788
888
CodeCompletionOperatorKind::None, /* IsSystem=*/ false,
789
889
CompletionString, /* ModuleName=*/ "", BriefDocComment,
790
- /* AssociatedUSRs=*/ {}, ContextFreeNotRecommendedReason::None,
890
+ /* AssociatedUSRs=*/ {}, ResultType,
891
+ ContextFreeNotRecommendedReason::None,
791
892
CodeCompletionDiagnosticSeverity::None, /* DiagnosticMessage=*/ " " ) {}
792
893
793
894
// / Constructs a \c Literal result.
@@ -796,13 +897,15 @@ class ContextFreeCodeCompletionResult {
796
897
// / result, typically by storing them in the same \c CodeCompletionResultSink
797
898
// / as the result itself.
798
899
ContextFreeCodeCompletionResult (CodeCompletionLiteralKind LiteralKind,
799
- CodeCompletionString *CompletionString)
900
+ CodeCompletionString *CompletionString,
901
+ CodeCompletionResultType *ResultType)
800
902
: ContextFreeCodeCompletionResult(
801
903
CodeCompletionResultKind::Literal,
802
904
static_cast <uint8_t >(LiteralKind), CodeCompletionOperatorKind::None,
803
905
/* IsSystem=*/ false , CompletionString, /* ModuleName=*/ " " ,
804
906
/* BriefDocComment=*/ " " ,
805
- /* AssociatedUSRs=*/ {}, ContextFreeNotRecommendedReason::None,
907
+ /* AssociatedUSRs=*/ {}, ResultType,
908
+ ContextFreeNotRecommendedReason::None,
806
909
CodeCompletionDiagnosticSeverity::None, /* DiagnosticMessage=*/ " " ) {}
807
910
808
911
// / Constructs a \c Declaration result.
@@ -813,7 +916,7 @@ class ContextFreeCodeCompletionResult {
813
916
ContextFreeCodeCompletionResult (
814
917
CodeCompletionString *CompletionString, const Decl *AssociatedDecl,
815
918
StringRef ModuleName, StringRef BriefDocComment,
816
- ArrayRef<StringRef> AssociatedUSRs,
919
+ ArrayRef<StringRef> AssociatedUSRs, CodeCompletionResultType *ResultType,
817
920
ContextFreeNotRecommendedReason NotRecommended,
818
921
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
819
922
StringRef DiagnosticMessage)
@@ -822,7 +925,7 @@ class ContextFreeCodeCompletionResult {
822
925
static_cast <uint8_t >(getCodeCompletionDeclKind(AssociatedDecl)),
823
926
CodeCompletionOperatorKind::None, getDeclIsSystem(AssociatedDecl),
824
927
CompletionString, ModuleName, BriefDocComment, AssociatedUSRs,
825
- NotRecommended, DiagnosticSeverity, DiagnosticMessage) {
928
+ ResultType, NotRecommended, DiagnosticSeverity, DiagnosticMessage) {
826
929
assert (AssociatedDecl && " should have a decl" );
827
930
}
828
931
@@ -856,6 +959,8 @@ class ContextFreeCodeCompletionResult {
856
959
857
960
ArrayRef<StringRef> getAssociatedUSRs () const { return AssociatedUSRs; }
858
961
962
+ CodeCompletionResultType *getResultType () const { return ResultType; }
963
+
859
964
ContextFreeNotRecommendedReason getNotRecommendedReason () const {
860
965
return NotRecommended;
861
966
}
@@ -886,6 +991,40 @@ class ContextFreeCodeCompletionResult {
886
991
static bool getDeclIsSystem (const Decl *D);
887
992
};
888
993
994
+ // / The expected contextual type(s) for code-completion.
995
+ struct ExpectedTypeContext {
996
+ // / Possible types of the code completion expression.
997
+ llvm::SmallVector<Type, 4 > possibleTypes;
998
+
999
+ // / Pre typechecked type of the expression at the completion position.
1000
+ Type idealType;
1001
+
1002
+ // / Whether the `ExpectedTypes` comes from a single-expression body, e.g.
1003
+ // / `foo({ here })`.
1004
+ // /
1005
+ // / Since the input may be incomplete, we take into account that the types are
1006
+ // / only a hint.
1007
+ bool isImplicitSingleExpressionReturn = false ;
1008
+ bool preferNonVoid = false ;
1009
+
1010
+ bool empty () const { return possibleTypes.empty (); }
1011
+ bool requiresNonVoid () const {
1012
+ if (isImplicitSingleExpressionReturn)
1013
+ return false ;
1014
+ if (preferNonVoid)
1015
+ return true ;
1016
+ if (possibleTypes.empty ())
1017
+ return false ;
1018
+ return std::all_of (possibleTypes.begin (), possibleTypes.end (),
1019
+ [](Type Ty) { return !Ty->isVoid (); });
1020
+ }
1021
+
1022
+ ExpectedTypeContext () = default ;
1023
+ ExpectedTypeContext (ArrayRef<Type> types, bool isImplicitSingleExprReturn)
1024
+ : possibleTypes(types.begin(), types.end()),
1025
+ isImplicitSingleExpressionReturn (isImplicitSingleExprReturn) {}
1026
+ };
1027
+
889
1028
// / A single code completion result enriched with information that depend on
890
1029
// / the completion's usage context.
891
1030
class CodeCompletionResult {
@@ -945,8 +1084,7 @@ class CodeCompletionResult {
945
1084
static_assert (int (ExpectedTypeRelation::MAX_VALUE) < 1 << 3 , " " );
946
1085
947
1086
public:
948
- // / Enrich a \c ContextFreeCodeCompletionResult with the following contextual
949
- // / information.
1087
+ // / Memberwise initializer
950
1088
CodeCompletionResult (ContextFreeCodeCompletionResult ContextFree,
951
1089
SemanticContextKind SemanticContext,
952
1090
CodeCompletionFlair Flair, uint8_t NumBytesToErase,
@@ -960,6 +1098,19 @@ class CodeCompletionResult {
960
1098
DiagnosticMessage(DiagnosticMessage), NumBytesToErase(NumBytesToErase),
961
1099
TypeDistance(TypeDistance) {}
962
1100
1101
+ // / Enrich a \c ContextFreeCodeCompletionResult with the following contextual
1102
+ // / information.
1103
+ // / This computes the type relation between the completion item and its
1104
+ // / expected type context.
1105
+ CodeCompletionResult (ContextFreeCodeCompletionResult ContextFree,
1106
+ SemanticContextKind SemanticContext,
1107
+ CodeCompletionFlair Flair, uint8_t NumBytesToErase,
1108
+ const ExpectedTypeContext &TypeContext,
1109
+ const DeclContext *DC,
1110
+ ContextualNotRecommendedReason NotRecommended,
1111
+ CodeCompletionDiagnosticSeverity DiagnosticSeverity,
1112
+ StringRef DiagnosticMessage);
1113
+
963
1114
const ContextFreeCodeCompletionResult &getContextFreeResult () const {
964
1115
return ContextFree;
965
1116
}
0 commit comments