Skip to content

Commit

Permalink
Start parsing names with argument labels.
Browse files Browse the repository at this point in the history
Basic implementatation of SE-0021, naming functions with argument
labels. Handle parsing of compound function names in various
unqualified-identifier productions, updating the AST representation of
various expressions from Identifiers to DeclNames. The result doesn't
capture all of the source locations we want; more on that later.

As part of this, remove the parsing code for the "selector-style"
method names, since we now have a replacement. The feature was never
publicized and doesn't make sense in Swift, so zap it outright.
  • Loading branch information
DougGregor committed Jan 21, 2016
1 parent 193a285 commit ecfde0e
Show file tree
Hide file tree
Showing 19 changed files with 279 additions and 184 deletions.
3 changes: 3 additions & 0 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,9 @@ ERROR(availability_query_outside_if_stmt_guard, none,
"#available may only be used as condition of an 'if', 'guard'"
" or 'while' statement", ())

ERROR(empty_arg_label_underscore, none,
"an empty argument label is spelled with '_'", ())

ERROR(expected_identifier_after_dot_expr,none,
"expected identifier after '.' expression", ())

Expand Down
17 changes: 8 additions & 9 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ NOTE(while_converting_subscript_index,none,
//------------------------------------------------------------------------------

ERROR(ambiguous_member_overload_set,none,
"ambiguous reference to member '%0'", (StringRef))
"ambiguous reference to member %0", (DeclName))

ERROR(ambiguous_subscript,none,
"ambiguous subscript with base type %0 and index type %1",
Expand All @@ -76,9 +76,9 @@ NOTE(did_you_mean_raw_type,none,
"did you mean to specify a raw type on the enum declaration?", ())

ERROR(expected_argument_in_contextual_member,none,
"contextual member %0 expects argument of type %1", (Identifier, Type))
"contextual member %0 expects argument of type %1", (DeclName, Type))
ERROR(unexpected_argument_in_contextual_member,none,
"contextual member %0 has no associated value", (Identifier))
"contextual member %0 has no associated value", (DeclName))

ERROR(could_not_use_value_member,none,
"member %1 cannot be used on value of type %0", (Type, DeclName))
Expand Down Expand Up @@ -443,7 +443,7 @@ ERROR(unspaced_unary_operator,none,


ERROR(use_unresolved_identifier,none,
"use of unresolved %select{identifier|operator}1 %0", (Identifier, bool))
"use of unresolved %select{identifier|operator}1 %0", (DeclName, bool))
ERROR(use_undeclared_type,none,
"use of undeclared type %0", (Identifier))
ERROR(use_undeclared_type_did_you_mean,none,
Expand All @@ -470,7 +470,7 @@ ERROR(use_non_type_value,none,
NOTE(use_non_type_value_prev,none,
"%0 declared here", (Identifier))
ERROR(use_local_before_declaration,none,
"use of local variable %0 before its declaration", (Identifier))
"use of local variable %0 before its declaration", (DeclName))
ERROR(unsupported_existential_type,none,
"protocol %0 can only be used as a generic constraint because it has "
"Self or associated type requirements", (Identifier))
Expand Down Expand Up @@ -647,11 +647,10 @@ ERROR(argument_out_of_order_named_unnamed,none,

ERROR(instance_member_use_on_type,none,
"use of instance member %1 on type %0; "
"did you mean to use a value of type %0 instead?", (Type, Identifier))
"did you mean to use a value of type %0 instead?", (Type, DeclName))
ERROR(instance_member_in_initializer,none,
"cannot use instance member %0 within property initializer; "
"property initializers run before 'self' is available", (Identifier))

"property initializers run before 'self' is available", (DeclName))

ERROR(missing_argument_named,none,
"missing argument for parameter %0 in call", (Identifier))
Expand Down Expand Up @@ -1779,7 +1778,7 @@ ERROR(inout_expr_outside_of_call,none,

ERROR(unresolved_member_no_inference,none,
"reference to member %0 cannot be resolved without a contextual type",
(Identifier))
(DeclName))

ERROR(type_of_expression_is_ambiguous,none,
"type of expression is ambiguous without more context", ())
Expand Down
22 changes: 11 additions & 11 deletions include/swift/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1175,26 +1175,26 @@ class OverloadedMemberRefExpr : public OverloadSetRefExpr {
return E->getKind() == ExprKind::OverloadedMemberRef;
}
};

