@@ -1481,6 +1481,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1481
1481
ASTContext &Ctx;
1482
1482
LazyResolver *TypeResolver = nullptr ;
1483
1483
const DeclContext *CurrDeclContext;
1484
+ ModuleDecl *CurrModule;
1484
1485
ClangImporter *Importer;
1485
1486
CodeCompletionContext *CompletionContext;
1486
1487
@@ -1629,6 +1630,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1629
1630
const DeclContext *CurrDeclContext,
1630
1631
CodeCompletionContext *CompletionContext = nullptr )
1631
1632
: Sink(Sink), Ctx(Ctx), CurrDeclContext(CurrDeclContext),
1633
+ CurrModule (CurrDeclContext ? CurrDeclContext->getParentModule ()
1634
+ : nullptr),
1632
1635
Importer(static_cast <ClangImporter *>(CurrDeclContext->getASTContext ().
1633
1636
getClangModuleLoader())),
1634
1637
CompletionContext(CompletionContext) {
@@ -3514,9 +3517,73 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3514
3517
addPostfixBang (ValueT);
3515
3518
}
3516
3519
3520
+ void addTypeRelationFromProtocol (CodeCompletionResultBuilder &builder,
3521
+ CodeCompletionLiteralKind kind,
3522
+ StringRef defaultTypeName) {
3523
+ // Check for matching ExpectedTypes.
3524
+ auto *P = Ctx.getProtocol (protocolForLiteralKind (kind));
3525
+ for (auto T : expectedTypeContext.possibleTypes ) {
3526
+ if (!T)
3527
+ continue ;
3528
+
3529
+ auto typeRelation = CodeCompletionResult::Identical;
3530
+ // Convert through optional types unless we're looking for a protocol
3531
+ // that Optional itself conforms to.
3532
+ if (kind != CodeCompletionLiteralKind::NilLiteral) {
3533
+ if (auto optionalObjT = T->getOptionalObjectType ()) {
3534
+ T = optionalObjT;
3535
+ typeRelation = CodeCompletionResult::Convertible;
3536
+ }
3537
+ }
3538
+
3539
+ // Check for conformance to the literal protocol.
3540
+ if (auto *NTD = T->getAnyNominal ()) {
3541
+ SmallVector<ProtocolConformance *, 2 > conformances;
3542
+ if (NTD->lookupConformance (CurrModule, P, conformances)) {
3543
+ addTypeAnnotation (builder, T);
3544
+ builder.setExpectedTypeRelation (typeRelation);
3545
+ return ;
3546
+ }
3547
+ }
3548
+ }
3549
+
3550
+ // Fallback to showing the default type.
3551
+ if (!defaultTypeName.empty ())
3552
+ builder.addTypeAnnotation (defaultTypeName);
3553
+ }
3554
+
3555
+ // / Add '#file', '#line', et at.
3556
+ void addPoundLiteralCompletions (bool needPound) {
3557
+ auto addFromProto = [&](StringRef name, CodeCompletionKeywordKind kwKind,
3558
+ CodeCompletionLiteralKind literalKind,
3559
+ StringRef defaultTypeName) {
3560
+ if (!needPound)
3561
+ name = name.substr (1 );
3562
+
3563
+ CodeCompletionResultBuilder builder (
3564
+ Sink, CodeCompletionResult::ResultKind::Keyword,
3565
+ SemanticContextKind::None, {});
3566
+ builder.setLiteralKind (literalKind);
3567
+ builder.setKeywordKind (kwKind);
3568
+ builder.addTextChunk (name);
3569
+ addTypeRelationFromProtocol (builder, literalKind, defaultTypeName);
3570
+ };
3571
+
3572
+ addFromProto (" #function" , CodeCompletionKeywordKind::pound_function,
3573
+ CodeCompletionLiteralKind::StringLiteral, " String" );
3574
+ addFromProto (" #file" , CodeCompletionKeywordKind::pound_file,
3575
+ CodeCompletionLiteralKind::StringLiteral, " String" );
3576
+ addFromProto (" #line" , CodeCompletionKeywordKind::pound_line,
3577
+ CodeCompletionLiteralKind::IntegerLiteral, " Int" );
3578
+ addFromProto (" #column" , CodeCompletionKeywordKind::pound_column,
3579
+ CodeCompletionLiteralKind::IntegerLiteral, " Int" );
3580
+
3581
+ addKeyword (needPound ? " #dsohandle" : " dsohandle" , " UnsafeRawPointer" ,
3582
+ CodeCompletionKeywordKind::pound_dsohandle);
3583
+ }
3584
+
3517
3585
void addValueLiteralCompletions () {
3518
3586
auto &context = CurrDeclContext->getASTContext ();
3519
- auto *module = CurrDeclContext->getParentModule ();
3520
3587
3521
3588
auto addFromProto = [&](
3522
3589
CodeCompletionLiteralKind kind, StringRef defaultTypeName,
@@ -3528,38 +3595,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3528
3595
builder.setLiteralKind (kind);
3529
3596
3530
3597
consumer (builder);
3531
-
3532
- // Check for matching ExpectedTypes.
3533
- auto *P = context.getProtocol (protocolForLiteralKind (kind));
3534
- bool foundConformance = false ;
3535
- for (auto T : expectedTypeContext.possibleTypes ) {
3536
- if (!T)
3537
- continue ;
3538
-
3539
- auto typeRelation = CodeCompletionResult::Identical;
3540
- // Convert through optional types unless we're looking for a protocol
3541
- // that Optional itself conforms to.
3542
- if (kind != CodeCompletionLiteralKind::NilLiteral) {
3543
- if (auto optionalObjT = T->getOptionalObjectType ()) {
3544
- T = optionalObjT;
3545
- typeRelation = CodeCompletionResult::Convertible;
3546
- }
3547
- }
3548
-
3549
- // Check for conformance to the literal protocol.
3550
- if (auto *NTD = T->getAnyNominal ()) {
3551
- SmallVector<ProtocolConformance *, 2 > conformances;
3552
- if (NTD->lookupConformance (module , P, conformances)) {
3553
- foundConformance = true ;
3554
- addTypeAnnotation (builder, T);
3555
- builder.setExpectedTypeRelation (typeRelation);
3556
- }
3557
- }
3558
- }
3559
-
3560
- // Fallback to showing the default type.
3561
- if (!foundConformance && !defaultTypeName.empty ())
3562
- builder.addTypeAnnotation (defaultTypeName);
3598
+ addTypeRelationFromProtocol (builder, kind, defaultTypeName);
3563
3599
};
3564
3600
3565
3601
// FIXME: the pedantically correct way is to resolve Swift.*LiteralType.
@@ -3708,8 +3744,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3708
3744
});
3709
3745
}
3710
3746
3711
- if (LiteralCompletions)
3747
+ if (LiteralCompletions) {
3712
3748
addValueLiteralCompletions ();
3749
+ addPoundLiteralCompletions (/* needPound=*/ true );
3750
+ }
3751
+
3713
3752
3714
3753
// If the expected type is ObjectiveC.Selector, add #selector. If
3715
3754
// it's String, add #keyPath.
@@ -4842,14 +4881,6 @@ static void addExprKeywords(CodeCompletionResultSink &Sink) {
4842
4881
addKeyword (Sink, " try" , CodeCompletionKeywordKind::kw_try);
4843
4882
addKeyword (Sink, " try!" , CodeCompletionKeywordKind::kw_try);
4844
4883
addKeyword (Sink, " try?" , CodeCompletionKeywordKind::kw_try);
4845
- // FIXME: The pedantically correct way to find the type is to resolve the
4846
- // Swift.StringLiteralType type.
4847
- addKeyword (Sink, " #function" , CodeCompletionKeywordKind::pound_function, " String" );
4848
- addKeyword (Sink, " #file" , CodeCompletionKeywordKind::pound_file, " String" );
4849
- // Same: Swift.IntegerLiteralType.
4850
- addKeyword (Sink, " #line" , CodeCompletionKeywordKind::pound_line, " Int" );
4851
- addKeyword (Sink, " #column" , CodeCompletionKeywordKind::pound_column, " Int" );
4852
- addKeyword (Sink, " #dsohandle" , CodeCompletionKeywordKind::pound_dsohandle, " UnsafeMutableRawPointer" );
4853
4884
}
4854
4885
4855
4886
static void addOpaqueTypeKeyword (CodeCompletionResultSink &Sink) {
@@ -5448,7 +5479,12 @@ void CodeCompletionCallbacksImpl::doneParsing() {
5448
5479
}
5449
5480
5450
5481
case CompletionKind::AfterPoundExpr: {
5482
+ ExprContextInfo ContextInfo (CurDeclContext, CodeCompleteTokenExpr);
5483
+ Lookup.setExpectedTypes (ContextInfo.getPossibleTypes (),
5484
+ ContextInfo.isSingleExpressionBody ());
5485
+
5451
5486
Lookup.addPoundAvailable (ParentStmtKind);
5487
+ Lookup.addPoundLiteralCompletions (/* needPound=*/ false );
5452
5488
Lookup.addPoundSelector (/* needPound=*/ false );
5453
5489
Lookup.addPoundKeyPath (/* needPound=*/ false );
5454
5490
break ;
0 commit comments