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