@@ -2782,6 +2782,7 @@ Parser::parseDecl(ParseDeclOptions Flags,
2782
2782
break ;
2783
2783
}
2784
2784
case tok::kw_typealias:
2785
+ DeclParsingContext.setCreateSyntax (SyntaxKind::TypealiasDecl);
2785
2786
DeclResult = parseDeclTypeAlias (Flags, Attributes, leadingLoc);
2786
2787
MayNeedOverrideCompletion = true ;
2787
2788
break ;
@@ -3976,126 +3977,115 @@ ParserStatus Parser::parseLineDirective(bool isLine) {
3976
3977
3977
3978
// / Parse a typealias decl.
3978
3979
// /
3980
+ // / \verbatim
3979
3981
// / decl-typealias:
3980
- // / 'typealias' identifier generic-params? '=' type
3981
- // / generic-where-clause?
3982
- ParsedSyntaxResult<ParsedDeclSyntax>
3983
- Parser::parseDeclTypeAliasSyntax (Parser::ParseDeclOptions Flags,
3984
- Optional<ParsedAttributeListSyntax> attrs,
3985
- Optional<ParsedModifierListSyntax> modifiers) {
3982
+ // / 'typealias' identifier generic-params? '=' type requirement-clause?
3983
+ // / \endverbatim
3984
+ ParserResult<TypeDecl>
3985
+ Parser::parseDeclTypeAlias (Parser::ParseDeclOptions Flags,
3986
+ DeclAttributes &Attributes, SourceLoc leadingLoc) {
3986
3987
ParserPosition startPosition = getParserPosition ();
3987
3988
llvm::Optional<SyntaxParsingContext> TmpCtxt;
3988
3989
TmpCtxt.emplace (SyntaxContext);
3989
3990
TmpCtxt->setBackTracking ();
3990
3991
3991
- auto typealiasKeyword = consumeTokenSyntax (tok::kw_typealias);
3992
-
3993
- ParserStatus status;
3994
-
3995
- auto applyIntroducer = [&](ParsedTypealiasDeclSyntaxBuilder &builder) {
3996
- if (attrs)
3997
- builder.useAttributes (std::move (*attrs));
3998
- if (modifiers)
3999
- builder.useModifiers (std::move (*modifiers));
4000
- builder.useTypealiasKeyword (std::move (typealiasKeyword));
4001
- };
3992
+ SourceLoc TypeAliasLoc = consumeToken (tok::kw_typealias);
3993
+ SourceLoc EqualLoc;
3994
+ Identifier Id;
3995
+ SourceLoc IdLoc;
3996
+ ParserStatus Status;
4002
3997
4003
- // Parse the name.
4004
- auto name =
4005
- parseIdentifierDeclNameSyntax (*this , " typealias" , [](const Token &next) {
4006
- return next.isAny (tok::colon, tok::equal);
4007
- });
4008
- if (name.isNull ()) {
3998
+ Status |= parseIdentifierDeclName (
3999
+ *this , Id, IdLoc, " typealias" ,
4000
+ [](const Token &next) { return next.isAny (tok::colon, tok::equal); });
4001
+ if (Status.isError ()) {
4009
4002
TmpCtxt->setTransparent ();
4010
- TmpCtxt.reset ();
4011
- ParsedTypealiasDeclSyntaxBuilder builder (*SyntaxContext);
4012
- applyIntroducer (builder);
4013
- return makeParsedError (builder.build ());
4003
+ return nullptr ;
4014
4004
}
4015
4005
4016
- // Parse optional generic parameters.
4017
- Optional<ParsedGenericParameterClauseSyntax> genericParams;
4006
+ DebuggerContextChange DCC (*this , Id, DeclKind::TypeAlias);
4007
+
4008
+ Optional<Scope> GenericsScope;
4009
+ GenericsScope.emplace (this , ScopeKind::Generics);
4010
+
4011
+ // Parse a generic parameter list if it is present.
4012
+ GenericParamList *genericParams = nullptr ;
4018
4013
if (startsWithLess (Tok)) {
4019
- auto result = parseGenericParameterClauseSyntax ();
4020
- status |= result.getStatus ();
4021
- if (!result.isNull ())
4022
- genericParams = result.get ();
4014
+ auto Result = parseGenericParameters ();
4015
+ if (Result.hasCodeCompletion () && !CodeCompletion)
4016
+ return makeParserCodeCompletionStatus ();
4017
+ genericParams = Result.getPtrOrNull ();
4018
+
4019
+ if (!genericParams) {
4020
+ // If the parser returned null, it is an already diagnosed parse error.
4021
+ } else if (!genericParams->getRequirements ().empty ()) {
4022
+ // Reject a where clause.
4023
+ diagnose (genericParams->getWhereLoc (),
4024
+ diag::associated_type_generic_parameter_list)
4025
+ .highlight (genericParams->getWhereClauseSourceRange ());
4026
+ }
4023
4027
}
4024
4028
4025
4029
if (Flags.contains (PD_InProtocol) && !genericParams && !Tok.is (tok::equal)) {
4026
- // If we're in a protocol and don't see an '=' this looks like leftover
4027
- // Swift 2 code intending to be an associatedtype.
4028
4030
TmpCtxt.reset ();
4031
+ // If we're in a protocol and don't see an '=' this looks like leftover Swift 2
4032
+ // code intending to be an associatedtype.
4029
4033
backtrackToPosition (startPosition);
4030
- return parseDeclAssociatedTypeSyntax (Flags, std::move (attrs),
4031
- std::move (modifiers));
4034
+ return parseDeclAssociatedType (Flags, Attributes, leadingLoc);
4032
4035
}
4033
-
4034
4036
TmpCtxt->setTransparent ();
4035
4037
TmpCtxt.reset ();
4036
4038
4037
- ParsedTypealiasDeclSyntaxBuilder builder (*SyntaxContext);
4038
- applyIntroducer (builder);
4039
- builder.useIdentifier (name.get ());
4040
- if (genericParams)
4041
- builder.useGenericParameterClause (std::move (*genericParams));
4039
+ auto *TAD = new (Context) TypeAliasDecl (TypeAliasLoc, EqualLoc, Id, IdLoc,
4040
+ genericParams, CurDeclContext);
4041
+ setLocalDiscriminator (TAD);
4042
+ ParserResult<TypeRepr> UnderlyingTy;
4042
4043
4043
- // Parse underlying type clause.
4044
- if (Tok.isAny (tok::equal, tok::colon)) {
4045
- ParsedTypeInitializerClauseSyntaxBuilder initBuilder (*SyntaxContext);
4044
+ if (Tok.is (tok::colon) || Tok.is (tok::equal)) {
4045
+ ContextChange CC (*this , TAD);
4046
4046
4047
- // Parse '='.
4047
+ SyntaxParsingContext InitCtx (SyntaxContext,
4048
+ SyntaxKind::TypeInitializerClause);
4048
4049
if (Tok.is (tok::colon)) {
4049
4050
// It is a common mistake to write "typealias A : Int" instead of = Int.
4050
4051
// Recognize this and produce a fixit.
4051
4052
diagnose (Tok, diag::expected_equal_in_typealias)
4052
4053
.fixItReplace (Tok.getLoc (), " = " );
4053
- ignoreToken (tok::colon);
4054
+ EqualLoc = consumeToken (tok::colon);
4054
4055
} else {
4055
- initBuilder. useEqual ( consumeTokenSyntax () );
4056
+ EqualLoc = consumeToken (tok::equal );
4056
4057
}
4057
4058
4058
- // Parse the underlying type.
4059
- auto underlyingType = parseTypeSyntax (diag::expected_type_in_typealias);
4060
- status |= underlyingType.getStatus ();
4061
- if (!underlyingType.isNull ()) {
4062
- initBuilder.useValue (underlyingType.get ());
4063
- } else {
4064
- initBuilder.useValue (
4065
- ParsedSyntaxRecorder::makeUnknownType ({}, *SyntaxContext));
4066
- }
4067
- builder.useInitializer (initBuilder.build ());
4068
- } else {
4069
- diagnose (Tok, diag::expected_equal_in_typealias);
4070
- status.setIsParseError ();
4059
+ UnderlyingTy = parseType (diag::expected_type_in_typealias);
4060
+ TAD->setTypeEndLoc (PreviousLoc);
4061
+ Status |= UnderlyingTy;
4071
4062
}
4072
4063
4073
- // Parse optional where clause.
4064
+ TAD->setUnderlyingTypeRepr (UnderlyingTy.getPtrOrNull ());
4065
+ TAD->getAttrs () = Attributes;
4066
+
4067
+ // Parse a 'where' clause if present, adding it to our GenericParamList.
4074
4068
if (Tok.is (tok::kw_where)) {
4075
- bool FirstTypeInComplete = false ;
4076
- auto whereClause = parseGenericWhereClauseSyntax (FirstTypeInComplete);
4077
- status |= whereClause.getStatus ();
4078
- builder.useGenericWhereClause (whereClause.get ());
4069
+ ContextChange CC (*this , TAD);
4070
+ Status |= parseFreestandingGenericWhereClause (genericParams);
4079
4071
}
4080
4072
4081
- return makeParsedResult (builder.build (), status);
4082
- }
4083
-
4084
- ParserResult<TypeDecl>
4085
- Parser::parseDeclTypeAlias (Parser::ParseDeclOptions Flags,
4086
- DeclAttributes &Attributes, SourceLoc leadingLoc) {
4087
- auto modifiers = SyntaxContext->popIf <ParsedModifierListSyntax>();
4088
- auto attrs = SyntaxContext->popIf <ParsedAttributeListSyntax>();
4073
+ if (UnderlyingTy.isNull ()) {
4074
+ // If there is an attempt to do code completion
4075
+ // inside of typealias type, let's just return
4076
+ // because we've seen required '=' token.
4077
+ if (EqualLoc.isInvalid ()) {
4078
+ diagnose (Tok, diag::expected_equal_in_typealias);
4079
+ Status.setIsParseError ();
4080
+ return Status;
4081
+ }
4082
+ }
4089
4083
4090
- auto parsed =
4091
- parseDeclTypeAliasSyntax (Flags, std::move (attrs), std::move (modifiers));
4092
- assert (!parsed.isNull ());
4084
+ // Exit the scope introduced for the generic parameters.
4085
+ GenericsScope.reset ();
4093
4086
4094
- SyntaxContext->addSyntax (parsed.get ());
4095
- auto syntax = SyntaxContext->topNode <DeclSyntax>();
4096
- TypeDecl *result =
4097
- cast_or_null<TypeDecl>(Generator.generate (syntax, leadingLoc));
4098
- return makeParserResult (parsed.getStatus (), result);
4087
+ addToScope (TAD);
4088
+ return DCC.fixupParserResult (Status, TAD);
4099
4089
}
4100
4090
4101
4091
// / Parse an associatedtype decl.
0 commit comments