mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Completion] Only complete @unchecked et al in inheritance clauses
Add a case for completing type attributes in inheritance clause position, and limit the completion of `@unchecked`, `@preconcurrency`, and `@retroactive` to that case.
This commit is contained in:
@@ -229,6 +229,7 @@ enum class CompletionKind : uint8_t {
|
||||
StmtLabel,
|
||||
ForEachPatternBeginning,
|
||||
TypeAttrBeginning,
|
||||
TypeAttrInheritanceBeginning,
|
||||
OptionalBinding,
|
||||
|
||||
/// Completion after `~` in an inheritance clause.
|
||||
|
||||
@@ -605,7 +605,7 @@ public:
|
||||
void getAttributeDeclParamCompletions(CustomSyntaxAttributeKind AttrKind,
|
||||
int ParamIndex, bool HasLabel);
|
||||
|
||||
void getTypeAttributeKeywordCompletions();
|
||||
void getTypeAttributeKeywordCompletions(CompletionKind completionKind);
|
||||
|
||||
void collectPrecedenceGroups();
|
||||
|
||||
|
||||
@@ -288,6 +288,8 @@ public:
|
||||
|
||||
virtual void completeTypeAttrBeginning() {};
|
||||
|
||||
virtual void completeTypeAttrInheritanceBeginning() {};
|
||||
|
||||
virtual void completeOptionalBinding(){};
|
||||
|
||||
virtual void completeWithoutConstraintType(){};
|
||||
|
||||
@@ -1398,6 +1398,8 @@ public:
|
||||
|
||||
/// Whether the type is for a closure attribute.
|
||||
CustomAttribute,
|
||||
/// A type in an inheritance clause.
|
||||
InheritanceClause,
|
||||
};
|
||||
|
||||
ParserResult<TypeRepr> parseTypeScalar(
|
||||
@@ -1455,6 +1457,7 @@ public:
|
||||
ParserResult<TypeRepr> parseTypeDotted(ParserResult<TypeRepr> Base);
|
||||
|
||||
struct ParsedTypeAttributeList {
|
||||
ParseTypeReason ParseReason;
|
||||
ParamDecl::Specifier Specifier = ParamDecl::Specifier::Default;
|
||||
SourceLoc SpecifierLoc;
|
||||
SourceLoc IsolatedLoc;
|
||||
@@ -1463,6 +1466,8 @@ public:
|
||||
SmallVector<TypeOrCustomAttr> Attributes;
|
||||
SmallVector<LifetimeDependenceSpecifier> lifetimeDependenceSpecifiers;
|
||||
|
||||
ParsedTypeAttributeList(ParseTypeReason reason) : ParseReason(reason) {}
|
||||
|
||||
/// Main entry point for parsing.
|
||||
///
|
||||
/// Inline we just have the fast path of failing to match. We call slowParse
|
||||
@@ -1484,7 +1489,7 @@ public:
|
||||
};
|
||||
|
||||
ParserStatus parseTypeAttribute(TypeOrCustomAttr &result, SourceLoc AtLoc,
|
||||
SourceLoc AtEndLoc,
|
||||
SourceLoc AtEndLoc, ParseTypeReason reason,
|
||||
PatternBindingInitializer *&initContext,
|
||||
bool justChecking = false);
|
||||
|
||||
|
||||
@@ -303,6 +303,7 @@ public:
|
||||
void completeStmtLabel(StmtKind ParentKind) override;
|
||||
void completeForEachPatternBeginning(bool hasTry, bool hasAwait) override;
|
||||
void completeTypeAttrBeginning() override;
|
||||
void completeTypeAttrInheritanceBeginning() override;
|
||||
void completeOptionalBinding() override;
|
||||
void completeWithoutConstraintType() override;
|
||||
|
||||
@@ -655,6 +656,11 @@ void CodeCompletionCallbacksImpl::completeTypeAttrBeginning() {
|
||||
Kind = CompletionKind::TypeAttrBeginning;
|
||||
}
|
||||
|
||||
void CodeCompletionCallbacksImpl::completeTypeAttrInheritanceBeginning() {
|
||||
CurDeclContext = P.CurDeclContext;
|
||||
Kind = CompletionKind::TypeAttrInheritanceBeginning;
|
||||
}
|
||||
|
||||
bool swift::ide::isDynamicLookup(Type T) {
|
||||
return T->getRValueType()->isAnyObject();
|
||||
}
|
||||
@@ -983,6 +989,7 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
|
||||
case CompletionKind::PrecedenceGroup:
|
||||
case CompletionKind::StmtLabel:
|
||||
case CompletionKind::TypeAttrBeginning:
|
||||
case CompletionKind::TypeAttrInheritanceBeginning:
|
||||
case CompletionKind::OptionalBinding:
|
||||
case CompletionKind::WithoutConstraintType:
|
||||
break;
|
||||
@@ -1931,14 +1938,14 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
|
||||
Lookup.getStmtLabelCompletions(Loc, ParentStmtKind == StmtKind::Continue);
|
||||
break;
|
||||
}
|
||||
case CompletionKind::TypeAttrBeginning: {
|
||||
Lookup.getTypeAttributeKeywordCompletions();
|
||||
case CompletionKind::TypeAttrBeginning:
|
||||
case CompletionKind::TypeAttrInheritanceBeginning: {
|
||||
Lookup.getTypeAttributeKeywordCompletions(Kind);
|
||||
|
||||
// Type names at attribute position after '@'.
|
||||
Lookup.getTypeCompletionsInDeclContext(
|
||||
P.Context.SourceMgr.getIDEInspectionTargetLoc());
|
||||
break;
|
||||
|
||||
}
|
||||
case CompletionKind::OptionalBinding: {
|
||||
SourceLoc Loc = P.Context.SourceMgr.getIDEInspectionTargetLoc();
|
||||
|
||||
@@ -3132,8 +3132,20 @@ void CompletionLookup::getAttributeDeclParamCompletions(
|
||||
}
|
||||
}
|
||||
|
||||
void CompletionLookup::getTypeAttributeKeywordCompletions() {
|
||||
auto addTypeAttr = [&](StringRef Name) {
|
||||
void CompletionLookup::getTypeAttributeKeywordCompletions(
|
||||
CompletionKind completionKind) {
|
||||
auto addTypeAttr = [&](TypeAttrKind Kind, StringRef Name) {
|
||||
if (completionKind != CompletionKind::TypeAttrInheritanceBeginning) {
|
||||
switch (Kind) {
|
||||
case TypeAttrKind::Retroactive:
|
||||
case TypeAttrKind::Preconcurrency:
|
||||
case TypeAttrKind::Unchecked:
|
||||
// These attributes are only available in inheritance clasuses.
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
CodeCompletionResultBuilder Builder = makeResultBuilder(
|
||||
CodeCompletionResultKind::Keyword, SemanticContextKind::None);
|
||||
Builder.addAttributeKeyword(Name, "Type Attribute");
|
||||
@@ -3142,17 +3154,17 @@ void CompletionLookup::getTypeAttributeKeywordCompletions() {
|
||||
// Add simple user-accessible attributes.
|
||||
#define SIL_TYPE_ATTR(SPELLING, C)
|
||||
#define SIMPLE_SIL_TYPE_ATTR(SPELLING, C)
|
||||
#define SIMPLE_TYPE_ATTR(SPELLING, C) \
|
||||
if (!TypeAttribute::isUserInaccessible(TypeAttrKind::C)) \
|
||||
addTypeAttr(#SPELLING);
|
||||
#define SIMPLE_TYPE_ATTR(SPELLING, C) \
|
||||
if (!TypeAttribute::isUserInaccessible(TypeAttrKind::C)) \
|
||||
addTypeAttr(TypeAttrKind::C, #SPELLING);
|
||||
#include "swift/AST/TypeAttr.def"
|
||||
|
||||
// Add non-simple cases.
|
||||
addTypeAttr("convention(swift)");
|
||||
addTypeAttr("convention(block)");
|
||||
addTypeAttr("convention(c)");
|
||||
addTypeAttr("convention(thin)");
|
||||
addTypeAttr("isolated(any)");
|
||||
addTypeAttr(TypeAttrKind::Convention, "convention(swift)");
|
||||
addTypeAttr(TypeAttrKind::Convention, "convention(block)");
|
||||
addTypeAttr(TypeAttrKind::Convention, "convention(c)");
|
||||
addTypeAttr(TypeAttrKind::Convention, "convention(thin)");
|
||||
addTypeAttr(TypeAttrKind::Isolated, "isolated(any)");
|
||||
}
|
||||
|
||||
void CompletionLookup::collectPrecedenceGroups() {
|
||||
|
||||
@@ -4483,7 +4483,8 @@ bool Parser::canParseTypeAttribute() {
|
||||
TypeOrCustomAttr result; // ignored
|
||||
PatternBindingInitializer *initContext = nullptr;
|
||||
return !parseTypeAttribute(result, /*atLoc=*/SourceLoc(),
|
||||
/*atEndLoc=*/SourceLoc(), initContext,
|
||||
/*atEndLoc=*/SourceLoc(),
|
||||
ParseTypeReason::Unspecified, initContext,
|
||||
/*justChecking*/ true)
|
||||
.isError();
|
||||
}
|
||||
@@ -4684,6 +4685,7 @@ bool Parser::parseUUIDString(UUID &uuid, Diag<> diagnostic, bool justChecking) {
|
||||
/// no need to actually record the attribute
|
||||
ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
|
||||
SourceLoc AtLoc, SourceLoc AtEndLoc,
|
||||
ParseTypeReason reason,
|
||||
PatternBindingInitializer *&initContext,
|
||||
bool justChecking) {
|
||||
if (AtEndLoc != Tok.getLoc()) {
|
||||
@@ -4699,7 +4701,14 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
|
||||
if (Tok.is(tok::code_complete)) {
|
||||
if (!justChecking) {
|
||||
if (CodeCompletionCallbacks) {
|
||||
CodeCompletionCallbacks->completeTypeAttrBeginning();
|
||||
switch (reason) {
|
||||
case ParseTypeReason::InheritanceClause:
|
||||
CodeCompletionCallbacks->completeTypeAttrInheritanceBeginning();
|
||||
break;
|
||||
default:
|
||||
CodeCompletionCallbacks->completeTypeAttrBeginning();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
consumeToken(tok::code_complete);
|
||||
@@ -5525,7 +5534,8 @@ ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
|
||||
TypeOrCustomAttr result;
|
||||
SourceLoc AtEndLoc = Tok.getRange().getEnd();
|
||||
SourceLoc AtLoc = P.consumeToken();
|
||||
status |= P.parseTypeAttribute(result, AtLoc, AtEndLoc, initContext);
|
||||
status |=
|
||||
P.parseTypeAttribute(result, AtLoc, AtEndLoc, ParseReason, initContext);
|
||||
if (status.isError())
|
||||
return status;
|
||||
if (result)
|
||||
@@ -6806,7 +6816,8 @@ ParserStatus Parser::parseInheritance(
|
||||
continue;
|
||||
}
|
||||
|
||||
auto ParsedTypeResult = parseType();
|
||||
auto ParsedTypeResult =
|
||||
parseType(diag::expected_type, ParseTypeReason::InheritanceClause);
|
||||
Status |= ParsedTypeResult;
|
||||
|
||||
// Record the type if its a single type.
|
||||
|
||||
@@ -159,7 +159,7 @@ SourceLoc Parser::tryCompleteFunctionParamTypeBeginning() {
|
||||
// Skip over any starting parameter specifiers.
|
||||
{
|
||||
CancellableBacktrackingScope backtrack(*this);
|
||||
ParsedTypeAttributeList attrs;
|
||||
ParsedTypeAttributeList attrs(ParseTypeReason::Unspecified);
|
||||
attrs.parse(*this);
|
||||
if (!Tok.is(tok::code_complete))
|
||||
return SourceLoc();
|
||||
|
||||
@@ -396,9 +396,15 @@ ParserResult<TypeRepr> Parser::parseTypeScalar(
|
||||
ParserStatus status;
|
||||
|
||||
// Parse attributes.
|
||||
ParsedTypeAttributeList parsedAttributeList;
|
||||
ParsedTypeAttributeList parsedAttributeList(reason);
|
||||
status |= parsedAttributeList.parse(*this);
|
||||
|
||||
// If we have a completion, create an ErrorType.
|
||||
if (status.hasCodeCompletion()) {
|
||||
auto *ET = ErrorTypeRepr::create(Context, PreviousLoc);
|
||||
return makeParserCodeCompletionResult<TypeRepr>(ET);
|
||||
}
|
||||
|
||||
// Parse generic parameters in SIL mode.
|
||||
GenericParamList *generics = nullptr;
|
||||
SourceLoc substitutedLoc;
|
||||
|
||||
@@ -1126,7 +1126,8 @@ bool SILParser::parseSILType(SILType &Result,
|
||||
}
|
||||
|
||||
// Parse attributes.
|
||||
Parser::ParsedTypeAttributeList parsedAttrs;
|
||||
Parser::ParsedTypeAttributeList parsedAttrs(
|
||||
Parser::ParseTypeReason::Unspecified);
|
||||
parsedAttrs.parse(P);
|
||||
|
||||
// Global functions are implicitly @convention(thin) if not specified otherwise.
|
||||
|
||||
@@ -1,16 +1,45 @@
|
||||
// RUN: %batch-code-completion
|
||||
|
||||
// TYPEATTR-NOT: myIntValue
|
||||
// TYPEATTR-NOT: Type Attribute
|
||||
// TYPEATTR-DAG: Keyword/None: autoclosure[#Type Attribute#]; name=autoclosure
|
||||
// TYPEATTR-DAG: Keyword/None: convention(swift)[#Type Attribute#]; name=convention(swift)
|
||||
// TYPEATTR-DAG: Keyword/None: convention(block)[#Type Attribute#]; name=convention(block)
|
||||
// TYPEATTR-DAG: Keyword/None: convention(c)[#Type Attribute#]; name=convention(c)
|
||||
// TYPEATTR-DAG: Keyword/None: convention(thin)[#Type Attribute#]; name=convention(thin)
|
||||
// TYPEATTR-DAG: Keyword/None: escaping[#Type Attribute#]; name=escaping
|
||||
// TYPEATTR-DAG: Keyword/None: isolated(any)[#Type Attribute#]; name=isolated(any)
|
||||
// TYPEATTR-DAG: Keyword/None: noDerivative[#Type Attribute#]; name=noDerivative
|
||||
// TYPEATTR-DAG: Keyword/None: Sendable[#Type Attribute#]; name=Sendable
|
||||
// TYPEATTR-NOT: Type Attribute
|
||||
// TYPEATTR-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
|
||||
// TYPEATTR-NOT: Type Attribute
|
||||
// TYPEATTR-NOT: myIntValue
|
||||
|
||||
struct MyStruct {}
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: autoclosure[#Type Attribute#]; name=autoclosure
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: convention(swift)[#Type Attribute#]; name=convention(swift)
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: convention(block)[#Type Attribute#]; name=convention(block)
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: convention(c)[#Type Attribute#]; name=convention(c)
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: convention(thin)[#Type Attribute#]; name=convention(thin)
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: escaping[#Type Attribute#]; name=escaping
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: isolated(any)[#Type Attribute#]; name=isolated(any)
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: noDerivative[#Type Attribute#]; name=noDerivative
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: Sendable[#Type Attribute#]; name=Sendable
|
||||
//
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: retroactive[#Type Attribute#]; name=retroactive
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: unchecked[#Type Attribute#]; name=unchecked
|
||||
// TYPEATTR_INHERIT-DAG: Keyword/None: preconcurrency[#Type Attribute#]; name=preconcurrency
|
||||
|
||||
struct MyStruct : @#^STRUCT_INHERIT?check=TYPEATTR_INHERIT^# {}
|
||||
|
||||
class C : @#^CLASS_INHERIT?check=TYPEATTR_INHERIT^#,
|
||||
Array<@#^GENERIC_ARG_INHERIT?check=TYPEATTR^#>,
|
||||
@unchecked @#^CLASS_INHERIT2?check=TYPEATTR_INHERIT^# {}
|
||||
|
||||
extension C : @#^EXT_INHERIT1?check=TYPEATTR_INHERIT^# {}
|
||||
|
||||
protocol P : @#^PROTO_INHERIT?check=TYPEATTR_INHERIT^# {}
|
||||
extension C : P, @#^EXT_INHERIT2?check=TYPEATTR_INHERIT^# {}
|
||||
|
||||
var myIntValue: Int = 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user