| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 class ParserTest { | |
| 6 static final String TAIL = '//comment\n\n'; | |
| 7 | |
| 8 static main() { | |
| 9 print('start ParserTest'); | |
| 10 initializeWorld(new FileSystem('.')); | |
| 11 testStatements(); | |
| 12 testLambdas(); | |
| 13 testExpressionsAsStatements(); | |
| 14 testDeclarationStatements(); | |
| 15 testTypeAmbiguities(); | |
| 16 | |
| 17 testDeclarations(); | |
| 18 | |
| 19 testLiterals(); | |
| 20 print('finished ParserTest'); | |
| 21 } | |
| 22 | |
| 23 static testStatements() { | |
| 24 testStatement('a - b - c - d;'); | |
| 25 | |
| 26 testStatement('if (true) return 1*2+3*4; else return 2;'); | |
| 27 testStatement('return 42 ? true : false;'); | |
| 28 testStatement('return true += 2+6*3;'); | |
| 29 | |
| 30 testStatement('int x;'); | |
| 31 testStatement('x.m y = 42, z;'); | |
| 32 testStatement('{ int x; return 22; }'); | |
| 33 testStatement('int f() { return 22; }'); | |
| 34 | |
| 35 testStatement('int f(int y) { return 22 + 3; }'); | |
| 36 testStatement('int f(int y, int x) { return 22 + x; }'); | |
| 37 | |
| 38 testStatement('int f(y, x) { return 22 + x; }'); | |
| 39 testStatement('foo() => 42;'); | |
| 40 | |
| 41 testStatement('throw;'); | |
| 42 testStatement('throw x(10);'); | |
| 43 | |
| 44 testStatement('break;'); | |
| 45 testStatement('continue;'); | |
| 46 testStatement('assert(true);'); | |
| 47 testStatement('assert(x < 10);'); | |
| 48 testStatement('break foo;'); | |
| 49 testStatement('continue bar;'); | |
| 50 | |
| 51 testStatement('var z=22, a=new C(1,2);'); | |
| 52 | |
| 53 testStatement('for (Map<String, Object> suite in stats) {}'); | |
| 54 } | |
| 55 | |
| 56 static testLambdas() { | |
| 57 testStatement('x = function() {};'); | |
| 58 testStatement('x = function() => 42;'); | |
| 59 testStatement('x = void f() {};'); | |
| 60 testStatement('x = func() => 42;'); | |
| 61 testStatement('x = void f(int x, int y) {};'); | |
| 62 testStatement('x = func(x) => 42;'); | |
| 63 testStatement('x = func(x,y,z) => 42;'); | |
| 64 | |
| 65 testStatement('x = func(x);'); | |
| 66 testStatement('x = func(x,y,z);'); | |
| 67 testStatement('x = func(42);'); | |
| 68 testStatement('x = func(x,y,42);'); | |
| 69 | |
| 70 | |
| 71 testStatement('f(x = function() {});'); | |
| 72 testStatement('f(x = function() => 42);'); | |
| 73 testStatement('f(x = void f() {});'); | |
| 74 testStatement('f(x = func() => 42);'); | |
| 75 | |
| 76 testStatement('f(foo() {});'); | |
| 77 | |
| 78 testStatement('f(void func(KV<K,V> e) {});'); | |
| 79 } | |
| 80 | |
| 81 static testExpressionsAsStatements() { | |
| 82 testStatement('x + 1;'); | |
| 83 | |
| 84 testStatement('(2+3);'); | |
| 85 testStatement('x.m(10);'); | |
| 86 testStatement('x(10);'); | |
| 87 | |
| 88 // TODO(jimhug): This is illegal - add as negative test... | |
| 89 //testStatement('var c = z=22, a=new C(1,2);'); | |
| 90 | |
| 91 testStatement('-a++;'); // TODO(jimhug): Ensure this parses as -(a++). | |
| 92 | |
| 93 testStatement('[(2+3), x(10), ++x, x++, --y, y--, x[42]];'); | |
| 94 testStatement('var m = {"a":42, "b":f(76),};'); | |
| 95 testStatement('var m = {};'); | |
| 96 testStatement('var m = {"a":"bye"};'); | |
| 97 testStatement('var m = {"a":42, "b":f(76)};'); | |
| 98 testStatement('var c = const [1,2];'); | |
| 99 testStatement('var c = const {"1":2};'); | |
| 100 | |
| 101 testStatement('final m = const <int>[1,2,3];'); | |
| 102 testStatement('final m = const <String, int>{"a":1,"b":2,"c":3};'); | |
| 103 | |
| 104 testStatement('if (a is double) {}'); | |
| 105 testStatement('if ((a is double) && b(10)) {}'); | |
| 106 | |
| 107 testStatement('try { foo(); } catch (e) {} catch (e, t) {} finally {}'); | |
| 108 testStatement('try { foo(); } catch (Ex1 e) {} catch (Ex2 e, St t) {}'); | |
| 109 | |
| 110 testStatement('for (i in set) {}'); | |
| 111 testStatement('for (final i in set) {}'); | |
| 112 testStatement('for (var i in set) {}'); | |
| 113 testStatement('for (final int i in set) {}'); | |
| 114 | |
| 115 testStatement('''switch (e) { | |
| 116 case 1: | |
| 117 foo(); | |
| 118 break; | |
| 119 case 2: case 3: | |
| 120 bar(); return 10; | |
| 121 default: return null; | |
| 122 }'''); | |
| 123 | |
| 124 // operator fun | |
| 125 testStatement('var o = x >> 2;'); | |
| 126 testStatement('var o = x >>> 2;'); | |
| 127 | |
| 128 testStatement('x >>= 2;'); | |
| 129 testStatement('x >>>= 2;'); | |
| 130 // TODO - need negatives! | |
| 131 | |
| 132 testStatement('var kv = new KeyValuePair<K, V>(key, value);'); | |
| 133 | |
| 134 testStatement('array.sort((a, b) => a < b);'); | |
| 135 | |
| 136 testStatement(';'); | |
| 137 testStatement('{;;;;;;;;;}'); | |
| 138 | |
| 139 testStatement('print("hello");'); | |
| 140 testStatement('print("hello \$foo");'); | |
| 141 testStatement('print("\${2 + x} = \${y(\'bar\')}");'); | |
| 142 } | |
| 143 | |
| 144 static testDeclarationStatements() { | |
| 145 testStatement('int m() {}'); | |
| 146 testStatement('m() {}'); | |
| 147 testStatement('m(x) {}'); | |
| 148 | |
| 149 testStatement('m(A<B> o) {}'); | |
| 150 | |
| 151 testStatement('m(A<B<C>> z) {}'); | |
| 152 | |
| 153 testStatement('A.B<C> m(int x, y, double z) {}'); | |
| 154 testStatement('A.B<C> m(int x, y, A<B<C>> z) {}'); | |
| 155 | |
| 156 testStatement('int x;'); | |
| 157 testStatement('A.B<C> x = 2+5;'); | |
| 158 testStatement('A.B<C> x = 2+5, y, z=42;'); | |
| 159 | |
| 160 testStatement('void f(e) { }'); | |
| 161 | |
| 162 testStatement('Promise<int> a = new Promise<int>();'); | |
| 163 testStatement('Promise<Promise<int>> b = new Promise<Promise<int>>();'); | |
| 164 testStatement('P<P<P<int>>> c = new P<P<P<int>>>();'); | |
| 165 testStatement('P<P<P<P<int>>>> c = new P<P<P<P<int>>>>();'); | |
| 166 } | |
| 167 | |
| 168 | |
| 169 static testDeclarations() { | |
| 170 testDeclaration('int m();'); | |
| 171 testDeclaration('m();'); | |
| 172 testDeclaration('m(x) {}'); | |
| 173 testDeclaration('A.B<C> m(int x, y, double z);'); | |
| 174 | |
| 175 | |
| 176 testDeclaration('A.B<C> m(int x, y, A<B<C>> z);'); | |
| 177 | |
| 178 testDeclaration('int x;'); | |
| 179 testDeclaration('A.B<C> x = 2+5;'); | |
| 180 testDeclaration('A.B<C> x = 2+5, y, z=42;'); | |
| 181 | |
| 182 testDeclaration('operator +(other) {}'); | |
| 183 testDeclaration('operator [](index) {}'); | |
| 184 testDeclaration('operator []=(index, value) {}'); | |
| 185 | |
| 186 testDeclaration('foo() => 42;'); | |
| 187 | |
| 188 testDeclaration('''class C extends D implements I { | |
| 189 void m() { return 43; } | |
| 190 int x; | |
| 191 }'''); | |
| 192 | |
| 193 testDeclaration('interface I { operator +(y) { return y + 10; }}'); | |
| 194 testDeclaration('interface I { int operator +(y) { return y + 10; }}'); | |
| 195 | |
| 196 testDeclaration('HashMap<K, DLLE<KeyValuePair<K, V>>> m_;'); | |
| 197 | |
| 198 // pseudo keywords? | |
| 199 testDeclaration('foo(A source) {}'); | |
| 200 testDeclaration('foo(A get, B assert, C static, D extends) {}'); | |
| 201 | |
| 202 testDeclaration('C(): b=x+y {}'); | |
| 203 | |
| 204 testDeclaration('C(): z=22, a=new C(1,2) {}'); | |
| 205 testDeclaration('C(b): _b = b == null ? 10 : 20 {}'); | |
| 206 | |
| 207 testDeclaration('C(this.x, this.y) {}'); | |
| 208 | |
| 209 testDeclaration('C(this.x, this.y): z=22, a=new C(1,2), b=x+y {}'); | |
| 210 | |
| 211 testDeclaration('void f(e) { }'); | |
| 212 } | |
| 213 | |
| 214 static testTypeAmbiguities() { | |
| 215 testMaybeType('A.B.C', false, false); | |
| 216 testMaybeType('A.B.C<10', false, true); | |
| 217 testMaybeType('A.B.C<D', false, true); | |
| 218 testMaybeType('A.B.C<D>', true, false); | |
| 219 testMaybeType('A.B.C<D,E>', true, false); | |
| 220 testMaybeType('A.B.C<D,E,F>', true, false); | |
| 221 testMaybeType('A.B.C<D,E,F,G>', true, false); | |
| 222 | |
| 223 testMaybeType('A<B1,B2<C>,D>', true, false); | |
| 224 | |
| 225 testMaybeType('A<B<C>,D>', true, false); | |
| 226 testMaybeType('A<B1,B2<C>,D>', true, false); | |
| 227 testMaybeType('A<B<C>>', true, false); | |
| 228 testMaybeType('A<B<C<D>>>', true, false); | |
| 229 | |
| 230 testMaybeType('KeyValuePair<K, V>', true, false); | |
| 231 testMaybeType('QueueEntry<KeyValuePair<K, V> >', true, false); | |
| 232 testMaybeType('QueueEntry<KeyValuePair<K, V>>', true, false); | |
| 233 testMaybeType('HashMap<K, QueueEntry<KeyValuePair<K, V> > >', | |
| 234 true, false); | |
| 235 testMaybeType('HashMap<K, QueueEntry<KeyValuePair<K, V>>>', | |
| 236 true, false); | |
| 237 } | |
| 238 | |
| 239 | |
| 240 static testLiterals() { | |
| 241 testLiteral('2', 2); | |
| 242 testLiteral('10e100', 10e100); | |
| 243 testLiteral('3.14159265', 3.14159265); | |
| 244 testLiteral('0x0', 0); | |
| 245 testLiteral('0xa8', 168); | |
| 246 testLiteral('0xfF', 255); | |
| 247 testLiteral('0XfF', 255); | |
| 248 | |
| 249 testLiteral('0xabcdef', 11259375); | |
| 250 testLiteral('0xABCDEF', 11259375); | |
| 251 // TODO(jimhug): This is too big for JS int | |
| 252 //testLiteral('0x123456789', 4886718345); | |
| 253 testLiteral('0x12345678', 305419896); | |
| 254 } | |
| 255 | |
| 256 static Parser makeParser(String filename, String code) { | |
| 257 return new Parser(new SourceFile(filename, code)); | |
| 258 } | |
| 259 | |
| 260 static void assertEqual(a, b) { | |
| 261 Expect.equals(a, b); | |
| 262 } | |
| 263 | |
| 264 static void validateNode(Node node, String filename, String code) { | |
| 265 // first, confirm sourcespan exists and is "correct" | |
| 266 var span = node.span; | |
| 267 assertEqual(span.file.filename, filename); | |
| 268 assertEqual(span.start, 0); | |
| 269 assertEqual(span.end, code.length); | |
| 270 | |
| 271 // TODO(jimhug): Walk and validate children spans and contents. | |
| 272 } | |
| 273 | |
| 274 static void testLiteral(String expr, var expected) { | |
| 275 print('>>>${expr}<<<'); | |
| 276 var filename = 'expr.dart'; | |
| 277 final parser = makeParser(filename, expr + TAIL); | |
| 278 var node = parser.expression(); | |
| 279 validateNode(node, filename, expr); | |
| 280 parser.checkEndOfFile(); | |
| 281 | |
| 282 assertEqual(expected, node.value); | |
| 283 } | |
| 284 | |
| 285 static void testDeclaration(String code, [String filename='test.dart']) { | |
| 286 print('>>>${code}<<<'); | |
| 287 final parser = makeParser(filename, code + TAIL); | |
| 288 var decl = parser.topLevelDefinition(); | |
| 289 validateNode(decl, filename, code); | |
| 290 parser.checkEndOfFile(); | |
| 291 } | |
| 292 | |
| 293 static void testStatement(String code, [String filename='test.dart']) { | |
| 294 print('>>>${code}<<<'); | |
| 295 final parser = makeParser(filename, code + TAIL); | |
| 296 var node = parser.statement(); | |
| 297 validateNode(node, filename, code); | |
| 298 parser.checkEndOfFile(); | |
| 299 } | |
| 300 | |
| 301 static void testMaybeType(String code, bool mustBeType, | |
| 302 bool mustBeExpression) { | |
| 303 if (!mustBeType) { | |
| 304 testStatement('x + ' + code + ';'); | |
| 305 } | |
| 306 if (!mustBeExpression) { | |
| 307 testStatement(code + ' x;'); | |
| 308 testDeclaration(code + ' x;'); | |
| 309 } | |
| 310 // TODO(jimhug): add negative test cases. | |
| 311 } | |
| 312 } | |
| OLD | NEW |