Skip to content

Commit

Permalink
Fix trait parse error for shape IDs
Browse files Browse the repository at this point in the history
closes #2021
  • Loading branch information
mtdowling committed Oct 27, 2023
1 parent c752eac commit 81afebb
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static Node expectAndSkipNode(IdlModelLoader loader, SourceLocation location) {
return result;
case IDENTIFIER:
String shapeId = loader.internString(IdlShapeIdParser.expectAndSkipShapeId(tokenizer));
return parseIdentifier(loader, shapeId, location);
return createIdentifier(loader, shapeId, location);
case NUMBER:
Number number = tokenizer.getCurrentTokenNumberValue();
tokenizer.next();
Expand All @@ -95,10 +95,10 @@ static Node expectAndSkipNode(IdlModelLoader loader, SourceLocation location) {
* @param location Source location to assign to the identifier.
* @return Returns the parsed identifier.
*/
static Node parseIdentifier(IdlModelLoader loader, String identifier, SourceLocation location) {
static Node createIdentifier(IdlModelLoader loader, String identifier, SourceLocation location) {
Keyword keyword = Keyword.from(identifier);
return keyword == null
? parseSyntacticShapeId(loader, identifier, location)
? createSyntacticShapeId(loader, identifier, location)
: keyword.createNode(location);
}

Expand Down Expand Up @@ -138,7 +138,7 @@ static Keyword from(String keyword) {
}
}

private static Node parseSyntacticShapeId(
private static Node createSyntacticShapeId(
IdlModelLoader loader,
String identifier,
SourceLocation location
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,19 +193,30 @@ private static Node parseTraitValueBody(IdlModelLoader loader, SourceLocation lo
}
case IDENTIFIER:
default:
String identifier = loader.internString(tokenizer.getCurrentTokenLexeme());
tokenizer.next();
// Handle: `foo`, `foo$bar`, `foo.bar#baz`, `foo.bar#baz$bam`, `foo: bam`
String identifier = loader.internString(IdlShapeIdParser.expectAndSkipShapeId(tokenizer));
tokenizer.skipWsAndDocs();
if (tokenizer.getCurrentToken() == IdlToken.COLON) {
if (tokenizer.getCurrentToken() == IdlToken.RPAREN || isItDefinitelyShapeId(identifier)) {
return IdlNodeParser.createIdentifier(loader, identifier, location);
} else {
tokenizer.expect(IdlToken.COLON);
tokenizer.next();
tokenizer.skipWsAndDocs();
return parseStructuredTrait(loader, new StringNode(identifier, location));
} else {
return IdlNodeParser.parseIdentifier(loader, identifier, location);
}
}
}

private static boolean isItDefinitelyShapeId(String identifier) {
for (int i = 0; i < identifier.length(); i++) {
char c = identifier.charAt(i);
if (c == '.' || c == '$' || c == '#') {
return true;
}
}
return false;
}

private static ObjectNode parseStructuredTrait(IdlModelLoader loader, StringNode firstKey) {
IdlInternalTokenizer tokenizer = loader.getTokenizer();
loader.increaseNestingLevel();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Syntax error at line 4, column 8: Expected RPAREN(')') but found IDENTIFIER('MyString') | Model
// Syntax error at line 4, column 8: Expected COLON(':') but found IDENTIFIER('MyString') | Model
namespace com.foo
@foo(
string MyString
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Syntax error at line 4, column 30: Expected RPAREN(')') but found DOT('.') | Model
// Syntax error at line 4, column 42: Expected RPAREN(')') but found COLON(':') | Model
namespace smithy.example

@externalDocumentation(smithy.example#foo: "bar")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"smithy": "2.0",
"shapes": {
"smithy.example#StructA": {
"type": "structure",
"members": {
"id": {
"target": "smithy.api#String"
}
}
},
"smithy.example#StructB": {
"type": "structure",
"members": {
"structAId": {
"target": "smithy.api#String",
"traits": {
"smithy.example#link": "smithy.example#StructA$id"
}
}
}
},
"smithy.example#StructC": {
"type": "structure",
"members": {
"structAId": {
"target": "smithy.api#String",
"traits": {
"smithy.example#link": "smithy.example#StructA$id"
}
}
}
},
"smithy.example#StructD": {
"type": "structure",
"members": {
"structAId": {
"target": "smithy.api#String",
"traits": {
"smithy.example#link": "smithy.example#StructA"
}
}
}
},
"smithy.example#link": {
"type": "string",
"traits": {
"smithy.api#idRef": {},
"smithy.api#trait": {}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
$version: "2.0"

namespace smithy.example

@trait
@idRef
string link

structure StructA {
id: String
}

structure StructB {
@link(StructA$id)
structAId: String
}

structure StructC {
@link(smithy.example#StructA$id)
structAId: String
}

structure StructD {
@link(smithy.example#StructA)
structAId: String
}

0 comments on commit 81afebb

Please sign in to comment.