Skip to content

Commit 4ad30b6

Browse files
authored
Merge pull request #3044 from apple/code-complete-postfix-decls
2 parents 4fb3a69 + e2632c1 commit 4ad30b6

14 files changed

+299
-89
lines changed

include/swift/AST/Expr.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,11 @@ class alignas(8) Expr {
494494
/// has an access kind
495495
void propagateLValueAccessKind(AccessKind accessKind,
496496
bool allowOverwrite = false);
497-
497+
498+
/// Retrieves the declaration that is being referenced by this
499+
/// expression, if any.
500+
ConcreteDeclRef getReferencedDecl() const;
501+
498502
/// Determine whether this expression is 'super', possibly converted to
499503
/// a base class.
500504
bool isSuperExpr() const;

include/swift/Sema/IDETypeChecking.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,12 @@ namespace swift {
8888

8989
/// \brief Return the type of an expression parsed during code completion, or
9090
/// None on error.
91-
Optional<Type> getTypeOfCompletionContextExpr(ASTContext &Ctx,
92-
DeclContext *DC,
93-
CompletionTypeCheckKind kind,
94-
Expr *&parsedExpr);
91+
Optional<Type> getTypeOfCompletionContextExpr(
92+
ASTContext &Ctx,
93+
DeclContext *DC,
94+
CompletionTypeCheckKind kind,
95+
Expr *&parsedExpr,
96+
ConcreteDeclRef &referencedDecl);
9597

9698
/// Typecheck the sequence expression \p parsedExpr for code completion.
9799
///

lib/AST/Expr.cpp

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,145 @@ void Expr::propagateLValueAccessKind(AccessKind accessKind,
330330
PropagateAccessKind(allowOverwrite).visit(this, accessKind);
331331
}
332332

333+
ConcreteDeclRef Expr::getReferencedDecl() const {
334+
switch (getKind()) {
335+
// No declaration reference.
336+
#define NO_REFERENCE(Id) case ExprKind::Id: return ConcreteDeclRef()
337+
#define SIMPLE_REFERENCE(Id, Getter) \
338+
case ExprKind::Id: \
339+
return cast<Id##Expr>(this)->Getter()
340+
#define PASS_THROUGH_REFERENCE(Id, GetSubExpr) \
341+
case ExprKind::Id: \
342+
return cast<Id##Expr>(this)->GetSubExpr()->getReferencedDecl()
343+
344+
NO_REFERENCE(Error);
345+
NO_REFERENCE(NilLiteral);
346+
NO_REFERENCE(IntegerLiteral);
347+
NO_REFERENCE(FloatLiteral);
348+
NO_REFERENCE(BooleanLiteral);
349+
NO_REFERENCE(StringLiteral);
350+
NO_REFERENCE(InterpolatedStringLiteral);
351+
NO_REFERENCE(ObjectLiteral);
352+
NO_REFERENCE(MagicIdentifierLiteral);
353+
NO_REFERENCE(DiscardAssignment);
354+
355+
SIMPLE_REFERENCE(DeclRef, getDecl);
356+
SIMPLE_REFERENCE(SuperRef, getSelf);
357+
358+
case ExprKind::Type: {
359+
auto typeRepr = cast<TypeExpr>(this)->getTypeRepr();
360+
if (!typeRepr) return ConcreteDeclRef();
361+
auto ident = dyn_cast<IdentTypeRepr>(typeRepr);
362+
if (!ident) return ConcreteDeclRef();
363+
return ident->getComponentRange().back()->getBoundDecl();
364+
}
365+
366+
SIMPLE_REFERENCE(OtherConstructorDeclRef, getDecl);
367+
368+
PASS_THROUGH_REFERENCE(DotSyntaxBaseIgnored, getRHS);
369+
370+
// FIXME: Return multiple results?
371+
case ExprKind::OverloadedDeclRef:
372+
case ExprKind::OverloadedMemberRef:
373+
return ConcreteDeclRef();
374+
375+
NO_REFERENCE(UnresolvedDeclRef);
376+
377+
SIMPLE_REFERENCE(MemberRef, getMember);
378+
SIMPLE_REFERENCE(DynamicMemberRef, getMember);
379+
SIMPLE_REFERENCE(DynamicSubscript, getMember);
380+
381+
PASS_THROUGH_REFERENCE(UnresolvedSpecialize, getSubExpr);
382+
383+
NO_REFERENCE(UnresolvedMember);
384+
NO_REFERENCE(UnresolvedDot);
385+
NO_REFERENCE(Sequence);
386+
PASS_THROUGH_REFERENCE(Paren, getSubExpr);
387+
PASS_THROUGH_REFERENCE(DotSelf, getSubExpr);
388+
PASS_THROUGH_REFERENCE(Try, getSubExpr);
389+
PASS_THROUGH_REFERENCE(ForceTry, getSubExpr);
390+
PASS_THROUGH_REFERENCE(OptionalTry, getSubExpr);
391+
392+
NO_REFERENCE(Tuple);
393+
NO_REFERENCE(Array);
394+
NO_REFERENCE(Dictionary);
395+
396+
case ExprKind::Subscript: {
397+
auto subscript = cast<SubscriptExpr>(this);
398+
if (subscript->hasDecl()) return subscript->getDecl();
399+
return ConcreteDeclRef();
400+
}
401+
402+
NO_REFERENCE(TupleElement);
403+
NO_REFERENCE(CaptureList);
404+
NO_REFERENCE(Closure);
405+
406+
PASS_THROUGH_REFERENCE(AutoClosure, getSingleExpressionBody);
407+
PASS_THROUGH_REFERENCE(InOut, getSubExpr);
408+
409+
NO_REFERENCE(DynamicType);
410+
411+
PASS_THROUGH_REFERENCE(RebindSelfInConstructor, getSubExpr);
412+
413+
NO_REFERENCE(OpaqueValue);
414+
PASS_THROUGH_REFERENCE(BindOptional, getSubExpr);
415+
PASS_THROUGH_REFERENCE(OptionalEvaluation, getSubExpr);
416+
PASS_THROUGH_REFERENCE(ForceValue, getSubExpr);
417+
PASS_THROUGH_REFERENCE(OpenExistential, getSubExpr);
418+
419+
NO_REFERENCE(Call);
420+
NO_REFERENCE(PrefixUnary);
421+
NO_REFERENCE(PostfixUnary);
422+
NO_REFERENCE(Binary);
423+
NO_REFERENCE(DotSyntaxCall);
424+
NO_REFERENCE(ConstructorRefCall);
425+
426+
PASS_THROUGH_REFERENCE(Load, getSubExpr);
427+
NO_REFERENCE(TupleShuffle);
428+
NO_REFERENCE(UnresolvedTypeConversion);
429+
PASS_THROUGH_REFERENCE(FunctionConversion, getSubExpr);
430+
PASS_THROUGH_REFERENCE(CovariantFunctionConversion, getSubExpr);
431+
PASS_THROUGH_REFERENCE(CovariantReturnConversion, getSubExpr);
432+
PASS_THROUGH_REFERENCE(MetatypeConversion, getSubExpr);
433+
PASS_THROUGH_REFERENCE(CollectionUpcastConversion, getSubExpr);
434+
PASS_THROUGH_REFERENCE(Erasure, getSubExpr);
435+
PASS_THROUGH_REFERENCE(DerivedToBase, getSubExpr);
436+
PASS_THROUGH_REFERENCE(ArchetypeToSuper, getSubExpr);
437+
PASS_THROUGH_REFERENCE(InjectIntoOptional, getSubExpr);
438+
PASS_THROUGH_REFERENCE(ClassMetatypeToObject, getSubExpr);
439+
PASS_THROUGH_REFERENCE(ExistentialMetatypeToObject, getSubExpr);
440+
PASS_THROUGH_REFERENCE(ProtocolMetatypeToObject, getSubExpr);
441+
PASS_THROUGH_REFERENCE(InOutToPointer, getSubExpr);
442+
PASS_THROUGH_REFERENCE(ArrayToPointer, getSubExpr);
443+
PASS_THROUGH_REFERENCE(StringToPointer, getSubExpr);
444+
PASS_THROUGH_REFERENCE(PointerToPointer, getSubExpr);
445+
PASS_THROUGH_REFERENCE(LValueToPointer, getSubExpr);
446+
PASS_THROUGH_REFERENCE(ForeignObjectConversion, getSubExpr);
447+
PASS_THROUGH_REFERENCE(UnevaluatedInstance, getSubExpr);
448+
NO_REFERENCE(Coerce);
449+
NO_REFERENCE(ForcedCheckedCast);
450+
NO_REFERENCE(ConditionalCheckedCast);
451+
NO_REFERENCE(Is);
452+
453+
NO_REFERENCE(Arrow);
454+
NO_REFERENCE(If);
455+
NO_REFERENCE(EnumIsCase);
456+
NO_REFERENCE(Assign);
457+
NO_REFERENCE(DefaultValue);
458+
NO_REFERENCE(CodeCompletion);
459+
NO_REFERENCE(UnresolvedPattern);
460+
NO_REFERENCE(EditorPlaceholder);
461+
NO_REFERENCE(ObjCSelector);
462+
NO_REFERENCE(ObjCKeyPath);
463+
464+
#undef SIMPLE_REFERENCE
465+
#undef NO_REFERENCE
466+
#undef PASS_THROUGH_REFERENCE
467+
}
468+
469+
return ConcreteDeclRef();
470+
}
471+
333472
/// Enumerate each immediate child expression of this node, invoking the
334473
/// specific functor on it. This ignores statements and other non-expression
335474
/// children.

0 commit comments

Comments
 (0)