Skip to content

Commit

Permalink
Fix parse error when apply is at eof
Browse files Browse the repository at this point in the history
  • Loading branch information
mtdowling committed Sep 10, 2019
1 parent 3f5765d commit d5f5764
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ private static void parse(State state) {
if (token.type == UNQUOTED) {
parseStatement(token, state);
} else if (token.type == ANNOTATION) {
state.pendingTraits.add(parseTraitValue(token, state, false));
state.pendingTraits.add(parseTraitValue(token, state, TraitValueType.SHAPE));
} else if (token.type == CONTROL) {
parseControlStatement(state, token);
} else if (token.type == DOC) {
Expand Down Expand Up @@ -386,22 +386,32 @@ private static void requireNamespaceOrThrow(State state) {
}
}

private static Pair<String, Node> parseTraitValue(Token token, State state, boolean memberScope) {
private enum TraitValueType { SHAPE, MEMBER, APPLY }

private static Pair<String, Node> parseTraitValue(Token token, State state, TraitValueType type) {
try {
requireNamespaceOrThrow(state);

// Resolve the trait name and ensure that the trait forms a syntactically valid value.
ShapeId.fromOptionalNamespace(state.visitor.getNamespace(), token.lexeme);
Pair<String, Node> result = Pair.of(token.lexeme, parseTraitValueBody(state));

// `apply` doesn't require any specific token to follow.
if (type == TraitValueType.APPLY) {
return result;
}

// Other kinds of trait values require an annotation or definition to follow.
if (!state.peek().isPresent()) {
throw state.syntax("Found a trait doesn't apply to anything");
}

Token next = state.peek().get();
if (next.type != ANNOTATION
&& (next.type != UNQUOTED || (!memberScope && !SUPPORTS_TRAITS.contains(next.lexeme)))) {
throw state.syntax("Traits cannot be applied to `" + next.lexeme + "`");
if (next.type != ANNOTATION) {
if (next.type != UNQUOTED
|| (type != TraitValueType.MEMBER && !SUPPORTS_TRAITS.contains(next.lexeme))) {
throw state.syntax("Traits cannot be applied to `" + next.lexeme + "`");
}
}

return result;
Expand Down Expand Up @@ -572,7 +582,7 @@ private static void parseStructuredContents(
Token token = state.expect(ANNOTATION, QUOTED, UNQUOTED, RBRACE, DOC);
while (token.type != RBRACE) {
if (token.type == ANNOTATION) {
memberTraits.add(parseTraitValue(token, state, true));
memberTraits.add(parseTraitValue(token, state, TraitValueType.MEMBER));
// Traits can't come before a closing brace, so continue
// to make sure they come before another trait or a key.
} else if (token.type == DOC) {
Expand Down Expand Up @@ -659,7 +669,7 @@ private static void parseApply(State state) {
String name = state.expect(UNQUOTED).lexeme;
ShapeId id = ShapeId.fromOptionalNamespace(state.visitor.getNamespace(), name);
Token token = state.expect(ANNOTATION);
Pair<String, Node> trait = parseTraitValue(token, state, false);
Pair<String, Node> trait = parseTraitValue(token, state, TraitValueType.APPLY);
state.visitor.onTrait(id, trait.getLeft(), trait.getRight());
state.expectNewline();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
},
"E": {
"type": "string",
"smithy.api#documentation": "Hello!"
"smithy.api#documentation": "Hello!",
"smithy.api#deprecated": {}
},
"F": {
"type": "string",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,5 @@ string T
many
lines.""")
string U

apply E @deprecated

0 comments on commit d5f5764

Please sign in to comment.