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 import "package:expect/expect.dart"; | |
6 import 'dart:async'; | 5 import 'dart:async'; |
7 import "package:async_helper/async_helper.dart"; | |
8 import 'dart:collection'; | 6 import 'dart:collection'; |
9 | 7 |
10 import "package:compiler/src/resolution/resolution.dart"; | 8 import 'package:async_helper/async_helper.dart'; |
11 import "compiler_helper.dart"; | 9 import 'package:expect/expect.dart'; |
12 import "parser_helper.dart"; | 10 import 'package:compiler/src/constants/expressions.dart'; |
13 | |
14 import 'package:compiler/src/dart_types.dart'; | 11 import 'package:compiler/src/dart_types.dart'; |
15 import 'package:compiler/src/elements/modelx.dart'; | 12 import 'package:compiler/src/elements/modelx.dart'; |
| 13 import 'package:compiler/src/resolution/resolution.dart'; |
| 14 |
| 15 import 'compiler_helper.dart'; |
16 import 'link_helper.dart'; | 16 import 'link_helper.dart'; |
| 17 import 'parser_helper.dart'; |
17 | 18 |
18 Node buildIdentifier(String name) => new Identifier(scan(name)); | 19 Node buildIdentifier(String name) => new Identifier(scan(name)); |
19 | 20 |
20 Node buildInitialization(String name) => | 21 Node buildInitialization(String name) => |
21 parseBodyCode('$name = 1', | 22 parseBodyCode('$name = 1', |
22 (parser, tokens) => parser.parseOptionallyInitializedIdentifier(tokens)); | 23 (parser, tokens) => parser.parseOptionallyInitializedIdentifier(tokens)); |
23 | 24 |
24 createLocals(List variables) { | 25 createLocals(List variables) { |
25 var locals = <Node>[]; | 26 var locals = <Node>[]; |
26 for (final variable in variables) { | 27 for (final variable in variables) { |
27 String name = variable[0]; | 28 String name = variable[0]; |
28 bool init = variable[1]; | 29 bool init = variable[1]; |
29 if (init) { | 30 if (init) { |
30 locals.add(buildInitialization(name)); | 31 locals.add(buildInitialization(name)); |
31 } else { | 32 } else { |
32 locals.add(buildIdentifier(name)); | 33 locals.add(buildIdentifier(name)); |
33 } | 34 } |
34 } | 35 } |
35 var definitions = new NodeList(null, LinkFromList(locals), null, null); | 36 var definitions = new NodeList(null, LinkFromList(locals), null, null); |
36 return new VariableDefinitions(null, Modifiers.EMPTY, definitions); | 37 return new VariableDefinitions(null, Modifiers.EMPTY, definitions); |
37 } | 38 } |
38 | 39 |
39 Future testLocals(List variables) { | 40 Future testLocals(List variables) { |
40 return MockCompiler.create((MockCompiler compiler) { | 41 return MockCompiler.create((MockCompiler compiler) { |
41 ResolverVisitor visitor = compiler.resolverVisitor(); | 42 ResolverVisitor visitor = compiler.resolverVisitor(); |
42 ResolutionResult result = visitor.visit(createLocals(variables)); | 43 ResolutionResult result = visitor.visit(createLocals(variables)); |
43 Element element = result != null ? result.element : null; | |
44 // A VariableDefinitions does not have an element. | 44 // A VariableDefinitions does not have an element. |
45 Expect.equals(null, element); | 45 Expect.equals(const NoneResult(), result); |
46 Expect.equals(variables.length, map(visitor).length); | 46 Expect.equals(variables.length, map(visitor).length); |
47 | 47 |
48 for (final variable in variables) { | 48 for (final variable in variables) { |
49 final name = variable[0]; | 49 final name = variable[0]; |
50 Identifier id = buildIdentifier(name); | 50 Identifier id = buildIdentifier(name); |
51 ResolutionResult result = visitor.visit(id); | 51 ResolutionResult result = visitor.visit(id); |
52 final VariableElement variableElement = | 52 final VariableElement variableElement = result.element; |
53 result != null ? result.element : null; | |
54 MethodScope scope = visitor.scope; | 53 MethodScope scope = visitor.scope; |
55 Expect.equals(variableElement, scope.elements[name]); | 54 Expect.equals(variableElement, scope.elements[name]); |
56 } | 55 } |
57 return compiler; | 56 return compiler; |
58 }); | 57 }); |
59 } | 58 } |
60 | 59 |
61 main() { | 60 main() { |
62 asyncTest(() => Future.forEach([ | 61 asyncTest(() => Future.forEach([ |
63 testLocalsOne, | 62 testLocalsOne, |
(...skipping 20 matching lines...) Expand all Loading... |
84 testTypeVariables, | 83 testTypeVariables, |
85 testToString, | 84 testToString, |
86 testIndexedOperator, | 85 testIndexedOperator, |
87 testIncrementsAndDecrements, | 86 testIncrementsAndDecrements, |
88 testOverrideHashCodeCheck, | 87 testOverrideHashCodeCheck, |
89 testSupertypeOrder, | 88 testSupertypeOrder, |
90 testConstConstructorAndNonFinalFields, | 89 testConstConstructorAndNonFinalFields, |
91 testCantAssignMethods, | 90 testCantAssignMethods, |
92 testCantAssignFinalAndConsts, | 91 testCantAssignFinalAndConsts, |
93 testAwaitHint, | 92 testAwaitHint, |
| 93 testConstantExpressions, |
94 ], (f) => f())); | 94 ], (f) => f())); |
95 } | 95 } |
96 | 96 |
97 Future testSupertypeOrder() { | 97 Future testSupertypeOrder() { |
98 return Future.wait([ | 98 return Future.wait([ |
99 MockCompiler.create((MockCompiler compiler) { | 99 MockCompiler.create((MockCompiler compiler) { |
100 compiler.parseScript(""" | 100 compiler.parseScript(""" |
101 class I1 {} | 101 class I1 {} |
102 class I2 {} | 102 class I2 {} |
103 class J1 extends K1 {} | 103 class J1 extends K1 {} |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 new Message(MessageKind.DUPLICATE_DEFINITION, {'name': 'foo'}, false), | 311 new Message(MessageKind.DUPLICATE_DEFINITION, {'name': 'foo'}, false), |
312 compiler.errors[0].message); | 312 compiler.errors[0].message); |
313 })], (f) => f()); | 313 })], (f) => f()); |
314 } | 314 } |
315 | 315 |
316 | 316 |
317 Future testLocalsTwo() { | 317 Future testLocalsTwo() { |
318 return MockCompiler.create((MockCompiler compiler) { | 318 return MockCompiler.create((MockCompiler compiler) { |
319 ResolverVisitor visitor = compiler.resolverVisitor(); | 319 ResolverVisitor visitor = compiler.resolverVisitor(); |
320 Node tree = parseStatement("if (true) { var a = 1; var b = 2; }"); | 320 Node tree = parseStatement("if (true) { var a = 1; var b = 2; }"); |
321 ResolutionResult element = visitor.visit(tree); | 321 ResolutionResult result = visitor.visit(tree); |
322 Expect.equals(null, element); | 322 Expect.equals(const NoneResult(), result); |
323 MethodScope scope = visitor.scope; | 323 MethodScope scope = visitor.scope; |
324 Expect.equals(0, scope.elements.length); | 324 Expect.equals(0, scope.elements.length); |
325 Expect.equals(2, map(visitor).length); | 325 Expect.equals(2, map(visitor).length); |
326 | 326 |
327 List<Element> elements = new List<Element>.from(map(visitor).values); | 327 List<Element> elements = new List<Element>.from(map(visitor).values); |
328 Expect.notEquals(elements[0], elements[1]); | 328 Expect.notEquals(elements[0], elements[1]); |
329 }); | 329 }); |
330 } | 330 } |
331 | 331 |
332 Future testLocalsThree() { | 332 Future testLocalsThree() { |
333 return MockCompiler.create((MockCompiler compiler) { | 333 return MockCompiler.create((MockCompiler compiler) { |
334 ResolverVisitor visitor = compiler.resolverVisitor(); | 334 ResolverVisitor visitor = compiler.resolverVisitor(); |
335 Node tree = parseStatement("{ var a = 1; if (true) { a; } }"); | 335 Node tree = parseStatement("{ var a = 1; if (true) { a; } }"); |
336 ResolutionResult element = visitor.visit(tree); | 336 ResolutionResult result = visitor.visit(tree); |
337 Expect.equals(null, element); | 337 Expect.equals(const NoneResult(), result); |
338 MethodScope scope = visitor.scope; | 338 MethodScope scope = visitor.scope; |
339 Expect.equals(0, scope.elements.length); | 339 Expect.equals(0, scope.elements.length); |
340 Expect.equals(3, map(visitor).length); | 340 Expect.equals(3, map(visitor).length); |
341 List<Element> elements = map(visitor).values.toList(); | 341 List<Element> elements = map(visitor).values.toList(); |
342 Expect.equals(elements[0], elements[1]); | 342 Expect.equals(elements[0], elements[1]); |
343 }); | 343 }); |
344 } | 344 } |
345 | 345 |
346 Future testLocalsFour() { | 346 Future testLocalsFour() { |
347 return MockCompiler.create((MockCompiler compiler) { | 347 return MockCompiler.create((MockCompiler compiler) { |
348 ResolverVisitor visitor = compiler.resolverVisitor(); | 348 ResolverVisitor visitor = compiler.resolverVisitor(); |
349 Node tree = parseStatement("{ var a = 1; if (true) { var a = 1; } }"); | 349 Node tree = parseStatement("{ var a = 1; if (true) { var a = 1; } }"); |
350 ResolutionResult element = visitor.visit(tree); | 350 ResolutionResult result = visitor.visit(tree); |
351 Expect.equals(null, element); | 351 Expect.equals(const NoneResult(), result); |
352 MethodScope scope = visitor.scope; | 352 MethodScope scope = visitor.scope; |
353 Expect.equals(0, scope.elements.length); | 353 Expect.equals(0, scope.elements.length); |
354 Expect.equals(2, map(visitor).length); | 354 Expect.equals(2, map(visitor).length); |
355 List<Element> elements = map(visitor).values.toList(); | 355 List<Element> elements = map(visitor).values.toList(); |
356 Expect.notEquals(elements[0], elements[1]); | 356 Expect.notEquals(elements[0], elements[1]); |
357 }); | 357 }); |
358 } | 358 } |
359 | 359 |
360 Future testLocalsFive() { | 360 Future testLocalsFive() { |
361 return MockCompiler.create((MockCompiler compiler) { | 361 return MockCompiler.create((MockCompiler compiler) { |
362 ResolverVisitor visitor = compiler.resolverVisitor(); | 362 ResolverVisitor visitor = compiler.resolverVisitor(); |
363 If tree = | 363 If tree = |
364 parseStatement("if (true) { var a = 1; a; } else { var a = 2; a;}"); | 364 parseStatement("if (true) { var a = 1; a; } else { var a = 2; a;}"); |
365 ResolutionResult element = visitor.visit(tree); | 365 ResolutionResult result = visitor.visit(tree); |
366 Expect.equals(null, element); | 366 Expect.equals(const NoneResult(), result); |
367 MethodScope scope = visitor.scope; | 367 MethodScope scope = visitor.scope; |
368 Expect.equals(0, scope.elements.length); | 368 Expect.equals(0, scope.elements.length); |
369 Expect.equals(6, map(visitor).length); | 369 Expect.equals(6, map(visitor).length); |
370 | 370 |
371 Block thenPart = tree.thenPart; | 371 Block thenPart = tree.thenPart; |
372 List statements1 = thenPart.statements.nodes.toList(); | 372 List statements1 = thenPart.statements.nodes.toList(); |
373 Node def1 = statements1[0].definitions.nodes.head; | 373 Node def1 = statements1[0].definitions.nodes.head; |
374 Node id1 = statements1[1].expression; | 374 Node id1 = statements1[1].expression; |
375 Expect.equals(visitor.registry.mapping[def1], | 375 Expect.equals(visitor.registry.mapping[def1], |
376 visitor.registry.mapping[id1]); | 376 visitor.registry.mapping[id1]); |
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 const { 'Object': 'class Object { Object() : super(); }' }; | 992 const { 'Object': 'class Object { Object() : super(); }' }; |
993 return resolveConstructor(script, | 993 return resolveConstructor(script, |
994 "Object o = new Object();", "Object", "", 1, | 994 "Object o = new Object();", "Object", "", 1, |
995 expectedWarnings: [], | 995 expectedWarnings: [], |
996 expectedErrors: [MessageKind.SUPER_INITIALIZER_IN_OBJECT], | 996 expectedErrors: [MessageKind.SUPER_INITIALIZER_IN_OBJECT], |
997 corelib: INVALID_OBJECT); | 997 corelib: INVALID_OBJECT); |
998 }, | 998 }, |
999 ], (f) => f()); | 999 ], (f) => f()); |
1000 } | 1000 } |
1001 | 1001 |
| 1002 Future testConstantExpressions() { |
| 1003 const Map<String, List<String>> testedConstants = const { |
| 1004 'null': const ['null'], |
| 1005 'true': const ['true'], |
| 1006 '0': const ['0'], |
| 1007 '0.0': const ['0.0'], |
| 1008 '"foo"': const ['"foo"'], |
| 1009 '#a': const ['#a'], |
| 1010 '0 + 1': const ['0', '1', '0 + 1'], |
| 1011 '0 * 1': const ['0', '1', '0 * 1'], |
| 1012 '0 * 1 + 2': const ['0', '1', '0 * 1', '2', '0 * 1 + 2'], |
| 1013 '0 + 1 * 2': const ['0', '1', '2', '1 * 2', '0 + 1 * 2'], |
| 1014 '-(1)': const ['1', '-1'], |
| 1015 '-(1 * 4)': const ['1', '4', '1 * 4', '-(1 * 4)'], |
| 1016 'true ? 0 : 1': const ['true', '0', '1', 'true ? 0 : 1'], |
| 1017 '"a" "b"': const ['"a"', '"b"', '"ab"'], |
| 1018 '"a" "b" "c"': const ['"a"', '"b"', '"c"', '"bc"', r'"a${"bc"}"'], |
| 1019 r'"a${0}b"': const ['"a"', '0', '"b"', r'"a${0}b"'], |
| 1020 r'"a${0}b${1}"': const ['"a"', '0', '"b"', '1', '""', r'"a${0}b${1}"'], |
| 1021 'true || false': const ['true', 'false', 'true || false'], |
| 1022 'true && false': const ['true', 'false', 'true && false'], |
| 1023 '!true': const ['true', '!true'], |
| 1024 'const []': const ['const []'], |
| 1025 'const <int>[]': const ['const <int>[]'], |
| 1026 'const [0, 1, 2]': const ['0', '1', '2', 'const [0, 1, 2]'], |
| 1027 'const <int>[0, 1, 2]': const ['0', '1', '2', 'const <int>[0, 1, 2]'], |
| 1028 'const {}': const ['const {}'], |
| 1029 'const <String, int>{}': const ['const <String, int>{}'], |
| 1030 'const {"a": 0, "b": 1, "c": 2}': |
| 1031 const ['"a"', '0', '"b"', '1', '"c"', '2', |
| 1032 'const {"a": 0, "b": 1, "c": 2}'], |
| 1033 'const <String, int>{"a": 0, "b": 1, "c": 2}': |
| 1034 const ['"a"', '0', '"b"', '1', '"c"', '2', |
| 1035 'const <String, int>{"a": 0, "b": 1, "c": 2}'], |
| 1036 }; |
| 1037 return Future.forEach(testedConstants.keys, (String constant) { |
| 1038 return MockCompiler.create((MockCompiler compiler) { |
| 1039 CollectingTreeElements elements = |
| 1040 compiler.resolveStatement("main() => $constant;"); |
| 1041 List<String> expectedConstants = testedConstants[constant]; |
| 1042 Expect.equals(0, compiler.warnings.length); |
| 1043 Expect.equals(0, compiler.errors.length); |
| 1044 List<ConstantExpression> constants = elements.constants; |
| 1045 String constantsText = |
| 1046 '[${constants.map((c) => c.getText()).join(', ')}]'; |
| 1047 Expect.equals(expectedConstants.length, constants.length, |
| 1048 "Expected ${expectedConstants.length} constants for `${constant}` " |
| 1049 "found $constantsText."); |
| 1050 for (int index = 0; index < expectedConstants.length; index++) { |
| 1051 Expect.equals(expectedConstants[index], constants[index].getText(), |
| 1052 "Expected ${expectedConstants} for `$constant`, " |
| 1053 "found $constantsText."); |
| 1054 } |
| 1055 }); |
| 1056 }); |
| 1057 } |
| 1058 |
1002 map(ResolverVisitor visitor) { | 1059 map(ResolverVisitor visitor) { |
1003 CollectingTreeElements elements = visitor.registry.mapping; | 1060 CollectingTreeElements elements = visitor.registry.mapping; |
1004 return elements.map; | 1061 return elements.map; |
1005 } | 1062 } |
1006 | 1063 |
1007 at(Link link, int index) => (index == 0) ? link.head : at(link.tail, index - 1); | 1064 at(Link link, int index) => (index == 0) ? link.head : at(link.tail, index - 1); |
1008 | 1065 |
1009 List<String> asSortedStrings(Link link) { | 1066 List<String> asSortedStrings(Link link) { |
1010 List<String> result = <String>[]; | 1067 List<String> result = <String>[]; |
1011 for (; !link.isEmpty; link = link.tail) result.add(link.head.toString()); | 1068 for (; !link.isEmpty; link = link.tail) result.add(link.head.toString()); |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 } | 1389 } |
1333 main() => A.m(); | 1390 main() => A.m(); |
1334 ''', functionName: 'm'); | 1391 ''', functionName: 'm'); |
1335 check(''' | 1392 check(''' |
1336 class A { | 1393 class A { |
1337 m() => () => await - 3; | 1394 m() => () => await - 3; |
1338 } | 1395 } |
1339 main() => new A().m(); | 1396 main() => new A().m(); |
1340 ''', className: 'A'); | 1397 ''', className: 'A'); |
1341 } | 1398 } |
OLD | NEW |