OLD | NEW |
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 #include "platform/assert.h" | 5 #include "platform/assert.h" |
6 #include "vm/os.h" | 6 #include "vm/os.h" |
7 #include "vm/scanner.h" | 7 #include "vm/scanner.h" |
8 #include "vm/token.h" | 8 #include "vm/token.h" |
9 #include "vm/unit_test.h" | 9 #include "vm/unit_test.h" |
10 | 10 |
11 namespace dart { | 11 namespace dart { |
12 | 12 |
13 | 13 |
14 typedef ZoneGrowableArray<Scanner::TokenDescriptor> GrowableTokenStream; | 14 typedef ZoneGrowableArray<Scanner::TokenDescriptor> GrowableTokenStream; |
15 | 15 |
16 | 16 |
17 static void LogTokenDesc(Scanner::TokenDescriptor token) { | 17 static void LogTokenDesc(Scanner::TokenDescriptor token) { |
18 OS::Print("pos %2d:%d-%d token %s ", | 18 OS::Print("pos %2d:%d-%d token %s ", token.position.line, |
19 token.position.line, token.position.column, | 19 token.position.column, token.position.column, |
20 token.position.column, | |
21 Token::Name(token.kind)); | 20 Token::Name(token.kind)); |
22 if (token.literal != NULL) { | 21 if (token.literal != NULL) { |
23 OS::Print("%s", token.literal->ToCString()); | 22 OS::Print("%s", token.literal->ToCString()); |
24 } | 23 } |
25 OS::Print("\n"); | 24 OS::Print("\n"); |
26 } | 25 } |
27 | 26 |
28 | 27 |
29 static void LogTokenStream(const GrowableTokenStream& token_stream) { | 28 static void LogTokenStream(const GrowableTokenStream& token_stream) { |
30 int token_index = 0; | 29 int token_index = 0; |
31 EXPECT_GT(token_stream.length(), 0); | 30 EXPECT_GT(token_stream.length(), 0); |
32 while (token_index < token_stream.length()) { | 31 while (token_index < token_stream.length()) { |
33 LogTokenDesc(token_stream[token_index]); | 32 LogTokenDesc(token_stream[token_index]); |
34 ASSERT(token_stream[token_index].kind != Token::kILLEGAL); | 33 ASSERT(token_stream[token_index].kind != Token::kILLEGAL); |
35 token_index++; | 34 token_index++; |
36 } | 35 } |
37 printf("%d tokens in stream.\n", token_index); | 36 printf("%d tokens in stream.\n", token_index); |
38 EXPECT_EQ(token_stream.Last().kind, Token::kEOS); | 37 EXPECT_EQ(token_stream.Last().kind, Token::kEOS); |
39 } | 38 } |
40 | 39 |
41 | 40 |
42 static void CheckKind(const GrowableTokenStream &token_stream, | 41 static void CheckKind(const GrowableTokenStream& token_stream, |
43 int index, | 42 int index, |
44 Token::Kind kind) { | 43 Token::Kind kind) { |
45 if (token_stream[index].kind != kind) { | 44 if (token_stream[index].kind != kind) { |
46 OS::PrintErr("Token %d: expected kind %s but got %s\n", index, | 45 OS::PrintErr("Token %d: expected kind %s but got %s\n", index, |
47 Token::Name(kind), Token::Name(token_stream[index].kind)); | 46 Token::Name(kind), Token::Name(token_stream[index].kind)); |
48 } | 47 } |
49 EXPECT_EQ(kind, token_stream[index].kind); | 48 EXPECT_EQ(kind, token_stream[index].kind); |
50 } | 49 } |
51 | 50 |
52 | 51 |
53 static void CheckLiteral(const GrowableTokenStream& token_stream, | 52 static void CheckLiteral(const GrowableTokenStream& token_stream, |
54 int index, | 53 int index, |
55 const char* literal) { | 54 const char* literal) { |
56 if (token_stream[index].literal == NULL) { | 55 if (token_stream[index].literal == NULL) { |
57 OS::PrintErr("Token %d: expected literal \"%s\" but got nothing\n", | 56 OS::PrintErr("Token %d: expected literal \"%s\" but got nothing\n", index, |
58 index, literal); | 57 literal); |
59 } else if (strcmp(literal, token_stream[index].literal->ToCString())) { | 58 } else if (strcmp(literal, token_stream[index].literal->ToCString())) { |
60 OS::PrintErr("Token %d: expected literal \"%s\" but got \"%s\"\n", | 59 OS::PrintErr("Token %d: expected literal \"%s\" but got \"%s\"\n", index, |
61 index, literal, token_stream[index].literal->ToCString()); | 60 literal, token_stream[index].literal->ToCString()); |
62 } | 61 } |
63 } | 62 } |
64 | 63 |
65 | 64 |
66 static void CheckIdent(const GrowableTokenStream& token_stream, | 65 static void CheckIdent(const GrowableTokenStream& token_stream, |
67 int index, | 66 int index, |
68 const char* literal) { | 67 const char* literal) { |
69 CheckKind(token_stream, index, Token::kIDENT); | 68 CheckKind(token_stream, index, Token::kIDENT); |
70 CheckLiteral(token_stream, index, literal); | 69 CheckLiteral(token_stream, index, literal); |
71 } | 70 } |
72 | 71 |
73 | 72 |
74 static void CheckInteger(const GrowableTokenStream& token_stream, | 73 static void CheckInteger(const GrowableTokenStream& token_stream, |
75 int index, | 74 int index, |
76 const char* literal) { | 75 const char* literal) { |
77 CheckKind(token_stream, index, Token::kINTEGER); | 76 CheckKind(token_stream, index, Token::kINTEGER); |
78 CheckLiteral(token_stream, index, literal); | 77 CheckLiteral(token_stream, index, literal); |
79 } | 78 } |
80 | 79 |
81 | 80 |
82 static void CheckLineNumber(const GrowableTokenStream& token_stream, | 81 static void CheckLineNumber(const GrowableTokenStream& token_stream, |
83 int index, | 82 int index, |
84 int line_number) { | 83 int line_number) { |
85 if (token_stream[index].position.line != line_number) { | 84 if (token_stream[index].position.line != line_number) { |
86 OS::PrintErr("Token %d: expected line number %d but got %d\n", | 85 OS::PrintErr("Token %d: expected line number %d but got %d\n", index, |
87 index, line_number, token_stream[index].position.line); | 86 line_number, token_stream[index].position.line); |
88 } | 87 } |
89 } | 88 } |
90 | 89 |
91 | 90 |
92 static void CheckNumTokens(const GrowableTokenStream& token_stream, | 91 static void CheckNumTokens(const GrowableTokenStream& token_stream, int index) { |
93 int index) { | |
94 if (token_stream.length() != index) { | 92 if (token_stream.length() != index) { |
95 OS::PrintErr("Expected %d tokens but got only %" Pd ".\n", | 93 OS::PrintErr("Expected %d tokens but got only %" Pd ".\n", index, |
96 index, token_stream.length()); | 94 token_stream.length()); |
97 } | 95 } |
98 } | 96 } |
99 | 97 |
100 | 98 |
101 class Collector : public Scanner::TokenCollector { | 99 class Collector : public Scanner::TokenCollector { |
102 public: | 100 public: |
103 explicit Collector(GrowableTokenStream* ts) : ts_(ts) { } | 101 explicit Collector(GrowableTokenStream* ts) : ts_(ts) {} |
104 virtual ~Collector() { } | 102 virtual ~Collector() {} |
105 | 103 |
106 virtual void AddToken(const Scanner::TokenDescriptor& token) { | 104 virtual void AddToken(const Scanner::TokenDescriptor& token) { |
107 ts_->Add(token); | 105 ts_->Add(token); |
108 } | 106 } |
| 107 |
109 private: | 108 private: |
110 GrowableTokenStream* ts_; | 109 GrowableTokenStream* ts_; |
111 }; | 110 }; |
112 | 111 |
113 | 112 |
114 static const GrowableTokenStream& Scan(const char* source) { | 113 static const GrowableTokenStream& Scan(const char* source) { |
115 OS::Print("\nScanning: <%s>\n", source); | 114 OS::Print("\nScanning: <%s>\n", source); |
116 | 115 |
117 Scanner scanner(String::Handle(String::New(source)), | 116 Scanner scanner(String::Handle(String::New(source)), |
118 String::Handle(String::New(""))); | 117 String::Handle(String::New(""))); |
(...skipping 12 matching lines...) Expand all Loading... |
131 CheckNumTokens(tokens, 6); | 130 CheckNumTokens(tokens, 6); |
132 CheckIdent(tokens, 0, "x"); | 131 CheckIdent(tokens, 0, "x"); |
133 CheckKind(tokens, 1, Token::kASSIGN); | 132 CheckKind(tokens, 1, Token::kASSIGN); |
134 CheckIdent(tokens, 2, "iffy"); | 133 CheckIdent(tokens, 2, "iffy"); |
135 CheckKind(tokens, 3, Token::kINCR); | 134 CheckKind(tokens, 3, Token::kINCR); |
136 CheckKind(tokens, 4, Token::kSEMICOLON); | 135 CheckKind(tokens, 4, Token::kSEMICOLON); |
137 } | 136 } |
138 | 137 |
139 | 138 |
140 static void CommentTest() { | 139 static void CommentTest() { |
141 const GrowableTokenStream& tokens = | 140 const GrowableTokenStream& tokens = Scan( |
142 Scan("Foo( /*block \n" | 141 "Foo( /*block \n" |
143 "comment*/ 0xff) // line comment;"); | 142 "comment*/ 0xff) // line comment;"); |
144 | 143 |
145 CheckNumTokens(tokens, 6); | 144 CheckNumTokens(tokens, 6); |
146 CheckIdent(tokens, 0, "Foo"); | 145 CheckIdent(tokens, 0, "Foo"); |
147 CheckLineNumber(tokens, 0, 1); | 146 CheckLineNumber(tokens, 0, 1); |
148 CheckKind(tokens, 1, Token::kLPAREN); | 147 CheckKind(tokens, 1, Token::kLPAREN); |
149 CheckKind(tokens, 2, Token::kNEWLINE); | 148 CheckKind(tokens, 2, Token::kNEWLINE); |
150 CheckInteger(tokens, 3, "0xff"); | 149 CheckInteger(tokens, 3, "0xff"); |
151 CheckKind(tokens, 4, Token::kRPAREN); | 150 CheckKind(tokens, 4, Token::kRPAREN); |
152 CheckLineNumber(tokens, 4, 2); | 151 CheckLineNumber(tokens, 4, 2); |
153 } | 152 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 EXPECT_EQ(' ', litchars[1]); | 184 EXPECT_EQ(' ', litchars[1]); |
186 EXPECT_EQ('\\', litchars[2]); | 185 EXPECT_EQ('\\', litchars[2]); |
187 EXPECT_EQ('\n', litchars[4]); | 186 EXPECT_EQ('\n', litchars[4]); |
188 EXPECT_EQ('\r', litchars[5]); | 187 EXPECT_EQ('\r', litchars[5]); |
189 EXPECT_EQ('\t', litchars[6]); | 188 EXPECT_EQ('\t', litchars[6]); |
190 EXPECT_EQ('\'', litchars[8]); | 189 EXPECT_EQ('\'', litchars[8]); |
191 } | 190 } |
192 | 191 |
193 | 192 |
194 static void InvalidStringEscapes() { | 193 static void InvalidStringEscapes() { |
195 const GrowableTokenStream& out_of_range_low = | 194 const GrowableTokenStream& out_of_range_low = Scan("\"\\u{110000}\""); |
196 Scan("\"\\u{110000}\""); | |
197 EXPECT_EQ(2, out_of_range_low.length()); | 195 EXPECT_EQ(2, out_of_range_low.length()); |
198 CheckKind(out_of_range_low, 0, Token::kERROR); | 196 CheckKind(out_of_range_low, 0, Token::kERROR); |
199 EXPECT(out_of_range_low[0].literal->Equals("invalid code point")); | 197 EXPECT(out_of_range_low[0].literal->Equals("invalid code point")); |
200 CheckKind(out_of_range_low, 1, Token::kEOS); | 198 CheckKind(out_of_range_low, 1, Token::kEOS); |
201 | 199 |
202 const GrowableTokenStream& out_of_range_high = | 200 const GrowableTokenStream& out_of_range_high = Scan("\"\\u{FFFFFF}\""); |
203 Scan("\"\\u{FFFFFF}\""); | |
204 EXPECT_EQ(2, out_of_range_high.length()); | 201 EXPECT_EQ(2, out_of_range_high.length()); |
205 CheckKind(out_of_range_high, 0, Token::kERROR); | 202 CheckKind(out_of_range_high, 0, Token::kERROR); |
206 EXPECT(out_of_range_high[0].literal->Equals("invalid code point")); | 203 EXPECT(out_of_range_high[0].literal->Equals("invalid code point")); |
207 CheckKind(out_of_range_high, 1, Token::kEOS); | 204 CheckKind(out_of_range_high, 1, Token::kEOS); |
208 } | 205 } |
209 | 206 |
210 | 207 |
211 static void RawString() { | 208 static void RawString() { |
212 // rs = @"\' \\" | 209 // rs = @"\' \\" |
213 const GrowableTokenStream& tokens = Scan("rs = r\"\\\' \\\\\""); | 210 const GrowableTokenStream& tokens = Scan("rs = r\"\\\' \\\\\""); |
214 | 211 |
215 EXPECT_EQ(4, tokens.length()); | 212 EXPECT_EQ(4, tokens.length()); |
216 CheckIdent(tokens, 0, "rs"); | 213 CheckIdent(tokens, 0, "rs"); |
217 CheckKind(tokens, 1, Token::kASSIGN); | 214 CheckKind(tokens, 1, Token::kASSIGN); |
218 CheckKind(tokens, 2, Token::kSTRING); | 215 CheckKind(tokens, 2, Token::kSTRING); |
219 CheckKind(tokens, 3, Token::kEOS); | 216 CheckKind(tokens, 3, Token::kEOS); |
220 CheckLineNumber(tokens, 2, 1); | 217 CheckLineNumber(tokens, 2, 1); |
221 const char* litchars = (tokens)[2].literal->ToCString(); | 218 const char* litchars = (tokens)[2].literal->ToCString(); |
222 EXPECT_EQ(5, (tokens)[2].literal->Length()); | 219 EXPECT_EQ(5, (tokens)[2].literal->Length()); |
223 | 220 |
224 EXPECT_EQ('\\', litchars[0]); | 221 EXPECT_EQ('\\', litchars[0]); |
225 EXPECT_EQ('\'', litchars[1]); | 222 EXPECT_EQ('\'', litchars[1]); |
226 EXPECT_EQ(' ', litchars[2]); | 223 EXPECT_EQ(' ', litchars[2]); |
227 EXPECT_EQ('\\', litchars[3]); | 224 EXPECT_EQ('\\', litchars[3]); |
228 EXPECT_EQ('\\', litchars[4]); | 225 EXPECT_EQ('\\', litchars[4]); |
229 } | 226 } |
230 | 227 |
231 | 228 |
232 static void MultilineString() { | 229 static void MultilineString() { |
233 // |mls = ''' | 230 // |mls = ''' |
234 // |1' x | 231 // |1' x |
235 // |2'''; | 232 // |2'''; |
236 const GrowableTokenStream& tokens = Scan("mls = '''\n1' x\n2''';"); | 233 const GrowableTokenStream& tokens = Scan("mls = '''\n1' x\n2''';"); |
237 | 234 |
238 EXPECT_EQ(7, tokens.length()); | 235 EXPECT_EQ(7, tokens.length()); |
239 CheckIdent(tokens, 0, "mls"); | 236 CheckIdent(tokens, 0, "mls"); |
240 CheckKind(tokens, 1, Token::kASSIGN); | 237 CheckKind(tokens, 1, Token::kASSIGN); |
241 CheckKind(tokens, 2, Token::kSTRING); | 238 CheckKind(tokens, 2, Token::kSTRING); |
242 CheckKind(tokens, 3, Token::kNEWLINE); | 239 CheckKind(tokens, 3, Token::kNEWLINE); |
243 CheckKind(tokens, 4, Token::kNEWLINE); | 240 CheckKind(tokens, 4, Token::kNEWLINE); |
244 CheckKind(tokens, 5, Token::kSEMICOLON); | 241 CheckKind(tokens, 5, Token::kSEMICOLON); |
245 CheckKind(tokens, 6, Token::kEOS); | 242 CheckKind(tokens, 6, Token::kEOS); |
246 CheckLineNumber(tokens, 0, 1); | 243 CheckLineNumber(tokens, 0, 1); |
247 CheckLineNumber(tokens, 5, 3); // Semicolon is on line 3. | 244 CheckLineNumber(tokens, 5, 3); // Semicolon is on line 3. |
248 const char* litchars = (tokens)[2].literal->ToCString(); | 245 const char* litchars = (tokens)[2].literal->ToCString(); |
249 EXPECT_EQ(6, (tokens)[2].literal->Length()); | 246 EXPECT_EQ(6, (tokens)[2].literal->Length()); |
250 | 247 |
251 EXPECT_EQ('1', litchars[0]); // First newline is dropped. | 248 EXPECT_EQ('1', litchars[0]); // First newline is dropped. |
252 EXPECT_EQ('\'', litchars[1]); | 249 EXPECT_EQ('\'', litchars[1]); |
253 EXPECT_EQ(' ', litchars[2]); | 250 EXPECT_EQ(' ', litchars[2]); |
254 EXPECT_EQ('x', litchars[3]); | 251 EXPECT_EQ('x', litchars[3]); |
255 EXPECT_EQ('\n', litchars[4]); | 252 EXPECT_EQ('\n', litchars[4]); |
256 EXPECT_EQ('2', litchars[5]); | 253 EXPECT_EQ('2', litchars[5]); |
257 } | 254 } |
258 | 255 |
259 | 256 |
260 static void EmptyString() { | 257 static void EmptyString() { |
261 // es = ""; | 258 // es = ""; |
262 const GrowableTokenStream& tokens = Scan("es = \"\";"); | 259 const GrowableTokenStream& tokens = Scan("es = \"\";"); |
263 | 260 |
264 EXPECT_EQ(5, tokens.length()); | 261 EXPECT_EQ(5, tokens.length()); |
265 CheckIdent(tokens, 0, "es"); | 262 CheckIdent(tokens, 0, "es"); |
266 CheckKind(tokens, 1, Token::kASSIGN); | 263 CheckKind(tokens, 1, Token::kASSIGN); |
(...skipping 11 matching lines...) Expand all Loading... |
278 CheckIdent(tokens, 0, "es"); | 275 CheckIdent(tokens, 0, "es"); |
279 CheckKind(tokens, 1, Token::kASSIGN); | 276 CheckKind(tokens, 1, Token::kASSIGN); |
280 CheckKind(tokens, 2, Token::kSTRING); | 277 CheckKind(tokens, 2, Token::kSTRING); |
281 CheckKind(tokens, 3, Token::kSEMICOLON); | 278 CheckKind(tokens, 3, Token::kSEMICOLON); |
282 CheckKind(tokens, 4, Token::kEOS); | 279 CheckKind(tokens, 4, Token::kEOS); |
283 EXPECT_EQ(0, (tokens)[2].literal->Length()); | 280 EXPECT_EQ(0, (tokens)[2].literal->Length()); |
284 } | 281 } |
285 | 282 |
286 | 283 |
287 static void NumberLiteral() { | 284 static void NumberLiteral() { |
288 const GrowableTokenStream& tokens = | 285 const GrowableTokenStream& tokens = Scan("5 0x5d 0.3 0.33 1E+12 .42 +5"); |
289 Scan("5 0x5d 0.3 0.33 1E+12 .42 +5"); | |
290 | 286 |
291 CheckKind(tokens, 0, Token::kINTEGER); | 287 CheckKind(tokens, 0, Token::kINTEGER); |
292 CheckKind(tokens, 1, Token::kINTEGER); | 288 CheckKind(tokens, 1, Token::kINTEGER); |
293 CheckKind(tokens, 2, Token::kDOUBLE); | 289 CheckKind(tokens, 2, Token::kDOUBLE); |
294 CheckKind(tokens, 3, Token::kDOUBLE); | 290 CheckKind(tokens, 3, Token::kDOUBLE); |
295 CheckKind(tokens, 4, Token::kDOUBLE); | 291 CheckKind(tokens, 4, Token::kDOUBLE); |
296 CheckKind(tokens, 5, Token::kDOUBLE); | 292 CheckKind(tokens, 5, Token::kDOUBLE); |
297 CheckKind(tokens, 6, Token::kADD); | 293 CheckKind(tokens, 6, Token::kADD); |
298 CheckKind(tokens, 7, Token::kINTEGER); | 294 CheckKind(tokens, 7, Token::kINTEGER); |
299 CheckKind(tokens, 8, Token::kEOS); | 295 CheckKind(tokens, 8, Token::kEOS); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 " }" | 354 " }" |
359 "}" | 355 "}" |
360 "" | 356 "" |
361 "" | 357 "" |
362 "j!==!iffy // means j !== !iffy"; | 358 "j!==!iffy // means j !== !iffy"; |
363 Scan(dart_source); | 359 Scan(dart_source); |
364 } | 360 } |
365 | 361 |
366 | 362 |
367 void InvalidText() { | 363 void InvalidText() { |
368 const GrowableTokenStream& tokens = | 364 const GrowableTokenStream& tokens = Scan("\\"); |
369 Scan("\\"); | |
370 | 365 |
371 EXPECT_EQ(2, tokens.length()); | 366 EXPECT_EQ(2, tokens.length()); |
372 CheckKind(tokens, 0, Token::kERROR); | 367 CheckKind(tokens, 0, Token::kERROR); |
373 CheckKind(tokens, 1, Token::kEOS); | 368 CheckKind(tokens, 1, Token::kEOS); |
374 } | 369 } |
375 | 370 |
376 | 371 |
377 void NewlinesTest() { | 372 void NewlinesTest() { |
378 const char* source = | 373 const char* source = |
379 "var es = /* a\n" | 374 "var es = /* a\n" |
(...skipping 13 matching lines...) Expand all Loading... |
393 CheckKind(tokens, 4, Token::kNEWLINE); | 388 CheckKind(tokens, 4, Token::kNEWLINE); |
394 CheckKind(tokens, 5, Token::kSTRING); | 389 CheckKind(tokens, 5, Token::kSTRING); |
395 CheckKind(tokens, 6, Token::kNEWLINE); | 390 CheckKind(tokens, 6, Token::kNEWLINE); |
396 CheckKind(tokens, 7, Token::kNEWLINE); | 391 CheckKind(tokens, 7, Token::kNEWLINE); |
397 CheckKind(tokens, 8, Token::kNEWLINE); | 392 CheckKind(tokens, 8, Token::kNEWLINE); |
398 CheckKind(tokens, 9, Token::kSEMICOLON); | 393 CheckKind(tokens, 9, Token::kSEMICOLON); |
399 CheckKind(tokens, 10, Token::kEOS); | 394 CheckKind(tokens, 10, Token::kEOS); |
400 | 395 |
401 EXPECT_EQ(4, (tokens)[5].literal->Length()); | 396 EXPECT_EQ(4, (tokens)[5].literal->Length()); |
402 const char* litchars = (tokens)[5].literal->ToCString(); | 397 const char* litchars = (tokens)[5].literal->ToCString(); |
403 EXPECT_EQ('c', litchars[0]); // First newline is dropped. | 398 EXPECT_EQ('c', litchars[0]); // First newline is dropped. |
404 EXPECT_EQ('\n', litchars[1]); | 399 EXPECT_EQ('\n', litchars[1]); |
405 EXPECT_EQ('d', litchars[2]); | 400 EXPECT_EQ('d', litchars[2]); |
406 EXPECT_EQ('\n', litchars[3]); | 401 EXPECT_EQ('\n', litchars[3]); |
407 } | 402 } |
408 | 403 |
409 | 404 |
410 TEST_CASE(Scanner_Test) { | 405 TEST_CASE(Scanner_Test) { |
411 ScanLargeText(); | 406 ScanLargeText(); |
412 | 407 |
413 BoringTest(); | 408 BoringTest(); |
414 CommentTest(); | 409 CommentTest(); |
415 GreedIsGood(); | 410 GreedIsGood(); |
416 StringEscapes(); | 411 StringEscapes(); |
417 InvalidStringEscapes(); | 412 InvalidStringEscapes(); |
418 RawString(); | 413 RawString(); |
419 MultilineString(); | 414 MultilineString(); |
420 EmptyString(); | 415 EmptyString(); |
421 EmptyMultilineString(); | 416 EmptyMultilineString(); |
422 NumberLiteral(); | 417 NumberLiteral(); |
423 InvalidText(); | 418 InvalidText(); |
424 NewlinesTest(); | 419 NewlinesTest(); |
425 } | 420 } |
426 | 421 |
427 } // namespace dart | 422 } // namespace dart |
OLD | NEW |