Chromium Code Reviews| Index: frog/leg/scanner/listener.dart |
| diff --git a/frog/leg/scanner/listener.dart b/frog/leg/scanner/listener.dart |
| index 55904511798dcff819328d9f996d109b052f7ef2..1fd80e7f355b580d07f80d4126fb87a87687c25f 100644 |
| --- a/frog/leg/scanner/listener.dart |
| +++ b/frog/leg/scanner/listener.dart |
| @@ -152,10 +152,10 @@ class Listener { |
| void endLabelledStatement(Token colon) { |
| } |
| - void beginLibraryTag(Token token) { |
| + void beginScriptTag(Token token) { |
|
ahe
2012/01/26 19:24:28
I'd like to keep the groups of begin/end sorted.
Lasse Reichstein Nielsen
2012/01/27 11:39:04
Done.
|
| } |
| - void endLibraryTag(bool hasPrefix, Token beginToken, Token endToken) { |
| + void endScriptTag(bool hasPrefix, Token beginToken, Token endToken) { |
| } |
| void beginLiteralMapEntry(Token token) { |
| @@ -164,6 +164,12 @@ class Listener { |
| void endLiteralMapEntry(Token colon, Token endToken) { |
| } |
| + void beginLiteralString(Token token) { |
| + } |
| + |
| + void endLiteralString(int interpolationCount) { |
| + } |
| + |
| void beginMember(Token token) { |
| } |
| @@ -335,9 +341,6 @@ class Listener { |
| void handleLiteralNull(Token token) { |
| } |
| - void handleLiteralString(Token token) { |
| - } |
| - |
| void handleModifier(Token token) { |
| } |
| @@ -371,7 +374,7 @@ class Listener { |
| void handleQualified(Token period) { |
| } |
| - void handleStringInterpolationParts(int count) { |
| + void handleStringPart(Token token) { |
| } |
| void handleSuperExpression(Token token) { |
| @@ -454,20 +457,34 @@ class ParserError { |
| class ElementListener extends Listener { |
| final Canceler canceler; |
| final CompilationUnitElement compilationUnitElement; |
| + final StringValidator stringValidator; |
| + final List<StringQuoting> interpolationScope; |
|
ahe
2012/01/26 19:24:28
Please use Link.
|
| Link<Node> nodes = const EmptyLink<Node>(); |
| - ElementListener(Canceler this.canceler, |
| - CompilationUnitElement this.compilationUnitElement); |
| + ElementListener(Canceler canceler, |
| + CompilationUnitElement this.compilationUnitElement) |
| + : this.canceler = canceler, |
| + stringValidator = new StringValidator(canceler), |
| + interpolationScope = <StringQuoting>[]; |
| + |
| + LiteralString popLiteralString() { |
| + Node node = popNode(); |
| + if (node is !LiteralString) { |
| + canceler.cancel("String is not a compile time constant", node: node); |
| + return null; |
| + } |
| + return node; |
| + } |
| - void endLibraryTag(bool hasPrefix, Token beginToken, Token endToken) { |
| + void endScriptTag(bool hasPrefix, Token beginToken, Token endToken) { |
| LiteralString prefix = null; |
| Identifier argumentName = null; |
| if (hasPrefix) { |
| - prefix = popNode(); |
| + prefix = popLiteralString(); |
| argumentName = popNode(); |
| } |
| - LiteralString firstArgument = popNode(); |
| + LiteralString firstArgument = popLiteralString(); |
| Identifier tag = popNode(); |
| compilationUnitElement.addTag(new ScriptTag(tag, firstArgument, |
| argumentName, prefix, |
| @@ -672,15 +689,59 @@ class ElementListener extends Listener { |
| return new NodeList(beginToken, nodes, endToken, sourceDelimiter); |
| } |
| - void handleLiteralString(Token token) { |
| - pushNode(new LiteralString(token)); |
| + void beginLiteralString(Token token) { |
| + SourceString source = token.value; |
| + StringQuoting quoting = StringValidator.quotingFromString(source); |
| + interpolationScope.add(quoting); |
| + // Just wrap the token for now. At the end of the interpolation, |
| + // when we know how many there are, go back and validate the tokens. |
| + pushNode(new LiteralString(token, null)); |
| + } |
| + |
| + void handleStringPart(Token token) { |
| + // Just push an unvalidated token now, and replace it when we know the |
| + // end of the interpolation. |
| + pushNode(new LiteralString(token, null)); |
| + } |
| + |
| + void endLiteralString(int count) { |
| + StringQuoting quoting = interpolationScope.removeLast(); |
| + |
| + Link<StringInterpolationPart> parts = |
| + const EmptyLink<StringInterpolationPart>(); |
| + bool isLast = true; |
|
ahe
2012/01/26 19:24:28
This confused the heck out of me. A comment to rem
Lasse Reichstein Nielsen
2012/01/27 11:39:04
Done.
|
| + for (int i = 0; i < count; i++) { |
| + LiteralString string = popNode(); |
| + QuotedString validation = |
| + stringValidator.validateInterpolationPart(string.token, quoting, |
| + isFirst: false, |
| + isLast: isLast); |
| + string = new LiteralString(string.token, validation); |
|
ahe
2012/01/26 19:24:28
Perhaps add a comment that you're replacing the no
Lasse Reichstein Nielsen
2012/01/27 11:39:04
Done.
|
| + Expression expression = popNode(); |
| + parts = parts.prepend(new StringInterpolationPart(expression, string)); |
| + isLast = false; |
| + } |
| + |
| + LiteralString string = popNode(); |
| + QuotedString validation = |
| + stringValidator.validateInterpolationPart(string.token, quoting, |
| + isFirst: true, |
| + isLast: isLast); |
| + string = new LiteralString(string.token, validation); |
| + if (isLast) { |
| + pushNode(string); |
| + } else { |
| + NodeList nodes = new NodeList(null, parts, null, null); |
| + pushNode(new StringInterpolation(string, nodes)); |
| + } |
| } |
| } |
| class NodeListener extends ElementListener { |
| final Logger logger; |
| - NodeListener(Canceler canceler, Logger this.logger) : super(canceler, null); |
| + NodeListener(Canceler canceler, Logger this.logger) |
| + : super(canceler, null); |
|
karlklose
2012/01/27 09:11:59
This can go back to the previous line again.
Lasse Reichstein Nielsen
2012/01/27 11:39:04
Done.
|
| void endClassDeclaration(int interfacesCount, Token beginToken, |
| Token extendsKeyword, Token implementsKeyword, |
| @@ -1051,21 +1112,6 @@ class NodeListener extends ElementListener { |
| pushNode(new NamedArgument(name, colon, expression)); |
| } |
| - void handleStringInterpolationParts(int count) { |
| - Link<StringInterpolationPart> parts = |
| - const EmptyLink<StringInterpolationPart>(); |
| - for (int i = 0; i < count; i++) { |
| - LiteralString string = popNode(); |
| - Expression expression = popNode(); |
| - parts = parts.prepend(new StringInterpolationPart(expression, string)); |
| - } |
| - if (!parts.isEmpty()) { |
| - LiteralString string = popNode(); |
| - NodeList nodes = new NodeList(null, parts, null, null); |
| - pushNode(new StringInterpolation(string, nodes)); |
| - } |
| - } |
| - |
| void endOptionalFormalParameters(int count, |
| Token beginToken, Token endToken) { |
| pushNode(makeNodeList(count, beginToken, endToken, ',')); |