/// UnresolvedDeclRefExpr - This represents use of an undeclared identifier,
/// which may ultimately be a use of something that hasn't been defined yet, it
/// may be a use of something that got imported (which will be resolved during
/// sema), or may just be a use of an unknown identifier.
///
class UnresolvedDeclRefExpr : public Expr {
Identifier Name;
DeclName Name;
SourceLoc Loc;
DeclRefKind RefKind;
bool IsSpecialized = false;

public:
UnresolvedDeclRefExpr(Identifier name, DeclRefKind refKind, SourceLoc loc)
UnresolvedDeclRefExpr(DeclName name, DeclRefKind refKind, SourceLoc loc)
: Expr(ExprKind::UnresolvedDeclRef, /*Implicit=*/loc.isInvalid()),
Name(name), Loc(loc), RefKind(refKind) {
}

bool hasName() const { return !Name.empty(); }
Identifier getName() const { return Name; }
bool hasName() const { return static_cast<bool>(Name); }
DeclName getName() const { return Name; }
DeclRefKind getRefKind() const { return RefKind; }

void setSpecialized(bool specialized) { IsSpecialized = specialized; }
Expand Down Expand Up @@ -1401,17 +1401,17 @@ class DynamicSubscriptExpr : public DynamicLookupExpr {
class UnresolvedMemberExpr : public Expr {
SourceLoc DotLoc;
SourceLoc NameLoc;
Identifier Name;
DeclName Name;
Expr *Argument;

public:
UnresolvedMemberExpr(SourceLoc dotLoc, SourceLoc nameLoc,
Identifier name, Expr *argument)
DeclName name, Expr *argument)
: Expr(ExprKind::UnresolvedMember, /*Implicit=*/false),
DotLoc(dotLoc), NameLoc(nameLoc), Name(name), Argument(argument) {
}

Identifier getName() const { return Name; }
DeclName getName() const { return Name; }
SourceLoc getNameLoc() const { return NameLoc; }
SourceLoc getDotLoc() const { return DotLoc; }
Expr *getArgument() const { return Argument; }
Expand Down Expand Up @@ -1898,9 +1898,9 @@ class UnresolvedDotExpr : public Expr {
Expr *SubExpr;
SourceLoc DotLoc;
SourceLoc NameLoc;
Identifier Name;
DeclName Name;
public:
UnresolvedDotExpr(Expr *subexpr, SourceLoc dotloc, Identifier name,
UnresolvedDotExpr(Expr *subexpr, SourceLoc dotloc, DeclName name,
SourceLoc nameloc, bool Implicit)
: Expr(ExprKind::UnresolvedDot, Implicit), SubExpr(subexpr), DotLoc(dotloc),
NameLoc(nameloc), Name(name) {}
Expand All @@ -1916,7 +1916,7 @@ class UnresolvedDotExpr : public Expr {
Expr *getBase() const { return SubExpr; }
void setBase(Expr *e) { SubExpr = e; }

Identifier getName() const { return Name; }
DeclName getName() const { return Name; }
SourceLoc getNameLoc() const { return NameLoc; }

static bool classof(const Expr *E) {
Expand Down
6 changes: 5 additions & 1 deletion include/swift/AST/Identifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,12 @@ class Identifier {
|| (C >= 0xE0100 && C <= 0xE01EF);
}

static bool isEditorPlaceholder(StringRef name) {
return name.startswith("<#");
}

bool isEditorPlaceholder() const {
return !empty() && Pointer[0] == '<' && Pointer[1] == '#';
return !empty() && isEditorPlaceholder(str());
}

void *getAsOpaquePointer() const { return (void *)Pointer; }
Expand Down
25 changes: 23 additions & 2 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,13 +373,17 @@ class Parser {
class BacktrackingScope {
Parser &P;
ParserPosition PP;
bool Backtrack = true;

public:
BacktrackingScope(Parser &P) : P(P), PP(P.getParserPosition()) {}

~BacktrackingScope() {
P.backtrackToPosition(PP);
if (Backtrack)
P.backtrackToPosition(PP);
}

void cancelBacktrack() { Backtrack = false; }
};

/// RAII object that, when it is destructed, restores the parser and lexer to
Expand Down Expand Up @@ -1096,7 +1100,24 @@ class Parser {
ParserResult<Expr> parseExprSuper();
ParserResult<Expr> parseExprConfiguration();
Expr *parseExprStringLiteral();


/// If the token is an escaped identifier being used as an argument
/// label, but doesn't need to be, diagnose it.
void diagnoseEscapedArgumentLabel(const Token &tok);

/// Parse an unqualified-identifier.

This comment has been minimized.

Copy link
@jrose-apple

jrose-apple Jan 21, 2016

Contributor

Aside: I think we need a new name for this production. "decl-name"?

This comment has been minimized.

Copy link
@DougGregor

DougGregor Jan 21, 2016

Author Member

Fair point; I'm going to start with unqualified-decl-name.

///
/// unqualified-identifier:
/// identifier
/// identifier '(' ((identifier | '_') ':') + ')'
///
///
/// \param allowInit Whether to allow 'init' for initializers.
/// \param loc Will be populated with the location of the name.
/// \param diag The diagnostic to emit if this is not a name.
DeclName parseUnqualifiedIdentifier(bool allowInit, SourceLoc &loc,
const Diagnostic &diag);

Expr *parseExprIdentifier();
Expr *parseExprEditorPlaceholder(Token PlaceholderTok,
Identifier PlaceholderId);
Expand Down
2 changes: 1 addition & 1 deletion lib/IDE/SyntaxModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,7 @@ class IdRefWalker : public ASTWalker {
if (DRE->getRefKind() != DeclRefKind::Ordinary)
return { true, E };
if (!Fn(CharSourceRange(DRE->getSourceRange().Start,
DRE->getName().getLength())))
DRE->getName().getBaseName().getLength())))
return { false, nullptr };
}
return { true, E };
Expand Down
Loading

1 comment on commit ecfde0e

@rudkx
Copy link
Contributor

@rudkx rudkx commented on ecfde0e Jan 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DougGregor It looks like this broke the LLDB build. From SwiftASTManipulator.cpp:
swift::Identifier name = decl_ref_expr->getName();

It's using name.str(), etc., so I don't think it's as simple as changing this to a DeclName.

If you're unable to get this fixed up soon I'll revert.

Please sign in to comment.