Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: frog/leg/tree/nodes.dart

Issue 9642001: Make string juxtaposition combine properly with string interpolations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments so far. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 interface Visitor<R> { 5 interface Visitor<R> {
6 R visitBlock(Block node); 6 R visitBlock(Block node);
7 R visitBreakStatement(BreakStatement node); 7 R visitBreakStatement(BreakStatement node);
8 R visitCatchBlock(CatchBlock node); 8 R visitCatchBlock(CatchBlock node);
9 R visitClassNode(ClassNode node); 9 R visitClassNode(ClassNode node);
10 R visitConditional(Conditional node); 10 R visitConditional(Conditional node);
11 R visitContinueStatement(ContinueStatement node); 11 R visitContinueStatement(ContinueStatement node);
12 R visitDoWhile(DoWhile node); 12 R visitDoWhile(DoWhile node);
13 R visitEmptyStatement(EmptyStatement node); 13 R visitEmptyStatement(EmptyStatement node);
14 R visitExpressionStatement(ExpressionStatement node); 14 R visitExpressionStatement(ExpressionStatement node);
15 R visitFor(For node); 15 R visitFor(For node);
16 R visitForInStatement(ForInStatement node); 16 R visitForInStatement(ForInStatement node);
17 R visitFunctionDeclaration(FunctionDeclaration node); 17 R visitFunctionDeclaration(FunctionDeclaration node);
18 R visitFunctionExpression(FunctionExpression node); 18 R visitFunctionExpression(FunctionExpression node);
19 R visitIdentifier(Identifier node); 19 R visitIdentifier(Identifier node);
20 R visitIf(If node); 20 R visitIf(If node);
21 R visitLabeledStatement(LabeledStatement node); 21 R visitLabeledStatement(LabeledStatement node);
22 R visitLiteralBool(LiteralBool node); 22 R visitLiteralBool(LiteralBool node);
23 R visitLiteralDouble(LiteralDouble node); 23 R visitLiteralDouble(LiteralDouble node);
24 R visitLiteralInt(LiteralInt node); 24 R visitLiteralInt(LiteralInt node);
25 R visitLiteralList(LiteralList node); 25 R visitLiteralList(LiteralList node);
26 R visitLiteralMap(LiteralMap node); 26 R visitLiteralMap(LiteralMap node);
27 R visitLiteralMapEntry(LiteralMapEntry node); 27 R visitLiteralMapEntry(LiteralMapEntry node);
28 R visitLiteralNull(LiteralNull node); 28 R visitLiteralNull(LiteralNull node);
29 R visitLiteralString(LiteralString node); 29 R visitLiteralString(LiteralString node);
30 R visitLiteralStringJuxtaposition(LiteralStringJuxtaposition node); 30 R visitStringJuxtaposition(StringJuxtaposition node);
31 R visitModifiers(Modifiers node); 31 R visitModifiers(Modifiers node);
32 R visitNamedArgument(NamedArgument node); 32 R visitNamedArgument(NamedArgument node);
33 R visitNewExpression(NewExpression node); 33 R visitNewExpression(NewExpression node);
34 R visitNodeList(NodeList node); 34 R visitNodeList(NodeList node);
35 R visitOperator(Operator node); 35 R visitOperator(Operator node);
36 R visitParenthesizedExpression(ParenthesizedExpression node); 36 R visitParenthesizedExpression(ParenthesizedExpression node);
37 R visitReturn(Return node); 37 R visitReturn(Return node);
38 R visitScriptTag(ScriptTag node); 38 R visitScriptTag(ScriptTag node);
39 R visitSend(Send node); 39 R visitSend(Send node);
40 R visitSendSet(SendSet node); 40 R visitSendSet(SendSet node);
41 R visitStringInterpolation(StringInterpolation node); 41 R visitStringInterpolation(StringInterpolation node);
42 R visitStringInterpolationPart(StringInterpolationPart node); 42 R visitStringInterpolationPart(StringInterpolationPart node);
43 R visitSwitchCase(SwitchCase node); 43 R visitSwitchCase(SwitchCase node);
44 R visitSwitchStatement(SwitchStatement node); 44 R visitSwitchStatement(SwitchStatement node);
45 R visitThrow(Throw node); 45 R visitThrow(Throw node);
46 R visitTryStatement(TryStatement node); 46 R visitTryStatement(TryStatement node);
47 R visitTypeAnnotation(TypeAnnotation node); 47 R visitTypeAnnotation(TypeAnnotation node);
48 R visitTypedef(Typedef node); 48 R visitTypedef(Typedef node);
49 R visitTypeVariable(TypeVariable node); 49 R visitTypeVariable(TypeVariable node);
50 R visitVariableDefinitions(VariableDefinitions node); 50 R visitVariableDefinitions(VariableDefinitions node);
51 R visitWhile(While node); 51 R visitWhile(While node);
52 } 52 }
53 53
54 Token firstBeginToken(Node first, Node second) { 54 Token firstBeginToken(Node first, Node second) {
55 if (first !== null) return first.getBeginToken(); 55 if (first !== null) return first.getBeginToken();
56 if (second !== null) return second.getBeginToken(); 56 if (second !== null) return second.getBeginToken();
57 return null; 57 return null;
58 } 58 }
59 59
60 class NodeAssertionFailure implements Exception {
61 final Node node;
62 final String message;
63 InvalidNodeException(this.node, this.message);
64 }
65
60 /** 66 /**
61 * A node in a syntax tree. 67 * A node in a syntax tree.
62 * 68 *
63 * The abstract part of "abstract syntax tree" is invalidated when 69 * The abstract part of "abstract syntax tree" is invalidated when
64 * supporting tools such as code formatting. These tools need concrete 70 * supporting tools such as code formatting. These tools need concrete
65 * syntax such as parentheses and no constant folding. 71 * syntax such as parentheses and no constant folding.
66 * 72 *
67 * We support these tools by storing additional references back to the 73 * We support these tools by storing additional references back to the
68 * token stream. These references are stored in fields ending with 74 * token stream. These references are stored in fields ending with
69 * "Token". 75 * "Token".
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 NodeList asNodeList() => null; 136 NodeList asNodeList() => null;
131 Operator asOperator() => null; 137 Operator asOperator() => null;
132 ParenthesizedExpression asParenthesizedExpression() => null; 138 ParenthesizedExpression asParenthesizedExpression() => null;
133 Return asReturn() => null; 139 Return asReturn() => null;
134 ScriptTag asScriptTag() => null; 140 ScriptTag asScriptTag() => null;
135 Send asSend() => null; 141 Send asSend() => null;
136 SendSet asSendSet() => null; 142 SendSet asSendSet() => null;
137 Statement asStatement() => null; 143 Statement asStatement() => null;
138 StringInterpolation asStringInterpolation() => null; 144 StringInterpolation asStringInterpolation() => null;
139 StringInterpolationPart asStringInterpolationPart() => null; 145 StringInterpolationPart asStringInterpolationPart() => null;
146 StringJuxtaposition asStringJuxtaposition() => null;
140 SwitchCase asSwitchCase() => null; 147 SwitchCase asSwitchCase() => null;
141 SwitchStatement asSwitchStatement() => null; 148 SwitchStatement asSwitchStatement() => null;
142 Throw asThrow() => null; 149 Throw asThrow() => null;
143 TryStatement asTryStatement() => null; 150 TryStatement asTryStatement() => null;
144 TypeAnnotation asTypeAnnotation() => null; 151 TypeAnnotation asTypeAnnotation() => null;
145 Typedef asTypedef() => null; 152 Typedef asTypedef() => null;
146 TypeVariable asTypeVariable() => null; 153 TypeVariable asTypeVariable() => null;
147 VariableDefinitions asVariableDefinitions() => null; 154 VariableDefinitions asVariableDefinitions() => null;
148 While asWhile() => null; 155 While asWhile() => null;
149 156
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 731
725 int get leftQuoteLength() => (raw ? 1 : 0) + leftQuoteCharCount; 732 int get leftQuoteLength() => (raw ? 1 : 0) + leftQuoteCharCount;
726 int get rightQuoteLength() => (leftQuoteCharCount > 2) ? 3 : 1; 733 int get rightQuoteLength() => (leftQuoteCharCount > 2) ? 3 : 1;
727 static StringQuoting getQuoting(int quote, bool raw, int quoteLength) { 734 static StringQuoting getQuoting(int quote, bool raw, int quoteLength) {
728 int index = quoteLength - 1; 735 int index = quoteLength - 1;
729 if (quoteLength > 2) index -= 1; 736 if (quoteLength > 2) index -= 1;
730 return mapping[(raw ? 1 : 0) + index * 2 + (quote === $SQ ? 8 : 0)]; 737 return mapping[(raw ? 1 : 0) + index * 2 + (quote === $SQ ? 8 : 0)];
731 } 738 }
732 } 739 }
733 740
734 class DartString implements Iterable<int> {
735 // This is a convenience constructor. If you need a const literal DartString,
736 // use [const LiteralDartString(string)] directly.
737 factory DartString.literal(String string) => new LiteralDartString(string);
738 factory DartString.rawString(SourceString source, int length) =>
739 new RawSourceDartString(source, length);
740 factory DartString.escapedString(SourceString source, int length) =>
741 new EscapedSourceDartString(source, length);
742 const DartString();
743 abstract int get length();
744 bool isEmpty() => length == 0;
745 abstract Iterator<int> iterator();
746 abstract String slowToString();
747
748 bool operator ==(var other) {
749 if (other is !DartString) return false;
750 DartString otherString = other;
751 if (length != otherString.length) return false;
752 Iterator it1 = iterator();
753 Iterator it2 = otherString.iterator();
754 while (it1.hasNext()) {
755 if (it1.next() != it2.next()) return false;
756 }
757 return true;
758 }
759 String toString() => "DartString#${length}:${slowToString()}";
760 abstract SourceString get source();
761 }
762
763 class LiteralDartString extends DartString {
764 final String string;
765 const LiteralDartString(this.string);
766 int get length() => string.length;
767 Iterator<int> iterator() => new StringCodeIterator(string);
768 String slowToString() => string;
769 SourceString get source() => new StringWrapper(string);
770 }
771
772 class SourceBasedDartString extends DartString {
773 String toStringCache = null;
774 final SourceString source;
775 final int length;
776 SourceBasedDartString(this.source, this.length);
777 abstract Iterator<int> iterator();
778 }
779
780 class RawSourceDartString extends SourceBasedDartString {
781 RawSourceDartString(source, length) : super(source, length);
782 Iterator<int> iterator() => source.iterator();
783 String slowToString() {
784 if (toStringCache !== null) return toStringCache;
785 toStringCache = source.slowToString();
786 return toStringCache;
787 }
788 }
789
790 class EscapedSourceDartString extends SourceBasedDartString {
791 EscapedSourceDartString(source, length) : super(source, length);
792 Iterator<int> iterator() {
793 if (toStringCache !== null) return new StringCodeIterator(toStringCache);
794 return new StringEscapeIterator(source);
795 }
796 String slowToString() {
797 if (toStringCache !== null) return toStringCache;
798 StringBuffer buffer = new StringBuffer();
799 StringEscapeIterator it = new StringEscapeIterator(source);
800 while (it.hasNext()) {
801 buffer.addCharCode(it.next());
802 }
803 toStringCache = buffer.toString();
804 return toStringCache;
805 }
806 }
807
808 class ConsDartString extends DartString {
809 final DartString left;
810 final DartString right;
811 final int length;
812 int hashCache = null;
813 String toStringCache;
814 ConsDartString(DartString left, DartString right)
815 : this.left = left,
816 this.right = right,
817 length = left.length + right.length;
818
819 Iterator<int> iterator() => new ConsDartStringIterator(this);
820
821 String slowToString() {
822 if (toStringCache !== null) return toStringCache;
823 toStringCache = left.slowToString().concat(right.slowToString());
824 return toStringCache;
825 }
826 SourceString get source() => new StringWrapper(slowToString());
827 }
828
829 class ConsDartStringIterator implements Iterator<int> {
830 Iterator<int> current;
831 DartString right;
832 bool hasNextLookAhead;
833 ConsDartStringIterator(ConsDartString cons)
834 : current = cons.left.iterator(),
835 right = cons.right {
836 hasNextLookAhead = current.hasNext();
837 if (!hasNextLookAhead) {
838 nextPart();
839 }
840 }
841 bool hasNext() {
842 return hasNextLookAhead;
843 }
844 int next() {
845 assert(hasNextLookAhead);
846 int result = current.next();
847 hasNextLookAhead = current.hasNext();
848 if (!hasNextLookAhead) {
849 nextPart();
850 }
851 return result;
852 }
853 void nextPart() {
854 if (right !== null) {
855 current = right.iterator();
856 right = null;
857 hasNextLookAhead = current.hasNext();
858 }
859 }
860 }
861
862 /** 741 /**
863 *Iterator that returns the actual string contents of a string with escapes. 742 * Superclass for classes representing string literals.
864 */ 743 */
865 class StringEscapeIterator implements Iterator<int>{ 744 class StringNode extends Expression {
866 final Iterator<int> source; 745 abstract DartString get dartString();
867 StringEscapeIterator(SourceString source) : this.source = source.iterator(); 746 abstract bool get isInterpolation();
868 bool hasNext() => source.hasNext();
869 int next() {
870 int code = source.next();
871 if (code !== $BACKSLASH) {
872 return code;
873 }
874 code = source.next();
875 if (code === $n) return $LF;
876 if (code === $r) return $CR;
877 if (code === $t) return $TAB;
878 if (code === $b) return $BS;
879 if (code === $f) return $FF;
880 if (code === $v) return $VTAB;
881 if (code === $x) {
882 int value = hexDigitValue(source.next());
883 value = value * 16 + hexDigitValue(source.next());
884 return value;
885 }
886 if (code === $u) {
887 int value = 0;
888 code = source.next();
889 if (code === $OPEN_CURLY_BRACKET) {
890 for (code = source.next();
891 code != $CLOSE_CURLY_BRACKET;
892 code = source.next()) {
893 value = value * 16 + hexDigitValue(code);
894 }
895 return value;
896 }
897 // Four digit hex value.
898 value = hexDigitValue(code);
899 for (int i = 0; i < 3; i++) {
900 code = source.next();
901 value = value * 16 + hexDigitValue(code);
902 }
903 return value;
904 }
905 return code;
906 }
907 } 747 }
908 748
749 class LiteralString extends StringNode {
750 final Token token;
751 /** Non-null on validated string literals. */
752 final DartString dartString;
909 753
910 class LiteralString extends Literal<SourceString> { 754 LiteralString(this.token, this.dartString);
911 /** Set on validated string literals. */
912 final DartString dartString = null;
913
914 LiteralString(Token token, this.dartString) : super(token, null);
915 755
916 LiteralString asLiteralString() => this; 756 LiteralString asLiteralString() => this;
917 757
758 void visitChildren(Visitor visitor) {}
759
760 bool get isInterpolation() => false;
918 bool isValidated() => dartString !== null; 761 bool isValidated() => dartString !== null;
919 762
920 SourceString get value() => token.value; 763 Token getBeginToken() => token;
764 Token getEndToken() => token;
921 765
922 accept(Visitor visitor) => visitor.visitLiteralString(this); 766 accept(Visitor visitor) => visitor.visitLiteralString(this);
923 } 767 }
924 768
925 class LiteralNull extends Literal<SourceString> { 769 class LiteralNull extends Literal<SourceString> {
926 LiteralNull(Token token) : super(token, null); 770 LiteralNull(Token token) : super(token, null);
927 771
928 LiteralNull asLiteralNull() => this; 772 LiteralNull asLiteralNull() => this;
929 773
930 SourceString get value() => null; 774 SourceString get value() => null;
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 visitChildren(Visitor visitor) => nodes.accept(visitor); 1085 visitChildren(Visitor visitor) => nodes.accept(visitor);
1242 1086
1243 bool isStatic() => (flags & FLAG_STATIC) != 0; 1087 bool isStatic() => (flags & FLAG_STATIC) != 0;
1244 bool isAbstract() => (flags & FLAG_ABSTRACT) != 0; 1088 bool isAbstract() => (flags & FLAG_ABSTRACT) != 0;
1245 bool isFinal() => (flags & FLAG_FINAL) != 0; 1089 bool isFinal() => (flags & FLAG_FINAL) != 0;
1246 bool isVar() => (flags & FLAG_VAR) != 0; 1090 bool isVar() => (flags & FLAG_VAR) != 0;
1247 bool isConst() => (flags & FLAG_CONST) != 0; 1091 bool isConst() => (flags & FLAG_CONST) != 0;
1248 bool isFactory() => (flags & FLAG_FACTORY) != 0; 1092 bool isFactory() => (flags & FLAG_FACTORY) != 0;
1249 } 1093 }
1250 1094
1251 class StringInterpolation extends Expression { 1095 class StringInterpolation extends StringNode {
1252 final LiteralString string; 1096 final LiteralString string;
1253 final NodeList parts; 1097 final NodeList parts;
1254 1098
1255 StringInterpolation(this.string, this.parts); 1099 StringInterpolation(this.string, this.parts);
1256 1100
1257 StringInterpolation asStringInterpolation() => this; 1101 StringInterpolation asStringInterpolation() => this;
1258 1102
1103 DartString get dartString() => null;
1104 bool get isInterpolation() => true;
1105
1259 accept(Visitor visitor) => visitor.visitStringInterpolation(this); 1106 accept(Visitor visitor) => visitor.visitStringInterpolation(this);
1260 1107
1261 visitChildren(Visitor visitor) { 1108 visitChildren(Visitor visitor) {
1262 string.accept(visitor); 1109 string.accept(visitor);
1263 parts.accept(visitor); 1110 parts.accept(visitor);
1264 } 1111 }
1265 1112
1266 Token getBeginToken() => string.getBeginToken(); 1113 Token getBeginToken() => string.getBeginToken();
1267
1268 Token getEndToken() => parts.getEndToken(); 1114 Token getEndToken() => parts.getEndToken();
1269 } 1115 }
1270 1116
1271 class StringInterpolationPart extends Node { 1117 class StringInterpolationPart extends Node {
1272 final Expression expression; 1118 final Expression expression;
1273 final LiteralString string; 1119 final LiteralString string;
1274 1120
1275 StringInterpolationPart(this.expression, this.string); 1121 StringInterpolationPart(this.expression, this.string);
1276 1122
1277 StringInterpolationPart asStringInterpolationPart() => this; 1123 StringInterpolationPart asStringInterpolationPart() => this;
1278 1124
1279 accept(Visitor visitor) => visitor.visitStringInterpolationPart(this); 1125 accept(Visitor visitor) => visitor.visitStringInterpolationPart(this);
1280 1126
1281 visitChildren(Visitor visitor) { 1127 visitChildren(Visitor visitor) {
1282 expression.accept(visitor); 1128 expression.accept(visitor);
1283 string.accept(visitor); 1129 string.accept(visitor);
1284 } 1130 }
1285 1131
1286 Token getBeginToken() => expression.getBeginToken(); 1132 Token getBeginToken() => expression.getBeginToken();
1287 1133
1288 Token getEndToken() => string.getEndToken(); 1134 Token getEndToken() => string.getEndToken();
1289 } 1135 }
1290 1136
1291 class LiteralStringJuxtaposition extends LiteralString { 1137 /**
1292 // List of either StringLiteral or StringInterpolation. 1138 * A class representing juxtaposed string literals.
1293 final Link<Expression> literals; 1139 * The string literals can be both plain literals and string interpolations.
1140 */
1141 class StringJuxtaposition extends StringNode {
1142 final Expression first;
1143 final Expression second;
1144 /**
ahe 2012/03/19 15:53:06 Add newline before comment.
Lasse Reichstein Nielsen 2012/03/20 09:34:33 Done.
1145 * Caches the check for whether this juxtaposition contains a string
1146 * interpolation
1147 */
1148 bool isInterpolationCache = null;
1149 /**
ahe 2012/03/19 15:53:06 Ditto.
Lasse Reichstein Nielsen 2012/03/20 09:34:33 Done.
1150 * Caches a Dart string representation of the entire juxtaposition's
1151 * content. Only juxtapositions that don't (transitively) contains
1152 * interpolations have a static representation.
1153 */
1154 DartString dartStringCache = null;
1294 1155
1295 LiteralStringJuxtaposition(Link<Expression> literals) 1156 StringJuxtaposition(this.first, this.second);
1296 : this.literals = literals,
1297 super(literals.head.getBeginToken(), concatenateLiterals(literals));
1298 1157
1299 static DartString concatenateLiterals(Link<Expression> literals) { 1158 StringJuxtaposition asStringJuxtaposition() => this;
1300 assert(!literals.isEmpty()); 1159
1301 LiteralString literal = literals.head; 1160 bool get isInterpolation() {
1302 if (literals.tail.isEmpty()) { 1161 if (isInterpolationCache === null) {
1303 return literal.dartString; 1162 isInterpolationCache = (first.accept(const IsInterpolationVisitor()) ||
1163 second.accept(const IsInterpolationVisitor()));
1304 } 1164 }
1305 return new ConsDartString(literal.dartString, 1165 return isInterpolationCache;
1306 concatenateLiterals(literals.tail));
1307 } 1166 }
1308 1167
1309 SourceString get value() => null; 1168 /**
1310 1169 * Retrieve a single DartString that represents this entire juxtaposition
1311 accept(Visitor visitor) => visitor.visitLiteralStringJuxtaposition(this); 1170 * of string literals.
1312 1171 * Should only be called if [isInterpolation] returns false.
1313 visitChildren(Visitor visitor) { 1172 */
1314 for (Expression literal in literals) { 1173 DartString get dartString() {
1315 literal.accept(visitor); 1174 if (isInterpolation) {
1175 throw new NodeAssertionFailure(this,
1176 "Getting dartString on interpolation;")
1316 } 1177 }
1178 if (dartStringCache === null) {
1179 DartString firstString = first.accept(const GetDartStringVisitor());
1180 DartString secondString = second.accept(const GetDartStringVisitor());
1181 if (firstString === null || secondString === null) {
1182 return null;
1183 }
1184 dartStringCache = new DartString.concat(firstString, secondString);
1185 }
1186 return dartStringCache;
1317 } 1187 }
1318 1188
1319 Token getBeginToken() => literals.head.getBeginToken(); 1189 accept(Visitor visitor) => visitor.visitStringJuxtaposition(this);
1320 1190
1321 Token getEndToken() { 1191 void visitChildren(Visitor visitor) {
1322 Link<Expression> current = literals; 1192 first.accept(visitor);
1323 Expression lastExpression = null; 1193 second.accept(visitor);
1324 while (!current.isEmpty()) {
1325 lastExpression = current.head;
1326 current = current.tail;
1327 }
1328 return lastExpression.getEndToken();
1329 } 1194 }
1195
1196 Token getBeginToken() => first.getBeginToken();
1197
1198 Token getEndToken() => second.getEndToken();
1330 } 1199 }
1331 1200
1332 class EmptyStatement extends Statement { 1201 class EmptyStatement extends Statement {
1333 final Token semicolonToken; 1202 final Token semicolonToken;
1334 1203
1335 EmptyStatement(this.semicolonToken); 1204 EmptyStatement(this.semicolonToken);
1336 1205
1337 EmptyStatement asEmptyStatement() => this; 1206 EmptyStatement asEmptyStatement() => this;
1338 1207
1339 accept(Visitor visitor) => visitor.visitEmptyStatement(this); 1208 accept(Visitor visitor) => visitor.visitEmptyStatement(this);
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 1458
1590 Node getBody() { 1459 Node getBody() {
1591 if (statement is! LabeledStatement) return statement; 1460 if (statement is! LabeledStatement) return statement;
1592 LabeledStatement labeled = statement; 1461 LabeledStatement labeled = statement;
1593 return labeled.getBody(); 1462 return labeled.getBody();
1594 } 1463 }
1595 } 1464 }
1596 1465
1597 class ScriptTag extends Node { 1466 class ScriptTag extends Node {
1598 final Identifier tag; 1467 final Identifier tag;
1599 final LiteralString argument; 1468 final StringNode argument;
1600 final Identifier prefixIdentifier; 1469 final Identifier prefixIdentifier;
1601 final LiteralString prefix; 1470 final StringNode prefix;
1602 1471
1603 final Token beginToken; 1472 final Token beginToken;
1604 final Token endToken; 1473 final Token endToken;
1605 1474
1606 ScriptTag(this.tag, this.argument, this.prefixIdentifier, this.prefix, 1475 ScriptTag(this.tag, this.argument, this.prefixIdentifier, this.prefix,
1607 this.beginToken, this.endToken); 1476 this.beginToken, this.endToken);
1608 1477
1609 bool isImport() => tag.source == const SourceString("import"); 1478 bool isImport() => tag.source == const SourceString("import");
1610 bool isSource() => tag.source == const SourceString("source"); 1479 bool isSource() => tag.source == const SourceString("source");
1611 bool isLibrary() => tag.source == const SourceString("library"); 1480 bool isLibrary() => tag.source == const SourceString("library");
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 static bool isConstructorRedirect(Send node) { 1603 static bool isConstructorRedirect(Send node) {
1735 return (node.receiver === null && 1604 return (node.receiver === null &&
1736 node.selector.asIdentifier() !== null && 1605 node.selector.asIdentifier() !== null &&
1737 node.selector.asIdentifier().isThis()) || 1606 node.selector.asIdentifier().isThis()) ||
1738 (node.receiver !== null && 1607 (node.receiver !== null &&
1739 node.receiver.asIdentifier() !== null && 1608 node.receiver.asIdentifier() !== null &&
1740 node.receiver.asIdentifier().isThis() && 1609 node.receiver.asIdentifier().isThis() &&
1741 node.selector.asIdentifier() !== null); 1610 node.selector.asIdentifier() !== null);
1742 } 1611 }
1743 } 1612 }
1613
1614 class GetDartStringVisitor extends AbstractVisitor<DartString> {
1615 const GetDartStringVisitor();
1616 DartString visitNode(Node node) => null;
1617 DartString visitStringJuxtaposition(StringJuxtaposition node)
1618 => node.dartString;
1619 DartString visitLiteralString(LiteralString node) => node.dartString;
1620 }
1621
1622 class IsInterpolationVisitor extends AbstractVisitor<bool> {
1623 const IsInterpolationVisitor();
1624 bool visitNode(Node node) => false;
1625 bool visitStringInterpolation(StringInterpolation node) => true;
1626 bool visitStringJuxtaposition(StringJuxtaposition node)
1627 => node.isInterpolation;
1628 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698