| 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 #import("../../../../lib/compiler/implementation/leg.dart"); | |
| 6 #import("../../../../lib/compiler/implementation/elements/elements.dart"); | |
| 7 #import("../../../../lib/compiler/implementation/tree/tree.dart"); | |
| 8 #import('../../../../lib/compiler/implementation/scanner/scannerlib.dart'); | |
| 9 #import("../../../../lib/compiler/implementation/util/util.dart"); | |
| 10 #import("mock_compiler.dart"); | |
| 11 #import("parser_helper.dart"); | |
| 12 | |
| 13 Type intType; | |
| 14 Type boolType; | |
| 15 Type stringType; | |
| 16 Type doubleType; | |
| 17 Type objectType; | |
| 18 | |
| 19 main() { | |
| 20 List tests = [testSimpleTypes, | |
| 21 testReturn, | |
| 22 testFor, | |
| 23 testWhile, | |
| 24 testOperators, | |
| 25 testConstructorInvocationArgumentCount, | |
| 26 testConstructorInvocationArgumentTypes, | |
| 27 testMethodInvocationArgumentCount, | |
| 28 testMethodInvocations, | |
| 29 testControlFlow, | |
| 30 // testNewExpression, | |
| 31 testConditionalExpression, | |
| 32 testIfStatement, | |
| 33 testThis, | |
| 34 testFunctionSubtyping]; | |
| 35 for (Function test in tests) { | |
| 36 setup(); | |
| 37 test(); | |
| 38 } | |
| 39 } | |
| 40 | |
| 41 testSimpleTypes() { | |
| 42 Expect.equals(intType, analyzeType("3")); | |
| 43 Expect.equals(boolType, analyzeType("false")); | |
| 44 Expect.equals(boolType, analyzeType("true")); | |
| 45 Expect.equals(stringType, analyzeType("'hestfisk'")); | |
| 46 } | |
| 47 | |
| 48 testReturn() { | |
| 49 analyzeTopLevel("void foo() { return 3; }", MessageKind.RETURN_VALUE_IN_VOID); | |
| 50 analyzeTopLevel("int bar() { return 'hest'; }", MessageKind.NOT_ASSIGNABLE); | |
| 51 analyzeTopLevel("void baz() { var x; return x; }"); | |
| 52 analyzeTopLevel(returnWithType("int", "'string'"), | |
| 53 MessageKind.NOT_ASSIGNABLE); | |
| 54 analyzeTopLevel(returnWithType("", "'string'")); | |
| 55 analyzeTopLevel(returnWithType("Object", "'string'")); | |
| 56 analyzeTopLevel(returnWithType("String", "'string'")); | |
| 57 analyzeTopLevel(returnWithType("String", null)); | |
| 58 analyzeTopLevel(returnWithType("int", null)); | |
| 59 analyzeTopLevel(returnWithType("void", "")); | |
| 60 analyzeTopLevel(returnWithType("void", 1), MessageKind.RETURN_VALUE_IN_VOID); | |
| 61 analyzeTopLevel(returnWithType("void", null)); | |
| 62 analyzeTopLevel(returnWithType("String", ""), MessageKind.RETURN_NOTHING); | |
| 63 // analyzeTopLevel("String foo() {};"); // Should probably fail. | |
| 64 } | |
| 65 | |
| 66 testFor() { | |
| 67 analyze("for (var x;true;x = x + 1) {}"); | |
| 68 analyze("for (var x;null;x = x + 1) {}"); | |
| 69 analyze("for (var x;0;x = x + 1) {}", MessageKind.NOT_ASSIGNABLE); | |
| 70 analyze("for (var x;'';x = x + 1) {}", MessageKind.NOT_ASSIGNABLE); | |
| 71 | |
| 72 analyze("for (;true;) {}"); | |
| 73 analyze("for (;null;) {}"); | |
| 74 analyze("for (;0;) {}", MessageKind.NOT_ASSIGNABLE); | |
| 75 analyze("for (;'';) {}", MessageKind.NOT_ASSIGNABLE); | |
| 76 | |
| 77 // Foreach tests | |
| 78 // TODO(karlklose): for each is not yet implemented. | |
| 79 // analyze("{ List<String> strings = ['1','2','3']; " + | |
| 80 // "for (String s in strings) {} }"); | |
| 81 // analyze("{ List<int> ints = [1,2,3]; for (String s in ints) {} }", | |
| 82 // MessageKind.NOT_ASSIGNABLE); | |
| 83 // analyze("for (String s in true) {}", MessageKind.METHOD_NOT_FOUND); | |
| 84 } | |
| 85 | |
| 86 testWhile() { | |
| 87 analyze("while (true) {}"); | |
| 88 analyze("while (null) {}"); | |
| 89 analyze("while (0) {}", MessageKind.NOT_ASSIGNABLE); | |
| 90 analyze("while ('') {}", MessageKind.NOT_ASSIGNABLE); | |
| 91 | |
| 92 analyze("do {} while (true);"); | |
| 93 analyze("do {} while (null);"); | |
| 94 analyze("do {} while (0);", MessageKind.NOT_ASSIGNABLE); | |
| 95 analyze("do {} while ('');", MessageKind.NOT_ASSIGNABLE); | |
| 96 analyze("do { int i = 0.5; } while (true);", MessageKind.NOT_ASSIGNABLE); | |
| 97 analyze("do { int i = 0.5; } while (null);", MessageKind.NOT_ASSIGNABLE); | |
| 98 } | |
| 99 | |
| 100 testOperators() { | |
| 101 // TODO(karlklose): add the DartC tests for operators when we can parse | |
| 102 // classes with operators. | |
| 103 for (final op in ['+', '-', '*', '/', '%', '~/', '|', '&']) { | |
| 104 analyze("{ var i = 1 ${op} 2; }"); | |
| 105 analyze("{ var i = 1; i ${op}= 2; }"); | |
| 106 analyze("{ int i; var j = (i = true) ${op} 2; }", | |
| 107 MessageKind.NOT_ASSIGNABLE); | |
| 108 analyze("{ int i; var j = 1 ${op} (i = true); }", | |
| 109 MessageKind.NOT_ASSIGNABLE); | |
| 110 } | |
| 111 for (final op in ['-', '~']) { | |
| 112 analyze("{ var i = ${op}1; }"); | |
| 113 analyze("{ int i; var j = ${op}(i = true); }", MessageKind.NOT_ASSIGNABLE); | |
| 114 } | |
| 115 for (final op in ['++', '--']) { | |
| 116 analyze("{ int i = 1; int j = i${op}; }"); | |
| 117 analyze("{ int i = 1; bool j = i${op}; }", MessageKind.NOT_ASSIGNABLE); | |
| 118 analyze("{ bool b = true; bool j = b${op}; }"); | |
| 119 analyze("{ bool b = true; int j = ${op}b; }"); | |
| 120 } | |
| 121 for (final op in ['||', '&&']) { | |
| 122 analyze("{ bool b = (true ${op} false); }"); | |
| 123 analyze("{ int b = true ${op} false; }", MessageKind.NOT_ASSIGNABLE); | |
| 124 analyze("{ bool b = (1 ${op} false); }", MessageKind.NOT_ASSIGNABLE); | |
| 125 analyze("{ bool b = (true ${op} 2); }", MessageKind.NOT_ASSIGNABLE); | |
| 126 } | |
| 127 for (final op in ['>', '<', '<=', '>=', '==', '!=', '===', '!==']) { | |
| 128 analyze("{ bool b = 1 ${op} 2; }"); | |
| 129 analyze("{ int i = 1 ${op} 2; }", MessageKind.NOT_ASSIGNABLE); | |
| 130 analyze("{ int i; bool b = (i = true) ${op} 2; }", | |
| 131 MessageKind.NOT_ASSIGNABLE); | |
| 132 analyze("{ int i; bool b = 1 ${op} (i = true); }", | |
| 133 MessageKind.NOT_ASSIGNABLE); | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 void testConstructorInvocationArgumentCount() { | |
| 138 compiler.parseScript(""" | |
| 139 class C1 { C1(x, y); } | |
| 140 class C2 { C2(int x, int y); } | |
| 141 """); | |
| 142 // calls to untyped constructor C1 | |
| 143 analyze("new C1(1, 2);"); | |
| 144 analyze("new C1();", MessageKind.MISSING_ARGUMENT); | |
| 145 analyze("new C1(1);", MessageKind.MISSING_ARGUMENT); | |
| 146 analyze("new C1(1, 2, 3);", MessageKind.ADDITIONAL_ARGUMENT); | |
| 147 // calls to typed constructor C2 | |
| 148 analyze("new C2(1, 2);"); | |
| 149 analyze("new C2();", MessageKind.MISSING_ARGUMENT); | |
| 150 analyze("new C2(1);", MessageKind.MISSING_ARGUMENT); | |
| 151 analyze("new C2(1, 2, 3);", MessageKind.ADDITIONAL_ARGUMENT); | |
| 152 } | |
| 153 | |
| 154 void testConstructorInvocationArgumentTypes() { | |
| 155 compiler.parseScript(""" | |
| 156 class C1 { C1(x); } | |
| 157 class C2 { C2(int x); } | |
| 158 """); | |
| 159 analyze("new C1(42);"); | |
| 160 analyze("new C1('string');"); | |
| 161 analyze("new C2(42);"); | |
| 162 analyze("new C2('string');", | |
| 163 MessageKind.NOT_ASSIGNABLE); | |
| 164 } | |
| 165 | |
| 166 void testMethodInvocationArgumentCount() { | |
| 167 compiler.parseScript(CLASS_WITH_METHODS); | |
| 168 final String header = "{ ClassWithMethods c; "; | |
| 169 analyze("${header}c.untypedNoArgumentMethod(1); }", | |
| 170 MessageKind.ADDITIONAL_ARGUMENT); | |
| 171 analyze("${header}c.untypedOneArgumentMethod(); }", | |
| 172 MessageKind.MISSING_ARGUMENT); | |
| 173 analyze("${header}c.untypedOneArgumentMethod(1, 1); }", | |
| 174 MessageKind.ADDITIONAL_ARGUMENT); | |
| 175 analyze("${header}c.untypedTwoArgumentMethod(); }", | |
| 176 MessageKind.MISSING_ARGUMENT); | |
| 177 analyze("${header}c.untypedTwoArgumentMethod(1, 2, 3); }", | |
| 178 MessageKind.ADDITIONAL_ARGUMENT); | |
| 179 analyze("${header}c.intNoArgumentMethod(1); }", | |
| 180 MessageKind.ADDITIONAL_ARGUMENT); | |
| 181 analyze("${header}c.intOneArgumentMethod(); }", | |
| 182 MessageKind.MISSING_ARGUMENT); | |
| 183 analyze("${header}c.intOneArgumentMethod(1, 1); }", | |
| 184 MessageKind.ADDITIONAL_ARGUMENT); | |
| 185 analyze("${header}c.intTwoArgumentMethod(); }", | |
| 186 MessageKind.MISSING_ARGUMENT); | |
| 187 analyze("${header}c.intTwoArgumentMethod(1, 2, 3); }", | |
| 188 MessageKind.ADDITIONAL_ARGUMENT); | |
| 189 // analyze("${header}c.untypedField(); }"); | |
| 190 } | |
| 191 | |
| 192 void testMethodInvocations() { | |
| 193 compiler.parseScript(CLASS_WITH_METHODS); | |
| 194 final String header = "{ ClassWithMethods c; SubClass d; int i; int j; "; | |
| 195 | |
| 196 analyze("${header}int k = c.untypedNoArgumentMethod(); }"); | |
| 197 analyze("${header}ClassWithMethods x = c.untypedNoArgumentMethod(); }"); | |
| 198 analyze("${header}ClassWithMethods x = d.untypedNoArgumentMethod(); }"); | |
| 199 analyze("${header}int k = d.intMethod(); }"); | |
| 200 analyze("${header}int k = c.untypedOneArgumentMethod(c); }"); | |
| 201 analyze("${header}ClassWithMethods x = c.untypedOneArgumentMethod(1); }"); | |
| 202 analyze("${header}int k = c.untypedOneArgumentMethod('string'); }"); | |
| 203 analyze("${header}int k = c.untypedOneArgumentMethod(i); }"); | |
| 204 analyze("${header}int k = d.untypedOneArgumentMethod(d); }"); | |
| 205 analyze("${header}ClassWithMethods x = d.untypedOneArgumentMethod(1); }"); | |
| 206 analyze("${header}int k = d.untypedOneArgumentMethod('string'); }"); | |
| 207 analyze("${header}int k = d.untypedOneArgumentMethod(i); }"); | |
| 208 | |
| 209 analyze("${header}int k = c.untypedTwoArgumentMethod(1, 'string'); }"); | |
| 210 analyze("${header}int k = c.untypedTwoArgumentMethod(i, j); }"); | |
| 211 analyze("${header}ClassWithMethods x = c.untypedTwoArgumentMethod(i, c); }"); | |
| 212 analyze("${header}int k = d.untypedTwoArgumentMethod(1, 'string'); }"); | |
| 213 analyze("${header}int k = d.untypedTwoArgumentMethod(i, j); }"); | |
| 214 analyze("${header}ClassWithMethods x = d.untypedTwoArgumentMethod(i, d); }"); | |
| 215 | |
| 216 analyze("${header}int k = c.intNoArgumentMethod(); }"); | |
| 217 analyze("${header}ClassWithMethods x = c.intNoArgumentMethod(); }", | |
| 218 MessageKind.NOT_ASSIGNABLE); | |
| 219 | |
| 220 analyze("${header}int k = c.intOneArgumentMethod(c); }", | |
| 221 MessageKind.NOT_ASSIGNABLE); | |
| 222 analyze("${header}ClassWithMethods x = c.intOneArgumentMethod(1); }", | |
| 223 MessageKind.NOT_ASSIGNABLE); | |
| 224 analyze("${header}int k = c.intOneArgumentMethod('string'); }", | |
| 225 MessageKind.NOT_ASSIGNABLE); | |
| 226 analyze("${header}int k = c.intOneArgumentMethod(i); }"); | |
| 227 | |
| 228 analyze("${header}int k = c.intTwoArgumentMethod(1, 'string'); }", | |
| 229 MessageKind.NOT_ASSIGNABLE); | |
| 230 analyze("${header}int k = c.intTwoArgumentMethod(i, j); }"); | |
| 231 analyze("${header}ClassWithMethods x = c.intTwoArgumentMethod(i, j); }", | |
| 232 MessageKind.NOT_ASSIGNABLE); | |
| 233 | |
| 234 analyze("${header}c.intField(); }", MessageKind.METHOD_NOT_FOUND); | |
| 235 analyze("${header}d.intField(); }", MessageKind.METHOD_NOT_FOUND); | |
| 236 } | |
| 237 | |
| 238 /** Tests analysis of returns (not required by the specification). */ | |
| 239 void testControlFlow() { | |
| 240 analyzeTopLevel("int foo() { if (true) { return 1; } }", | |
| 241 MessageKind.MAYBE_MISSING_RETURN); | |
| 242 final bar = | |
| 243 """void bar() { | |
| 244 if (true) { | |
| 245 if (true) { return; } else { return; } | |
| 246 } else { return; } | |
| 247 }"""; | |
| 248 analyzeTopLevel(bar); | |
| 249 analyzeTopLevel("void baz() { return; int i = 1; }", | |
| 250 MessageKind.UNREACHABLE_CODE); | |
| 251 final qux = | |
| 252 """void qux() { | |
| 253 if (true) { | |
| 254 return; | |
| 255 } else if (true) { | |
| 256 if (true) { | |
| 257 return; | |
| 258 } | |
| 259 throw 'hest'; | |
| 260 } | |
| 261 throw 'fisk'; | |
| 262 }"""; | |
| 263 analyzeTopLevel(qux); | |
| 264 analyzeTopLevel("int hest() {}", MessageKind.MISSING_RETURN); | |
| 265 final fisk = """int fisk() { | |
| 266 if (true) { | |
| 267 if (true) { return 1; } else {} | |
| 268 } else { return 1; } | |
| 269 }"""; | |
| 270 analyzeTopLevel(fisk, MessageKind.MAYBE_MISSING_RETURN); | |
| 271 } | |
| 272 | |
| 273 testNewExpression() { | |
| 274 compiler.parseScript("class A {}"); | |
| 275 analyze("A a = new A();"); | |
| 276 analyze("int i = new A();", MessageKind.NOT_ASSIGNABLE); | |
| 277 | |
| 278 // TODO(karlklose): constructors are not yet implemented. | |
| 279 // compiler.parseScript( | |
| 280 // "class Foo {\n" + | |
| 281 // " Foo(int x) {}\n" + | |
| 282 // " Foo.foo() {}\n" + | |
| 283 // " Foo.bar([int i = null]) {}\n" + | |
| 284 // "}\n" + | |
| 285 // "interface Bar<T> factory Baz {\n" + | |
| 286 // " Bar.make();\n" + | |
| 287 // "}\n" + | |
| 288 // "class Baz {\n" + | |
| 289 // " factory Bar<S>.make(S x) { return null; }\n" + | |
| 290 // "}"); | |
| 291 // | |
| 292 // analyze("Foo x = new Foo(0);"); | |
| 293 // analyze("Foo x = new Foo();", MessageKind.MISSING_ARGUMENT); | |
| 294 // analyze("Foo x = new Foo('');", MessageKind.NOT_ASSIGNABLE); | |
| 295 // analyze("Foo x = new Foo(0, null);", MessageKind.ADDITIONAL_ARGUMENT); | |
| 296 // | |
| 297 // analyze("Foo x = new Foo.foo();"); | |
| 298 // analyze("Foo x = new Foo.foo(null);", MessageKind.ADDITIONAL_ARGUMENT); | |
| 299 // | |
| 300 // analyze("Foo x = new Foo.bar();"); | |
| 301 // analyze("Foo x = new Foo.bar(0);"); | |
| 302 // analyze("Foo x = new Foo.bar('');", MessageKind.NOT_ASSIGNABLE); | |
| 303 // analyze("Foo x = new Foo.bar(0, null);", | |
| 304 // MessageKind.ADDITIONAL_ARGUMENT); | |
| 305 // | |
| 306 // analyze("Bar<String> x = new Bar<String>.make('');"); | |
| 307 } | |
| 308 | |
| 309 testConditionalExpression() { | |
| 310 analyze("int i = true ? 2 : 1;"); | |
| 311 analyze("int i = true ? 'hest' : 1;"); | |
| 312 analyze("int i = true ? 'hest' : 'fisk';", MessageKind.NOT_ASSIGNABLE); | |
| 313 analyze("String s = true ? 'hest' : 'fisk';"); | |
| 314 | |
| 315 analyze("true ? 1 : 2;"); | |
| 316 analyze("null ? 1 : 2;"); | |
| 317 analyze("0 ? 1 : 2;", MessageKind.NOT_ASSIGNABLE); | |
| 318 analyze("'' ? 1 : 2;", MessageKind.NOT_ASSIGNABLE); | |
| 319 analyze("{ int i; true ? i = 2.7 : 2; }", | |
| 320 MessageKind.NOT_ASSIGNABLE); | |
| 321 analyze("{ int i; true ? 2 : i = 2.7; }", | |
| 322 MessageKind.NOT_ASSIGNABLE); | |
| 323 analyze("{ int i; i = true ? 2.7 : 2; }"); | |
| 324 } | |
| 325 | |
| 326 testIfStatement() { | |
| 327 analyze("if (true) {}"); | |
| 328 analyze("if (null) {}"); | |
| 329 analyze("if (0) {}", | |
| 330 MessageKind.NOT_ASSIGNABLE); | |
| 331 analyze("if ('') {}", | |
| 332 MessageKind.NOT_ASSIGNABLE); | |
| 333 analyze("{ int i = 27; if (true) { i = 2.7; } else {} }", | |
| 334 MessageKind.NOT_ASSIGNABLE); | |
| 335 analyze("{ int i = 27; if (true) {} else { i = 2.7; } }", | |
| 336 MessageKind.NOT_ASSIGNABLE); | |
| 337 } | |
| 338 | |
| 339 testThis() { | |
| 340 String script = "class Foo {}"; | |
| 341 LibraryElement library = mockLibrary(compiler, script); | |
| 342 compiler.parseScript(script, library); | |
| 343 ClassElement foo = library.find(const SourceString("Foo")); | |
| 344 analyzeIn(foo, "{ int i = this; }", MessageKind.NOT_ASSIGNABLE); | |
| 345 analyzeIn(foo, "{ Object o = this; }"); | |
| 346 analyzeIn(foo, "{ Foo f = this; }"); | |
| 347 } | |
| 348 | |
| 349 testFunctionSubtyping() { | |
| 350 // Checks that the type (in1 -> out1) is a subtype of (in2 -> out2). | |
| 351 bool isSubtype(List<Type> in1, Type out1, List<Type> in2, Type out2) { | |
| 352 return compiler.types.isSubtype( | |
| 353 new FunctionType(out1, new Link<Type>.fromList(in1), null), | |
| 354 new FunctionType(out2, new Link<Type>.fromList(in2), null)); | |
| 355 } | |
| 356 Expect.isTrue(isSubtype([], intType, [], intType)); | |
| 357 Expect.isTrue(isSubtype([], intType, [], objectType)); | |
| 358 Expect.isFalse(isSubtype([], intType, [], doubleType)); | |
| 359 Expect.isTrue(isSubtype([intType], intType, [intType], intType)); | |
| 360 Expect.isTrue(isSubtype([objectType], intType, [intType], objectType)); | |
| 361 Expect.isFalse(isSubtype([intType], intType, [doubleType], intType)); | |
| 362 Expect.isFalse(isSubtype([intType], intType, [intType, intType], intType)); | |
| 363 Expect.isFalse(isSubtype([intType, intType], intType, [intType], intType)); | |
| 364 } | |
| 365 | |
| 366 final CLASS_WITH_METHODS = ''' | |
| 367 class ClassWithMethods { | |
| 368 untypedNoArgumentMethod() {} | |
| 369 untypedOneArgumentMethod(argument) {} | |
| 370 untypedTwoArgumentMethod(argument1, argument2) {} | |
| 371 | |
| 372 int intNoArgumentMethod() {} | |
| 373 int intOneArgumentMethod(int argument) {} | |
| 374 int intTwoArgumentMethod(int argument1, int argument2) {} | |
| 375 | |
| 376 Function functionField; | |
| 377 var untypedField; | |
| 378 int intField; | |
| 379 } | |
| 380 interface I { | |
| 381 int intMethod(); | |
| 382 } | |
| 383 class SubClass extends ClassWithMethods implements I {}'''; | |
| 384 | |
| 385 Types types; | |
| 386 MockCompiler compiler; | |
| 387 | |
| 388 String returnWithType(String type, expression) { | |
| 389 return "$type foo() { return $expression; }"; | |
| 390 } | |
| 391 | |
| 392 Node parseExpression(String text) => | |
| 393 parseBodyCode(text, (parser, token) => parser.parseExpression(token)); | |
| 394 | |
| 395 void setup() { | |
| 396 compiler = new MockCompiler(); | |
| 397 types = compiler.types; | |
| 398 intType = compiler.intClass.computeType(compiler); | |
| 399 doubleType = compiler.doubleClass.computeType(compiler); | |
| 400 boolType = compiler.boolClass.computeType(compiler); | |
| 401 stringType = compiler.stringClass.computeType(compiler); | |
| 402 objectType = compiler.objectClass.computeType(compiler); | |
| 403 } | |
| 404 | |
| 405 Type analyzeType(String text) { | |
| 406 var node = parseExpression(text); | |
| 407 TypeCheckerVisitor visitor = | |
| 408 new TypeCheckerVisitor(compiler, new TreeElementMapping(), types); | |
| 409 return visitor.analyze(node); | |
| 410 } | |
| 411 | |
| 412 analyzeTopLevel(String text, [expectedWarnings]) { | |
| 413 if (expectedWarnings === null) expectedWarnings = []; | |
| 414 if (expectedWarnings is !List) expectedWarnings = [expectedWarnings]; | |
| 415 | |
| 416 LibraryElement library = mockLibrary(compiler, text); | |
| 417 | |
| 418 Link<Element> topLevelElements = parseUnit(text, compiler, library); | |
| 419 | |
| 420 for (Link<Element> elements = topLevelElements; | |
| 421 !elements.isEmpty(); | |
| 422 elements = elements.tail) { | |
| 423 Node node = elements.head.parseNode(compiler); | |
| 424 TreeElements mapping = compiler.resolver.resolve(elements.head); | |
| 425 TypeCheckerVisitor checker = | |
| 426 new TypeCheckerVisitor(compiler, mapping, types); | |
| 427 compiler.clearWarnings(); | |
| 428 checker.analyze(node); | |
| 429 compareWarningKinds(text, expectedWarnings, compiler.warnings); | |
| 430 } | |
| 431 } | |
| 432 | |
| 433 analyze(String text, [expectedWarnings]) { | |
| 434 if (expectedWarnings === null) expectedWarnings = []; | |
| 435 if (expectedWarnings is !List) expectedWarnings = [expectedWarnings]; | |
| 436 | |
| 437 Token tokens = scan(text); | |
| 438 NodeListener listener = new NodeListener(compiler, null); | |
| 439 Parser parser = new Parser(listener); | |
| 440 parser.parseStatement(tokens); | |
| 441 Node node = listener.popNode(); | |
| 442 TreeElements elements = compiler.resolveNodeStatement(node, compiler.mainApp); | |
| 443 TypeCheckerVisitor checker = new TypeCheckerVisitor(compiler, elements, | |
| 444 types); | |
| 445 compiler.clearWarnings(); | |
| 446 checker.analyze(node); | |
| 447 compareWarningKinds(text, expectedWarnings, compiler.warnings); | |
| 448 } | |
| 449 | |
| 450 analyzeIn(ClassElement classElement, String text, [expectedWarnings]) { | |
| 451 if (expectedWarnings === null) expectedWarnings = []; | |
| 452 if (expectedWarnings is !List) expectedWarnings = [expectedWarnings]; | |
| 453 | |
| 454 Token tokens = scan(text); | |
| 455 NodeListener listener = new NodeListener(compiler, null); | |
| 456 Parser parser = new Parser(listener); | |
| 457 parser.parseStatement(tokens); | |
| 458 Node node = listener.popNode(); | |
| 459 TreeElements elements = compiler.resolveNodeStatement(node, classElement); | |
| 460 TypeCheckerVisitor checker = new TypeCheckerVisitor(compiler, elements, | |
| 461 types); | |
| 462 compiler.clearWarnings(); | |
| 463 checker.currentClass = classElement; | |
| 464 checker.analyze(node); | |
| 465 compareWarningKinds(text, expectedWarnings, compiler.warnings); | |
| 466 } | |
| OLD | NEW |