| 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 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 | 7 |
| 8 import 'package:async_helper/async_helper.dart'; | 8 import 'package:async_helper/async_helper.dart'; |
| 9 import 'package:expect/expect.dart'; | 9 import 'package:expect/expect.dart'; |
| 10 import 'package:compiler/src/constants/expressions.dart'; | 10 import 'package:compiler/src/constants/expressions.dart'; |
| 11 import 'package:compiler/src/dart_types.dart'; | 11 import 'package:compiler/src/dart_types.dart'; |
| 12 import 'package:compiler/src/elements/modelx.dart'; | 12 import 'package:compiler/src/elements/modelx.dart'; |
| 13 import 'package:compiler/src/resolution/constructors.dart'; | 13 import 'package:compiler/src/resolution/constructors.dart'; |
| 14 import 'package:compiler/src/resolution/members.dart'; | 14 import 'package:compiler/src/resolution/members.dart'; |
| 15 import 'package:compiler/src/resolution/registry.dart'; | 15 import 'package:compiler/src/resolution/registry.dart'; |
| 16 import 'package:compiler/src/resolution/resolution_result.dart'; | 16 import 'package:compiler/src/resolution/resolution_result.dart'; |
| 17 import 'package:compiler/src/resolution/scope.dart'; | 17 import 'package:compiler/src/resolution/scope.dart'; |
| 18 import 'package:compiler/src/resolution/tree_elements.dart'; | 18 import 'package:compiler/src/resolution/tree_elements.dart'; |
| 19 | 19 |
| 20 import 'compiler_helper.dart'; | 20 import 'compiler_helper.dart'; |
| 21 import 'link_helper.dart'; | 21 import 'link_helper.dart'; |
| 22 import 'parser_helper.dart'; | 22 import 'parser_helper.dart'; |
| 23 | 23 |
| 24 Node buildIdentifier(String name) => new Identifier(scan(name)); | 24 Node buildIdentifier(String name) => new Identifier(scan(name)); |
| 25 | 25 |
| 26 Node buildInitialization(String name) => | 26 Node buildInitialization(String name) => parseBodyCode('$name = 1', |
| 27 parseBodyCode('$name = 1', | 27 (parser, tokens) => parser.parseOptionallyInitializedIdentifier(tokens)); |
| 28 (parser, tokens) => parser.parseOptionallyInitializedIdentifier(tokens)); | |
| 29 | 28 |
| 30 createLocals(List variables) { | 29 createLocals(List variables) { |
| 31 var locals = <Node>[]; | 30 var locals = <Node>[]; |
| 32 for (final variable in variables) { | 31 for (final variable in variables) { |
| 33 String name = variable[0]; | 32 String name = variable[0]; |
| 34 bool init = variable[1]; | 33 bool init = variable[1]; |
| 35 if (init) { | 34 if (init) { |
| 36 locals.add(buildInitialization(name)); | 35 locals.add(buildInitialization(name)); |
| 37 } else { | 36 } else { |
| 38 locals.add(buildIdentifier(name)); | 37 locals.add(buildIdentifier(name)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 57 final VariableElement variableElement = result.element; | 56 final VariableElement variableElement = result.element; |
| 58 MethodScope scope = visitor.scope; | 57 MethodScope scope = visitor.scope; |
| 59 Expect.equals(variableElement, scope.elements[name]); | 58 Expect.equals(variableElement, scope.elements[name]); |
| 60 } | 59 } |
| 61 return compiler; | 60 return compiler; |
| 62 }); | 61 }); |
| 63 } | 62 } |
| 64 | 63 |
| 65 main() { | 64 main() { |
| 66 asyncTest(() => Future.forEach([ | 65 asyncTest(() => Future.forEach([ |
| 67 testLocalsOne, | 66 testLocalsOne, |
| 68 testLocalsTwo, | 67 testLocalsTwo, |
| 69 testLocalsThree, | 68 testLocalsThree, |
| 70 testLocalsFour, | 69 testLocalsFour, |
| 71 testLocalsFive, | 70 testLocalsFive, |
| 72 testParametersOne, | 71 testParametersOne, |
| 73 testFor, | 72 testFor, |
| 74 testTypeAnnotation, | 73 testTypeAnnotation, |
| 75 testSuperclass, | 74 testSuperclass, |
| 76 // testVarSuperclass, // The parser crashes with 'class Foo extends var'. | 75 // testVarSuperclass, // The parser crashes with 'class Foo extends var'
. |
| 77 // testOneInterface, // Generates unexpected error message. | 76 // testOneInterface, // Generates unexpected error message. |
| 78 // testTwoInterfaces, // Generates unexpected error message. | 77 // testTwoInterfaces, // Generates unexpected error message. |
| 79 testFunctionExpression, | 78 testFunctionExpression, |
| 80 testNewExpression, | 79 testNewExpression, |
| 81 testTopLevelFields, | 80 testTopLevelFields, |
| 82 testClassHierarchy, | 81 testClassHierarchy, |
| 83 testEnumDeclaration, | 82 testEnumDeclaration, |
| 84 testInitializers, | 83 testInitializers, |
| 85 testThis, | 84 testThis, |
| 86 testSuperCalls, | 85 testSuperCalls, |
| 87 testSwitch, | 86 testSwitch, |
| 88 testTypeVariables, | 87 testTypeVariables, |
| 89 testToString, | 88 testToString, |
| 90 testIndexedOperator, | 89 testIndexedOperator, |
| 91 testIncrementsAndDecrements, | 90 testIncrementsAndDecrements, |
| 92 testOverrideHashCodeCheck, | 91 testOverrideHashCodeCheck, |
| 93 testSupertypeOrder, | 92 testSupertypeOrder, |
| 94 testConstConstructorAndNonFinalFields, | 93 testConstConstructorAndNonFinalFields, |
| 95 testCantAssignMethods, | 94 testCantAssignMethods, |
| 96 testCantAssignFinalAndConsts, | 95 testCantAssignFinalAndConsts, |
| 97 testAwaitHint, | 96 testAwaitHint, |
| 98 testConstantExpressions, | 97 testConstantExpressions, |
| 99 ], (f) => f())); | 98 ], (f) => f())); |
| 100 } | 99 } |
| 101 | 100 |
| 102 Future testSupertypeOrder() { | 101 Future testSupertypeOrder() { |
| 103 return Future.wait([ | 102 return Future.wait([ |
| 104 MockCompiler.create((MockCompiler compiler) { | 103 MockCompiler.create((MockCompiler compiler) { |
| 105 compiler.parseScript(""" | 104 compiler.parseScript(""" |
| 106 class I1 {} | 105 class I1 {} |
| 107 class I2 {} | 106 class I2 {} |
| 108 class J1 extends K1 {} | 107 class J1 extends K1 {} |
| 109 class J2 implements K2 {} | 108 class J2 implements K2 {} |
| 110 class K1 {} | 109 class K1 {} |
| 111 class K2 {} | 110 class K2 {} |
| 112 class L1 {} | 111 class L1 {} |
| 113 class A implements I1, I2 {} | 112 class A implements I1, I2 {} |
| 114 class B extends A implements J1, J2 {} | 113 class B extends A implements J1, J2 {} |
| 115 class C extends B implements L1 {} | 114 class C extends B implements L1 {} |
| 116 """); | 115 """); |
| 117 compiler.resolveStatement("C c;"); | 116 compiler.resolveStatement("C c;"); |
| 118 ClassElement classA = compiler.mainApp.find("A"); | 117 ClassElement classA = compiler.mainApp.find("A"); |
| 119 ClassElement classB = compiler.mainApp.find("B"); | 118 ClassElement classB = compiler.mainApp.find("B"); |
| 120 ClassElement classC = compiler.mainApp.find("C"); | 119 ClassElement classC = compiler.mainApp.find("C"); |
| 121 Expect.equals('[ I2, I1, Object ]', classA.allSupertypes.toString()); | 120 Expect.equals('[ I2, I1, Object ]', classA.allSupertypes.toString()); |
| 122 Expect.equals('[ A, J2, J1, I2, I1, K2, K1, Object ]', | 121 Expect.equals('[ A, J2, J1, I2, I1, K2, K1, Object ]', |
| 123 classB.allSupertypes.toString()); | 122 classB.allSupertypes.toString()); |
| 124 Expect.equals('[ B, L1, A, J2, J1, I2, I1, K2, K1, Object ]', | 123 Expect.equals('[ B, L1, A, J2, J1, I2, I1, K2, K1, Object ]', |
| 125 classC.allSupertypes.toString()); | 124 classC.allSupertypes.toString()); |
| 126 }), | 125 }), |
| 127 MockCompiler.create((MockCompiler compiler) { | 126 MockCompiler.create((MockCompiler compiler) { |
| 128 compiler.parseScript(""" | 127 compiler.parseScript(""" |
| 129 class X<T> {} | 128 class X<T> {} |
| 130 class Foo extends X<Foo> {} | 129 class Foo extends X<Foo> {} |
| 131 class Bar extends Foo implements X<Bar> {} | 130 class Bar extends Foo implements X<Bar> {} |
| 132 """); | 131 """); |
| 133 compiler.resolveStatement("Bar bar;"); | 132 compiler.resolveStatement("Bar bar;"); |
| 134 ClassElement classBar = compiler.mainApp.find("Bar"); | 133 ClassElement classBar = compiler.mainApp.find("Bar"); |
| 135 DiagnosticCollector collector = compiler.diagnosticCollector; | 134 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 136 Expect.equals(0, collector.warnings.length); | 135 Expect.equals(0, collector.warnings.length); |
| 137 Expect.equals(1, collector.errors.length); | 136 Expect.equals(1, collector.errors.length); |
| 138 Expect.equals(MessageKind.MULTI_INHERITANCE, | 137 Expect.equals( |
| 139 collector.errors.first.message.kind); | 138 MessageKind.MULTI_INHERITANCE, collector.errors.first.message.kind); |
| 140 Expect.equals(0, collector.crashes.length); | 139 Expect.equals(0, collector.crashes.length); |
| 141 }), | 140 }), |
| 142 ]); | 141 ]); |
| 143 } | 142 } |
| 144 | 143 |
| 145 Future testTypeVariables() { | 144 Future testTypeVariables() { |
| 146 matchResolvedTypes(visitor, text, name, expectedElements) { | 145 matchResolvedTypes(visitor, text, name, expectedElements) { |
| 147 VariableDefinitions definition = parseStatement(text); | 146 VariableDefinitions definition = parseStatement(text); |
| 148 visitor.visit(definition.type); | 147 visitor.visit(definition.type); |
| 149 InterfaceType type = visitor.registry.mapping.getType(definition.type); | 148 InterfaceType type = visitor.registry.mapping.getType(definition.type); |
| 150 Expect.equals(definition.type.typeArguments.slowLength(), | 149 Expect.equals( |
| 151 type.typeArguments.length); | 150 definition.type.typeArguments.slowLength(), type.typeArguments.length); |
| 152 int index = 0; | 151 int index = 0; |
| 153 for (DartType argument in type.typeArguments) { | 152 for (DartType argument in type.typeArguments) { |
| 154 Expect.equals(true, index < expectedElements.length); | 153 Expect.equals(true, index < expectedElements.length); |
| 155 Expect.equals(expectedElements[index], argument.element); | 154 Expect.equals(expectedElements[index], argument.element); |
| 156 index++; | 155 index++; |
| 157 } | 156 } |
| 158 Expect.equals(index, expectedElements.length); | 157 Expect.equals(index, expectedElements.length); |
| 159 } | 158 } |
| 160 | 159 |
| 161 return Future.wait([ | 160 return Future.wait([ |
| 162 MockCompiler.create((MockCompiler compiler) { | 161 MockCompiler.create((MockCompiler compiler) { |
| 163 ResolverVisitor visitor = compiler.resolverVisitor(); | 162 ResolverVisitor visitor = compiler.resolverVisitor(); |
| 164 compiler.parseScript('class Foo<T, U> {}'); | 163 compiler.parseScript('class Foo<T, U> {}'); |
| 165 ClassElement foo = compiler.mainApp.find('Foo'); | 164 ClassElement foo = compiler.mainApp.find('Foo'); |
| 166 matchResolvedTypes(visitor, 'Foo<int, String> x;', 'Foo', | 165 matchResolvedTypes(visitor, 'Foo<int, String> x;', 'Foo', |
| 167 [compiler.coreClasses.intClass, | 166 [compiler.coreClasses.intClass, compiler.coreClasses.stringClass]); |
| 168 compiler.coreClasses.stringClass]); | 167 matchResolvedTypes(visitor, 'Foo<Foo, Foo> x;', 'Foo', [foo, foo]); |
| 169 matchResolvedTypes(visitor, 'Foo<Foo, Foo> x;', 'Foo', | |
| 170 [foo, foo]); | |
| 171 }), | 168 }), |
| 172 | |
| 173 MockCompiler.create((MockCompiler compiler) { | 169 MockCompiler.create((MockCompiler compiler) { |
| 174 compiler.parseScript('class Foo<T, U> {}'); | 170 compiler.parseScript('class Foo<T, U> {}'); |
| 175 compiler.resolveStatement('Foo<notype, int> x;'); | 171 compiler.resolveStatement('Foo<notype, int> x;'); |
| 176 DiagnosticCollector collector = compiler.diagnosticCollector; | 172 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 177 Expect.equals(1, collector.warnings.length); | 173 Expect.equals(1, collector.warnings.length); |
| 178 Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE, | 174 Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE, |
| 179 collector.warnings.first.message.kind); | 175 collector.warnings.first.message.kind); |
| 180 Expect.equals(0, collector.errors.length); | 176 Expect.equals(0, collector.errors.length); |
| 181 }), | 177 }), |
| 182 | |
| 183 MockCompiler.create((MockCompiler compiler) { | 178 MockCompiler.create((MockCompiler compiler) { |
| 184 compiler.parseScript('class Foo<T, U> {}'); | 179 compiler.parseScript('class Foo<T, U> {}'); |
| 185 compiler.resolveStatement('var x = new Foo<notype, int>();'); | 180 compiler.resolveStatement('var x = new Foo<notype, int>();'); |
| 186 DiagnosticCollector collector = compiler.diagnosticCollector; | 181 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 187 Expect.equals(1, collector.warnings.length); | 182 Expect.equals(1, collector.warnings.length); |
| 188 Expect.equals(0, collector.errors.length); | 183 Expect.equals(0, collector.errors.length); |
| 189 Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE, | 184 Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE, |
| 190 collector.warnings.first.message.kind); | 185 collector.warnings.first.message.kind); |
| 191 }), | 186 }), |
| 192 | |
| 193 MockCompiler.create((MockCompiler compiler) { | 187 MockCompiler.create((MockCompiler compiler) { |
| 194 compiler.parseScript('class Foo<T> {' | 188 compiler.parseScript('class Foo<T> {' |
| 195 ' Foo<T> t;' | 189 ' Foo<T> t;' |
| 196 ' foo(Foo<T> f) {}' | 190 ' foo(Foo<T> f) {}' |
| 197 ' bar() { g(Foo<T> f) {}; g(); }' | 191 ' bar() { g(Foo<T> f) {}; g(); }' |
| 198 '}'); | 192 '}'); |
| 199 ClassElement foo = compiler.mainApp.find('Foo'); | 193 ClassElement foo = compiler.mainApp.find('Foo'); |
| 200 foo.ensureResolved(compiler.resolution); | 194 foo.ensureResolved(compiler.resolution); |
| 201 MemberElement tMember = foo.lookupLocalMember('t'); | 195 MemberElement tMember = foo.lookupLocalMember('t'); |
| 202 tMember.computeType(compiler.resolution); | 196 tMember.computeType(compiler.resolution); |
| 203 MemberElement fooMember = foo.lookupLocalMember('foo'); | 197 MemberElement fooMember = foo.lookupLocalMember('foo'); |
| 204 fooMember.computeType(compiler.resolution); | 198 fooMember.computeType(compiler.resolution); |
| 205 compiler.resolver.resolve(foo.lookupLocalMember('bar')); | 199 compiler.resolver.resolve(foo.lookupLocalMember('bar')); |
| 206 DiagnosticCollector collector = compiler.diagnosticCollector; | 200 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 207 Expect.equals(0, collector.warnings.length); | 201 Expect.equals(0, collector.warnings.length); |
| 208 Expect.equals(0, collector.errors.length); | 202 Expect.equals(0, collector.errors.length); |
| 209 }), | 203 }), |
| 210 ]); | 204 ]); |
| 211 } | 205 } |
| 212 | 206 |
| 213 Future testSuperCalls() { | 207 Future testSuperCalls() { |
| 214 return MockCompiler.create((MockCompiler compiler) { | 208 return MockCompiler.create((MockCompiler compiler) { |
| 215 String script = """class A { foo() {} } | 209 String script = """class A { foo() {} } |
| 216 class B extends A { foo() => super.foo(); }"""; | 210 class B extends A { foo() => super.foo(); }"""; |
| 217 compiler.parseScript(script); | 211 compiler.parseScript(script); |
| 218 compiler.resolveStatement("B b;"); | 212 compiler.resolveStatement("B b;"); |
| 219 | 213 |
| 220 ClassElement classB = compiler.mainApp.find("B"); | 214 ClassElement classB = compiler.mainApp.find("B"); |
| 221 FunctionElement fooB = classB.lookupLocalMember("foo"); | 215 FunctionElement fooB = classB.lookupLocalMember("foo"); |
| 222 ClassElement classA = compiler.mainApp.find("A"); | 216 ClassElement classA = compiler.mainApp.find("A"); |
| 223 FunctionElement fooA = classA.lookupLocalMember("foo"); | 217 FunctionElement fooA = classA.lookupLocalMember("foo"); |
| 224 | 218 |
| 225 ResolverVisitor visitor = new ResolverVisitor( | 219 ResolverVisitor visitor = new ResolverVisitor( |
| 226 compiler, | 220 compiler.resolution, |
| 227 fooB, | 221 fooB, |
| 228 new ResolutionRegistry(compiler, new CollectingTreeElements(fooB)), | 222 new ResolutionRegistry( |
| 223 compiler.backend, new CollectingTreeElements(fooB)), |
| 229 scope: new MockTypeVariablesScope(classB.buildScope())); | 224 scope: new MockTypeVariablesScope(classB.buildScope())); |
| 230 FunctionExpression node = | 225 FunctionExpression node = |
| 231 (fooB as FunctionElementX).parseNode(compiler.parsingContext); | 226 (fooB as FunctionElementX).parseNode(compiler.parsingContext); |
| 232 visitor.visit(node.body); | 227 visitor.visit(node.body); |
| 233 Map mapping = map(visitor); | 228 Map mapping = map(visitor); |
| 234 | 229 |
| 235 Send superCall = node.body.asReturn().expression; | 230 Send superCall = node.body.asReturn().expression; |
| 236 FunctionElement called = mapping[superCall]; | 231 FunctionElement called = mapping[superCall]; |
| 237 Expect.isNotNull(called); | 232 Expect.isNotNull(called); |
| 238 Expect.equals(fooA, called); | 233 Expect.equals(fooA, called); |
| 239 }); | 234 }); |
| 240 } | 235 } |
| 241 | 236 |
| 242 Future testSwitch() { | 237 Future testSwitch() { |
| 243 return MockCompiler.create((MockCompiler compiler) { | 238 return MockCompiler.create((MockCompiler compiler) { |
| 244 compiler.parseScript("class Foo { foo() {" | 239 compiler.parseScript("class Foo { foo() {" |
| 245 "switch (null) { case '': break; case 2: break; } } }"); | 240 "switch (null) { case '': break; case 2: break; } } }"); |
| 246 compiler.resolveStatement("Foo foo;"); | 241 compiler.resolveStatement("Foo foo;"); |
| 247 ClassElement fooElement = compiler.mainApp.find("Foo"); | 242 ClassElement fooElement = compiler.mainApp.find("Foo"); |
| 248 FunctionElement funElement = fooElement.lookupLocalMember("foo"); | 243 FunctionElement funElement = fooElement.lookupLocalMember("foo"); |
| 249 compiler.processQueue(compiler.enqueuer.resolution, funElement); | 244 compiler.processQueue(compiler.enqueuer.resolution, funElement); |
| 250 DiagnosticCollector collector = compiler.diagnosticCollector; | 245 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 251 Expect.equals(0, collector.warnings.length); | 246 Expect.equals(0, collector.warnings.length); |
| 252 Expect.equals(1, collector.errors.length); | 247 Expect.equals(1, collector.errors.length); |
| 253 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL, | 248 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL, |
| 254 collector.errors.first.message.kind); | 249 collector.errors.first.message.kind); |
| 255 Expect.equals(2, collector.infos.length); | 250 Expect.equals(2, collector.infos.length); |
| 256 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, | 251 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, |
| 257 collector.infos.first.message.kind); | 252 collector.infos.first.message.kind); |
| 258 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, | 253 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, |
| 259 collector.infos.elementAt(1).message.kind); | 254 collector.infos.elementAt(1).message.kind); |
| 260 }); | 255 }); |
| 261 } | 256 } |
| 262 | 257 |
| 263 Future testThis() { | 258 Future testThis() { |
| 264 return Future.wait([ | 259 return Future.wait([ |
| 265 MockCompiler.create((MockCompiler compiler) { | 260 MockCompiler.create((MockCompiler compiler) { |
| 266 compiler.parseScript("class Foo { foo() { return this; } }"); | 261 compiler.parseScript("class Foo { foo() { return this; } }"); |
| 267 compiler.resolveStatement("Foo foo;"); | 262 compiler.resolveStatement("Foo foo;"); |
| 268 ClassElement fooElement = compiler.mainApp.find("Foo"); | 263 ClassElement fooElement = compiler.mainApp.find("Foo"); |
| 269 FunctionElement funElement = fooElement.lookupLocalMember("foo"); | 264 FunctionElement funElement = fooElement.lookupLocalMember("foo"); |
| 270 ResolverVisitor visitor = new ResolverVisitor( | 265 ResolverVisitor visitor = new ResolverVisitor( |
| 271 compiler, | 266 compiler.resolution, |
| 272 funElement, | 267 funElement, |
| 273 new ResolutionRegistry( | 268 new ResolutionRegistry( |
| 274 compiler, new CollectingTreeElements(funElement)), | 269 compiler.backend, new CollectingTreeElements(funElement)), |
| 275 scope: new MockTypeVariablesScope(fooElement.buildScope())); | 270 scope: new MockTypeVariablesScope(fooElement.buildScope())); |
| 276 FunctionExpression function = | 271 FunctionExpression function = |
| 277 (funElement as FunctionElementX).parseNode(compiler.parsingContext); | 272 (funElement as FunctionElementX).parseNode(compiler.parsingContext); |
| 278 visitor.visit(function.body); | 273 visitor.visit(function.body); |
| 279 Map mapping = map(visitor); | 274 Map mapping = map(visitor); |
| 280 List<Element> values = mapping.values.toList(); | 275 List<Element> values = mapping.values.toList(); |
| 281 DiagnosticCollector collector = compiler.diagnosticCollector; | 276 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 282 Expect.equals(0, mapping.length); | 277 Expect.equals(0, mapping.length); |
| 283 Expect.equals(0, collector.warnings.length); | 278 Expect.equals(0, collector.warnings.length); |
| 284 }), | 279 }), |
| 285 MockCompiler.create((MockCompiler compiler) { | 280 MockCompiler.create((MockCompiler compiler) { |
| 286 compiler.resolveStatement("main() { return this; }"); | 281 compiler.resolveStatement("main() { return this; }"); |
| 287 DiagnosticCollector collector = compiler.diagnosticCollector; | 282 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 288 Expect.equals(0, collector.warnings.length); | 283 Expect.equals(0, collector.warnings.length); |
| 289 Expect.equals(1, collector.errors.length); | 284 Expect.equals(1, collector.errors.length); |
| 290 Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE, | 285 Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE, |
| 291 collector.errors.first.message.kind); | 286 collector.errors.first.message.kind); |
| 292 }), | 287 }), |
| 293 MockCompiler.create((MockCompiler compiler) { | 288 MockCompiler.create((MockCompiler compiler) { |
| 294 compiler.parseScript("class Foo { static foo() { return this; } }"); | 289 compiler.parseScript("class Foo { static foo() { return this; } }"); |
| 295 compiler.resolveStatement("Foo foo;"); | 290 compiler.resolveStatement("Foo foo;"); |
| 296 ClassElement fooElement = compiler.mainApp.find("Foo"); | 291 ClassElement fooElement = compiler.mainApp.find("Foo"); |
| 297 FunctionElement funElement = fooElement.lookupLocalMember("foo"); | 292 FunctionElement funElement = fooElement.lookupLocalMember("foo"); |
| 298 ResolverVisitor visitor = new ResolverVisitor( | 293 ResolverVisitor visitor = new ResolverVisitor( |
| 299 compiler, | 294 compiler.resolution, |
| 300 funElement, | 295 funElement, |
| 301 new ResolutionRegistry( | 296 new ResolutionRegistry( |
| 302 compiler, new CollectingTreeElements(funElement)), | 297 compiler.backend, new CollectingTreeElements(funElement)), |
| 303 scope: new MockTypeVariablesScope(fooElement.buildScope())); | 298 scope: new MockTypeVariablesScope(fooElement.buildScope())); |
| 304 FunctionExpression function = | 299 FunctionExpression function = |
| 305 (funElement as FunctionElementX).parseNode(compiler.parsingContext); | 300 (funElement as FunctionElementX).parseNode(compiler.parsingContext); |
| 306 visitor.visit(function.body); | 301 visitor.visit(function.body); |
| 307 DiagnosticCollector collector = compiler.diagnosticCollector; | 302 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 308 Expect.equals(0, collector.warnings.length); | 303 Expect.equals(0, collector.warnings.length); |
| 309 Expect.equals(1, collector.errors.length); | 304 Expect.equals(1, collector.errors.length); |
| 310 Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE, | 305 Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE, |
| 311 collector.errors.first.message.kind); | 306 collector.errors.first.message.kind); |
| 312 }), | 307 }), |
| 313 ]); | 308 ]); |
| 314 } | 309 } |
| 315 | 310 |
| 316 Future testLocalsOne() { | 311 Future testLocalsOne() { |
| 317 return Future.forEach([ | 312 return Future.forEach([ |
| 318 () => testLocals([["foo", false]]), | 313 () => testLocals([ |
| 319 () => testLocals([["foo", false], ["bar", false]]), | 314 ["foo", false] |
| 320 () => testLocals([["foo", false], ["bar", false], ["foobar", false]]), | 315 ]), |
| 321 | 316 () => testLocals([ |
| 322 () => testLocals([["foo", true]]), | 317 ["foo", false], |
| 323 () => testLocals([["foo", false], ["bar", true]]), | 318 ["bar", false] |
| 324 () => testLocals([["foo", true], ["bar", true]]), | 319 ]), |
| 325 | 320 () => testLocals([ |
| 326 () => testLocals([["foo", false], ["bar", false], ["foobar", true]]), | 321 ["foo", false], |
| 327 () => testLocals([["foo", false], ["bar", true], ["foobar", true]]), | 322 ["bar", false], |
| 328 () => testLocals([["foo", true], ["bar", true], ["foobar", true]]), | 323 ["foobar", false] |
| 329 | 324 ]), |
| 330 () => testLocals([["foo", false], ["foo", false]]) | 325 () => testLocals([ |
| 331 .then((MockCompiler compiler) { | 326 ["foo", true] |
| 332 DiagnosticCollector collector = compiler.diagnosticCollector; | 327 ]), |
| 333 Expect.equals(1, collector.errors.length); | 328 () => testLocals([ |
| 334 Expect.equals( | 329 ["foo", false], |
| 335 new Message( | 330 ["bar", true] |
| 336 MessageTemplate.TEMPLATES[MessageKind.DUPLICATE_DEFINITION], | 331 ]), |
| 337 {'name': 'foo'}, false), | 332 () => testLocals([ |
| 338 collector.errors.first.message); | 333 ["foo", true], |
| 339 })], (f) => f()); | 334 ["bar", true] |
| 335 ]), |
| 336 () => testLocals([ |
| 337 ["foo", false], |
| 338 ["bar", false], |
| 339 ["foobar", true] |
| 340 ]), |
| 341 () => testLocals([ |
| 342 ["foo", false], |
| 343 ["bar", true], |
| 344 ["foobar", true] |
| 345 ]), |
| 346 () => testLocals([ |
| 347 ["foo", true], |
| 348 ["bar", true], |
| 349 ["foobar", true] |
| 350 ]), |
| 351 () => testLocals([ |
| 352 ["foo", false], |
| 353 ["foo", false] |
| 354 ]).then((MockCompiler compiler) { |
| 355 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 356 Expect.equals(1, collector.errors.length); |
| 357 Expect.equals( |
| 358 new Message( |
| 359 MessageTemplate.TEMPLATES[MessageKind.DUPLICATE_DEFINITION], |
| 360 {'name': 'foo'}, |
| 361 false), |
| 362 collector.errors.first.message); |
| 363 }) |
| 364 ], (f) => f()); |
| 340 } | 365 } |
| 341 | 366 |
| 342 | |
| 343 Future testLocalsTwo() { | 367 Future testLocalsTwo() { |
| 344 return MockCompiler.create((MockCompiler compiler) { | 368 return MockCompiler.create((MockCompiler compiler) { |
| 345 ResolverVisitor visitor = compiler.resolverVisitor(); | 369 ResolverVisitor visitor = compiler.resolverVisitor(); |
| 346 Node tree = parseStatement("if (true) { var a = 1; var b = 2; }"); | 370 Node tree = parseStatement("if (true) { var a = 1; var b = 2; }"); |
| 347 ResolutionResult result = visitor.visit(tree); | 371 ResolutionResult result = visitor.visit(tree); |
| 348 Expect.equals(const NoneResult(), result); | 372 Expect.equals(const NoneResult(), result); |
| 349 MethodScope scope = visitor.scope; | 373 MethodScope scope = visitor.scope; |
| 350 Expect.equals(0, scope.elements.length); | 374 Expect.equals(0, scope.elements.length); |
| 351 Expect.equals(2, map(visitor).length); | 375 Expect.equals(2, map(visitor).length); |
| 352 | 376 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 ResolutionResult result = visitor.visit(tree); | 415 ResolutionResult result = visitor.visit(tree); |
| 392 Expect.equals(const NoneResult(), result); | 416 Expect.equals(const NoneResult(), result); |
| 393 MethodScope scope = visitor.scope; | 417 MethodScope scope = visitor.scope; |
| 394 Expect.equals(0, scope.elements.length); | 418 Expect.equals(0, scope.elements.length); |
| 395 Expect.equals(4, map(visitor).length); | 419 Expect.equals(4, map(visitor).length); |
| 396 | 420 |
| 397 Block thenPart = tree.thenPart; | 421 Block thenPart = tree.thenPart; |
| 398 List statements1 = thenPart.statements.nodes.toList(); | 422 List statements1 = thenPart.statements.nodes.toList(); |
| 399 Node def1 = statements1[0].definitions.nodes.head; | 423 Node def1 = statements1[0].definitions.nodes.head; |
| 400 Node id1 = statements1[1].expression; | 424 Node id1 = statements1[1].expression; |
| 401 Expect.equals(visitor.registry.mapping[def1], | 425 Expect.equals( |
| 402 visitor.registry.mapping[id1]); | 426 visitor.registry.mapping[def1], visitor.registry.mapping[id1]); |
| 403 | 427 |
| 404 Block elsePart = tree.elsePart; | 428 Block elsePart = tree.elsePart; |
| 405 List statements2 = elsePart.statements.nodes.toList(); | 429 List statements2 = elsePart.statements.nodes.toList(); |
| 406 Node def2 = statements2[0].definitions.nodes.head; | 430 Node def2 = statements2[0].definitions.nodes.head; |
| 407 Node id2 = statements2[1].expression; | 431 Node id2 = statements2[1].expression; |
| 408 Expect.equals(visitor.registry.mapping[def2], | 432 Expect.equals( |
| 409 visitor.registry.mapping[id2]); | 433 visitor.registry.mapping[def2], visitor.registry.mapping[id2]); |
| 410 | 434 |
| 411 Expect.notEquals(visitor.registry.mapping[def1], | 435 Expect.notEquals( |
| 412 visitor.registry.mapping[def2]); | 436 visitor.registry.mapping[def1], visitor.registry.mapping[def2]); |
| 413 Expect.notEquals(visitor.registry.mapping[id1], | 437 Expect.notEquals( |
| 414 visitor.registry.mapping[id2]); | 438 visitor.registry.mapping[id1], visitor.registry.mapping[id2]); |
| 415 }); | 439 }); |
| 416 } | 440 } |
| 417 | 441 |
| 418 Future testParametersOne() { | 442 Future testParametersOne() { |
| 419 return MockCompiler.create((MockCompiler compiler) { | 443 return MockCompiler.create((MockCompiler compiler) { |
| 420 ResolverVisitor visitor = compiler.resolverVisitor(); | 444 ResolverVisitor visitor = compiler.resolverVisitor(); |
| 421 FunctionExpression tree = | 445 FunctionExpression tree = |
| 422 parseFunction("void foo(int a) { return a; }", compiler); | 446 parseFunction("void foo(int a) { return a; }", compiler); |
| 423 visitor.visit(tree); | 447 visitor.visit(tree); |
| 424 | 448 |
| 425 // Check that an element has been created for the parameter. | 449 // Check that an element has been created for the parameter. |
| 426 VariableDefinitions vardef = tree.parameters.nodes.head; | 450 VariableDefinitions vardef = tree.parameters.nodes.head; |
| 427 Node param = vardef.definitions.nodes.head; | 451 Node param = vardef.definitions.nodes.head; |
| 428 Expect.equals(ElementKind.PARAMETER, visitor.registry.mapping[param].kind); | 452 Expect.equals(ElementKind.PARAMETER, visitor.registry.mapping[param].kind); |
| 429 | 453 |
| 430 // Check that 'a' in 'return a' is resolved to the parameter. | 454 // Check that 'a' in 'return a' is resolved to the parameter. |
| 431 Block body = tree.body; | 455 Block body = tree.body; |
| 432 Return ret = body.statements.nodes.head; | 456 Return ret = body.statements.nodes.head; |
| 433 Send use = ret.expression; | 457 Send use = ret.expression; |
| 434 Expect.equals(ElementKind.PARAMETER, visitor.registry.mapping[use].kind); | 458 Expect.equals(ElementKind.PARAMETER, visitor.registry.mapping[use].kind); |
| 435 Expect.equals(visitor.registry.mapping[param], | 459 Expect.equals( |
| 436 visitor.registry.mapping[use]); | 460 visitor.registry.mapping[param], visitor.registry.mapping[use]); |
| 437 }); | 461 }); |
| 438 } | 462 } |
| 439 | 463 |
| 440 Future testFor() { | 464 Future testFor() { |
| 441 return MockCompiler.create((MockCompiler compiler) { | 465 return MockCompiler.create((MockCompiler compiler) { |
| 442 ResolverVisitor visitor = compiler.resolverVisitor(); | 466 ResolverVisitor visitor = compiler.resolverVisitor(); |
| 443 For tree = parseStatement("for (int i = 0; i < 10; i = i + 1) { i = 5; }"); | 467 For tree = parseStatement("for (int i = 0; i < 10; i = i + 1) { i = 5; }"); |
| 444 visitor.visit(tree); | 468 visitor.visit(tree); |
| 445 | 469 |
| 446 MethodScope scope = visitor.scope; | 470 MethodScope scope = visitor.scope; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 }); | 503 }); |
| 480 } | 504 } |
| 481 | 505 |
| 482 checkIdentifier(Element expected, Node node, Element actual) { | 506 checkIdentifier(Element expected, Node node, Element actual) { |
| 483 Expect.isTrue(node is Identifier, node.toDebugString()); | 507 Expect.isTrue(node is Identifier, node.toDebugString()); |
| 484 Expect.equals(expected, actual); | 508 Expect.equals(expected, actual); |
| 485 } | 509 } |
| 486 | 510 |
| 487 checkSend(Element expected, Node node, Element actual) { | 511 checkSend(Element expected, Node node, Element actual) { |
| 488 Expect.isTrue(node is Send, node.toDebugString()); | 512 Expect.isTrue(node is Send, node.toDebugString()); |
| 489 Expect.isTrue(node is !SendSet, node.toDebugString()); | 513 Expect.isTrue(node is! SendSet, node.toDebugString()); |
| 490 Expect.equals(expected, actual); | 514 Expect.equals(expected, actual); |
| 491 } | 515 } |
| 492 | 516 |
| 493 checkSendSet(Element expected, Node node, Element actual) { | 517 checkSendSet(Element expected, Node node, Element actual) { |
| 494 Expect.isTrue(node is SendSet, node.toDebugString()); | 518 Expect.isTrue(node is SendSet, node.toDebugString()); |
| 495 Expect.equals(expected, actual); | 519 Expect.equals(expected, actual); |
| 496 } | 520 } |
| 497 | 521 |
| 498 Future testTypeAnnotation() { | 522 Future testTypeAnnotation() { |
| 499 return MockCompiler.create((MockCompiler compiler) { | 523 return MockCompiler.create((MockCompiler compiler) { |
| 500 String statement = "Foo bar;"; | 524 String statement = "Foo bar;"; |
| 501 | 525 |
| 502 // Test that we get a warning when Foo is not defined. | 526 // Test that we get a warning when Foo is not defined. |
| 503 Map mapping = compiler.resolveStatement(statement).map; | 527 Map mapping = compiler.resolveStatement(statement).map; |
| 504 | 528 |
| 505 Expect.equals(1, mapping.length); // Only [bar] has an element. | 529 Expect.equals(1, mapping.length); // Only [bar] has an element. |
| 506 DiagnosticCollector collector = compiler.diagnosticCollector; | 530 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 507 Expect.equals(1, collector.warnings.length); | 531 Expect.equals(1, collector.warnings.length); |
| 508 | 532 |
| 509 Expect.equals( | 533 Expect.equals( |
| 510 new Message( | 534 new Message(MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], |
| 511 MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], | |
| 512 {'typeName': 'Foo'}, false), | 535 {'typeName': 'Foo'}, false), |
| 513 collector.warnings.first.message); | 536 collector.warnings.first.message); |
| 514 collector.clear(); | 537 collector.clear(); |
| 515 | 538 |
| 516 // Test that there is no warning after defining Foo. | 539 // Test that there is no warning after defining Foo. |
| 517 compiler.parseScript("class Foo {}"); | 540 compiler.parseScript("class Foo {}"); |
| 518 mapping = compiler.resolveStatement(statement).map; | 541 mapping = compiler.resolveStatement(statement).map; |
| 519 Expect.equals(1, mapping.length); | 542 Expect.equals(1, mapping.length); |
| 520 Expect.equals(0, collector.warnings.length); | 543 Expect.equals(0, collector.warnings.length); |
| 521 | 544 |
| 522 // Test that 'var' does not create a warning. | 545 // Test that 'var' does not create a warning. |
| 523 mapping = compiler.resolveStatement("var foo;").map; | 546 mapping = compiler.resolveStatement("var foo;").map; |
| 524 Expect.equals(1, mapping.length); | 547 Expect.equals(1, mapping.length); |
| 525 Expect.equals(0, collector.warnings.length); | 548 Expect.equals(0, collector.warnings.length); |
| 526 }); | 549 }); |
| 527 } | 550 } |
| 528 | 551 |
| 529 Future testSuperclass() { | 552 Future testSuperclass() { |
| 530 return Future.wait([ | 553 return Future.wait([ |
| 531 MockCompiler.create((MockCompiler compiler) { | 554 MockCompiler.create((MockCompiler compiler) { |
| 532 compiler.parseScript("class Foo extends Bar {}"); | 555 compiler.parseScript("class Foo extends Bar {}"); |
| 533 compiler.resolveStatement("Foo bar;"); | 556 compiler.resolveStatement("Foo bar;"); |
| 534 DiagnosticCollector collector = compiler.diagnosticCollector; | 557 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 535 Expect.equals(1, collector.errors.length); | 558 Expect.equals(1, collector.errors.length); |
| 536 var cannotResolveBar = new Message( | 559 var cannotResolveBar = new Message( |
| 537 MessageTemplate.TEMPLATES[MessageKind.CANNOT_EXTEND_MALFORMED], | 560 MessageTemplate.TEMPLATES[MessageKind.CANNOT_EXTEND_MALFORMED], |
| 538 {'className': 'Foo', 'malformedType': 'Bar'}, false); | 561 {'className': 'Foo', 'malformedType': 'Bar'}, |
| 562 false); |
| 539 Expect.equals(cannotResolveBar, collector.errors.first.message); | 563 Expect.equals(cannotResolveBar, collector.errors.first.message); |
| 540 collector.clear(); | 564 collector.clear(); |
| 541 }), | 565 }), |
| 542 MockCompiler.create((MockCompiler compiler) { | 566 MockCompiler.create((MockCompiler compiler) { |
| 543 compiler.parseScript("class Foo extends Bar {}"); | 567 compiler.parseScript("class Foo extends Bar {}"); |
| 544 compiler.parseScript("class Bar {}"); | 568 compiler.parseScript("class Bar {}"); |
| 545 Map mapping = compiler.resolveStatement("Foo bar;").map; | 569 Map mapping = compiler.resolveStatement("Foo bar;").map; |
| 546 Expect.equals(1, mapping.length); | 570 Expect.equals(1, mapping.length); |
| 547 | 571 |
| 548 ClassElement fooElement = compiler.mainApp.find('Foo'); | 572 ClassElement fooElement = compiler.mainApp.find('Foo'); |
| 549 ClassElement barElement = compiler.mainApp.find('Bar'); | 573 ClassElement barElement = compiler.mainApp.find('Bar'); |
| 550 Expect.equals(barElement.computeType(compiler.resolution), | 574 Expect.equals( |
| 551 fooElement.supertype); | 575 barElement.computeType(compiler.resolution), fooElement.supertype); |
| 552 Expect.isTrue(fooElement.interfaces.isEmpty); | 576 Expect.isTrue(fooElement.interfaces.isEmpty); |
| 553 Expect.isTrue(barElement.interfaces.isEmpty); | 577 Expect.isTrue(barElement.interfaces.isEmpty); |
| 554 }), | 578 }), |
| 555 ]); | 579 ]); |
| 556 } | 580 } |
| 557 | 581 |
| 558 Future testVarSuperclass() { | 582 Future testVarSuperclass() { |
| 559 return MockCompiler.create((MockCompiler compiler) { | 583 return MockCompiler.create((MockCompiler compiler) { |
| 560 compiler.parseScript("class Foo extends var {}"); | 584 compiler.parseScript("class Foo extends var {}"); |
| 561 compiler.resolveStatement("Foo bar;"); | 585 compiler.resolveStatement("Foo bar;"); |
| 562 DiagnosticCollector collector = compiler.diagnosticCollector; | 586 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 563 Expect.equals(1, collector.errors.length); | 587 Expect.equals(1, collector.errors.length); |
| 564 Expect.equals( | 588 Expect.equals( |
| 565 new Message( | 589 new Message(MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], |
| 566 MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], | |
| 567 {'typeName': 'var'}, false), | 590 {'typeName': 'var'}, false), |
| 568 collector.errors.first.message); | 591 collector.errors.first.message); |
| 569 collector.clear(); | 592 collector.clear(); |
| 570 }); | 593 }); |
| 571 } | 594 } |
| 572 | 595 |
| 573 Future testOneInterface() { | 596 Future testOneInterface() { |
| 574 return MockCompiler.create((MockCompiler compiler) { | 597 return MockCompiler.create((MockCompiler compiler) { |
| 575 compiler.parseScript("class Foo implements Bar {}"); | 598 compiler.parseScript("class Foo implements Bar {}"); |
| 576 compiler.resolveStatement("Foo bar;"); | 599 compiler.resolveStatement("Foo bar;"); |
| 577 DiagnosticCollector collector = compiler.diagnosticCollector; | 600 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 578 Expect.equals(1, collector.errors.length); | 601 Expect.equals(1, collector.errors.length); |
| 579 Expect.equals( | 602 Expect.equals( |
| 580 new Message( | 603 new Message(MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], |
| 581 MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], | |
| 582 {'typeName': 'bar'}, false), | 604 {'typeName': 'bar'}, false), |
| 583 collector.errors.first.message); | 605 collector.errors.first.message); |
| 584 collector.clear(); | 606 collector.clear(); |
| 585 | 607 |
| 586 // Add the abstract class to the world and make sure everything is setup | 608 // Add the abstract class to the world and make sure everything is setup |
| 587 // correctly. | 609 // correctly. |
| 588 compiler.parseScript("abstract class Bar {}"); | 610 compiler.parseScript("abstract class Bar {}"); |
| 589 | 611 |
| 590 ResolverVisitor visitor = new ResolverVisitor( | 612 ResolverVisitor visitor = new ResolverVisitor( |
| 591 compiler, | 613 compiler.resolution, |
| 592 null, | 614 null, |
| 593 new ResolutionRegistry(compiler, new CollectingTreeElements(null))); | 615 new ResolutionRegistry( |
| 616 compiler.backend, |
| 617 new CollectingTreeElements(null))); |
| 594 compiler.resolveStatement("Foo bar;"); | 618 compiler.resolveStatement("Foo bar;"); |
| 595 | 619 |
| 596 ClassElement fooElement = compiler.mainApp.find('Foo'); | 620 ClassElement fooElement = compiler.mainApp.find('Foo'); |
| 597 ClassElement barElement = compiler.mainApp.find('Bar'); | 621 ClassElement barElement = compiler.mainApp.find('Bar'); |
| 598 | 622 |
| 599 Expect.equals(null, barElement.supertype); | 623 Expect.equals(null, barElement.supertype); |
| 600 Expect.isTrue(barElement.interfaces.isEmpty); | 624 Expect.isTrue(barElement.interfaces.isEmpty); |
| 601 | 625 |
| 602 Expect.equals(barElement.computeType(compiler.resolution), | 626 Expect.equals(barElement.computeType(compiler.resolution), |
| 603 fooElement.interfaces.head); | 627 fooElement.interfaces.head); |
| 604 Expect.equals(1, length(fooElement.interfaces)); | 628 Expect.equals(1, length(fooElement.interfaces)); |
| 605 }); | 629 }); |
| 606 } | 630 } |
| 607 | 631 |
| 608 Future testTwoInterfaces() { | 632 Future testTwoInterfaces() { |
| 609 return MockCompiler.create((MockCompiler compiler) { | 633 return MockCompiler.create((MockCompiler compiler) { |
| 610 compiler.parseScript( | 634 compiler.parseScript("""abstract class I1 {} |
| 611 """abstract class I1 {} | |
| 612 abstract class I2 {} | 635 abstract class I2 {} |
| 613 class C implements I1, I2 {}"""); | 636 class C implements I1, I2 {}"""); |
| 614 compiler.resolveStatement("Foo bar;"); | 637 compiler.resolveStatement("Foo bar;"); |
| 615 | 638 |
| 616 ClassElement c = compiler.mainApp.find('C'); | 639 ClassElement c = compiler.mainApp.find('C'); |
| 617 ClassElement i1 = compiler.mainApp.find('I1'); | 640 ClassElement i1 = compiler.mainApp.find('I1'); |
| 618 ClassElement i2 = compiler.mainApp.find('I2'); | 641 ClassElement i2 = compiler.mainApp.find('I2'); |
| 619 | 642 |
| 620 Expect.equals(2, length(c.interfaces)); | 643 Expect.equals(2, length(c.interfaces)); |
| 621 Expect.equals(i1.computeType(compiler.resolution), at(c.interfaces, 0)); | 644 Expect.equals(i1.computeType(compiler.resolution), at(c.interfaces, 0)); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 VariableDefinitions bNode = | 707 VariableDefinitions bNode = |
| 685 bElement.variables.parseNode(bElement, compiler.parsingContext); | 708 bElement.variables.parseNode(bElement, compiler.parsingContext); |
| 686 VariableDefinitions cNode = | 709 VariableDefinitions cNode = |
| 687 cElement.variables.parseNode(cElement, compiler.parsingContext); | 710 cElement.variables.parseNode(cElement, compiler.parsingContext); |
| 688 Expect.equals(bNode, cNode); | 711 Expect.equals(bNode, cNode); |
| 689 Expect.isNull(bNode.type); | 712 Expect.isNull(bNode.type); |
| 690 Expect.isTrue(bNode.modifiers.isVar); | 713 Expect.isTrue(bNode.modifiers.isVar); |
| 691 }); | 714 }); |
| 692 } | 715 } |
| 693 | 716 |
| 694 Future resolveConstructor( | 717 Future resolveConstructor(String script, String statement, String className, |
| 695 String script, String statement, String className, | |
| 696 String constructor, int expectedElementCount, | 718 String constructor, int expectedElementCount, |
| 697 {List expectedWarnings: const [], | 719 {List expectedWarnings: const [], |
| 698 List expectedErrors: const [], | 720 List expectedErrors: const [], |
| 699 List expectedInfos: const [], | 721 List expectedInfos: const [], |
| 700 Map<String, String> corelib}) { | 722 Map<String, String> corelib}) { |
| 701 MockCompiler compiler = new MockCompiler.internal(coreSource: corelib); | 723 MockCompiler compiler = new MockCompiler.internal(coreSource: corelib); |
| 702 return compiler.init().then((_) { | 724 return compiler.init().then((_) { |
| 703 compiler.parseScript(script); | 725 compiler.parseScript(script); |
| 704 compiler.resolveStatement(statement); | 726 compiler.resolveStatement(statement); |
| 705 ClassElement classElement = compiler.mainApp.find(className); | 727 ClassElement classElement = compiler.mainApp.find(className); |
| 706 Element element; | 728 Element element; |
| 707 element = classElement.lookupConstructor(constructor); | 729 element = classElement.lookupConstructor(constructor); |
| 708 FunctionExpression tree = (element as FunctionElement).node; | 730 FunctionExpression tree = (element as FunctionElement).node; |
| 709 ResolverVisitor visitor = new ResolverVisitor( | 731 ResolverVisitor visitor = |
| 710 compiler, | 732 new ResolverVisitor(compiler.resolution, element, |
| 711 element, | 733 new ResolutionRegistry( |
| 712 new ResolutionRegistry(compiler, new CollectingTreeElements(element)), | 734 compiler.backend, |
| 713 scope: classElement.buildScope()); | 735 new CollectingTreeElements(element)), |
| 736 scope: classElement.buildScope()); |
| 714 new InitializerResolver(visitor, element, tree).resolveInitializers(); | 737 new InitializerResolver(visitor, element, tree).resolveInitializers(); |
| 715 visitor.visit(tree.body); | 738 visitor.visit(tree.body); |
| 716 Expect.equals(expectedElementCount, map(visitor).length, | 739 Expect.equals(expectedElementCount, map(visitor).length, |
| 717 "${map(visitor).values} for '$statement' in context of `$script`"); | 740 "${map(visitor).values} for '$statement' in context of `$script`"); |
| 718 | 741 |
| 719 DiagnosticCollector collector = compiler.diagnosticCollector; | 742 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 720 compareWarningKinds(script, expectedWarnings, collector.warnings); | 743 compareWarningKinds(script, expectedWarnings, collector.warnings); |
| 721 compareWarningKinds(script, expectedErrors, collector.errors); | 744 compareWarningKinds(script, expectedErrors, collector.errors); |
| 722 compareWarningKinds(script, expectedInfos, collector.infos); | 745 compareWarningKinds(script, expectedInfos, collector.infos); |
| 723 }); | 746 }); |
| 724 } | 747 } |
| 725 | 748 |
| 726 Future testClassHierarchy() { | 749 Future testClassHierarchy() { |
| 727 final MAIN = "main"; | 750 final MAIN = "main"; |
| 728 return Future.wait([ | 751 return Future.wait([ |
| 729 MockCompiler.create((MockCompiler compiler) { | 752 MockCompiler.create((MockCompiler compiler) { |
| 730 compiler.parseScript("""class A extends A {} | 753 compiler.parseScript("""class A extends A {} |
| 731 main() { return new A(); }"""); | 754 main() { return new A(); }"""); |
| 732 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 755 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 733 compiler.resolver.resolve(mainElement); | 756 compiler.resolver.resolve(mainElement); |
| 734 DiagnosticCollector collector = compiler.diagnosticCollector; | 757 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 735 Expect.equals(0, collector.warnings.length); | 758 Expect.equals(0, collector.warnings.length); |
| 736 Expect.equals(1, collector.errors.length); | 759 Expect.equals(1, collector.errors.length); |
| 737 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, | 760 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, |
| 738 collector.errors.first.message.kind); | 761 collector.errors.first.message.kind); |
| 739 }), | 762 }), |
| 740 MockCompiler.create((MockCompiler compiler) { | 763 MockCompiler.create((MockCompiler compiler) { |
| 741 compiler.parseScript("""class A extends B {} | 764 compiler.parseScript("""class A extends B {} |
| 742 class B extends A {} | 765 class B extends A {} |
| 743 main() { return new A(); }"""); | 766 main() { return new A(); }"""); |
| 744 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 767 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 745 compiler.resolver.resolve(mainElement); | 768 compiler.resolver.resolve(mainElement); |
| 746 DiagnosticCollector collector = compiler.diagnosticCollector; | 769 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 747 Expect.equals(0, collector.warnings.length); | 770 Expect.equals(0, collector.warnings.length); |
| 748 Expect.equals(2, collector.errors.length); | 771 Expect.equals(2, collector.errors.length); |
| 749 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, | 772 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, |
| 750 collector.errors.first.message.kind); | 773 collector.errors.first.message.kind); |
| 751 Expect.equals(MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR, | 774 Expect.equals(MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR, |
| 752 collector.errors.elementAt(1).message.kind); | 775 collector.errors.elementAt(1).message.kind); |
| 753 }), | 776 }), |
| 754 MockCompiler.create((MockCompiler compiler) { | 777 MockCompiler.create((MockCompiler compiler) { |
| 755 compiler.parseScript("""abstract class A extends B {} | 778 compiler.parseScript("""abstract class A extends B {} |
| 756 abstract class B extends A {} | 779 abstract class B extends A {} |
| 757 class C implements A {} | 780 class C implements A {} |
| 758 main() { return new C(); }"""); | 781 main() { return new C(); }"""); |
| 759 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 782 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 760 compiler.resolver.resolve(mainElement); | 783 compiler.resolver.resolve(mainElement); |
| 761 DiagnosticCollector collector = compiler.diagnosticCollector; | 784 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 762 Expect.equals(0, collector.warnings.length); | 785 Expect.equals(0, collector.warnings.length); |
| 763 Expect.equals(1, collector.errors.length); | 786 Expect.equals(1, collector.errors.length); |
| 764 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, | 787 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, |
| 765 collector.errors.first.message.kind); | 788 collector.errors.first.message.kind); |
| 766 }), | 789 }), |
| 767 MockCompiler.create((MockCompiler compiler) { | 790 MockCompiler.create((MockCompiler compiler) { |
| 768 compiler.parseScript("""class A extends B {} | 791 compiler.parseScript("""class A extends B {} |
| 769 class B extends C {} | 792 class B extends C {} |
| 770 class C {} | 793 class C {} |
| 771 main() { return new A(); }"""); | 794 main() { return new A(); }"""); |
| 772 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 795 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 773 compiler.resolver.resolve(mainElement); | 796 compiler.resolver.resolve(mainElement); |
| 774 DiagnosticCollector collector = compiler.diagnosticCollector; | 797 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 775 Expect.equals(0, collector.warnings.length); | 798 Expect.equals(0, collector.warnings.length); |
| 776 Expect.equals(0, collector.errors.length); | 799 Expect.equals(0, collector.errors.length); |
| 777 ClassElement aElement = compiler.mainApp.find("A"); | 800 ClassElement aElement = compiler.mainApp.find("A"); |
| 778 Link<DartType> supertypes = aElement.allSupertypes; | 801 Link<DartType> supertypes = aElement.allSupertypes; |
| 779 Expect.equals(<String>['B', 'C', 'Object'].toString(), | 802 Expect.equals(<String>['B', 'C', 'Object'].toString(), |
| 780 asSortedStrings(supertypes).toString()); | 803 asSortedStrings(supertypes).toString()); |
| 781 }), | 804 }), |
| 782 MockCompiler.create((MockCompiler compiler) { | 805 MockCompiler.create((MockCompiler compiler) { |
| 783 compiler.parseScript("""class A<T> {} | 806 compiler.parseScript("""class A<T> {} |
| 784 class B<Z,W> extends A<int> | 807 class B<Z,W> extends A<int> |
| 785 implements I<Z,List<W>> {} | 808 implements I<Z,List<W>> {} |
| 786 class I<X,Y> {} | 809 class I<X,Y> {} |
| 787 class C extends B<bool,String> {} | 810 class C extends B<bool,String> {} |
| 788 main() { return new C(); }"""); | 811 main() { return new C(); }"""); |
| 789 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 812 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 790 compiler.resolver.resolve(mainElement); | 813 compiler.resolver.resolve(mainElement); |
| 791 DiagnosticCollector collector = compiler.diagnosticCollector; | 814 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 792 Expect.equals(0, collector.warnings.length); | 815 Expect.equals(0, collector.warnings.length); |
| 793 Expect.equals(0, collector.errors.length); | 816 Expect.equals(0, collector.errors.length); |
| 794 ClassElement aElement = compiler.mainApp.find("C"); | 817 ClassElement aElement = compiler.mainApp.find("C"); |
| 795 Link<DartType> supertypes = aElement.allSupertypes; | 818 Link<DartType> supertypes = aElement.allSupertypes; |
| 796 // Object is once per inheritance path, that is from both A and I. | 819 // Object is once per inheritance path, that is from both A and I. |
| 797 Expect.equals(<String>['A<int>', 'B<bool, String>', | 820 Expect.equals( |
| 798 'I<bool, List<String>>', 'Object'].toString(), | 821 <String>[ |
| 799 asSortedStrings(supertypes).toString()); | 822 'A<int>', |
| 823 'B<bool, String>', |
| 824 'I<bool, List<String>>', |
| 825 'Object' |
| 826 ].toString(), |
| 827 asSortedStrings(supertypes).toString()); |
| 800 }), | 828 }), |
| 801 MockCompiler.create((MockCompiler compiler) { | 829 MockCompiler.create((MockCompiler compiler) { |
| 802 compiler.parseScript("""class A<T> {} | 830 compiler.parseScript("""class A<T> {} |
| 803 class D extends A<E> {} | 831 class D extends A<E> {} |
| 804 class E extends D {} | 832 class E extends D {} |
| 805 main() { return new E(); }"""); | 833 main() { return new E(); }"""); |
| 806 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 834 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 807 compiler.resolver.resolve(mainElement); | 835 compiler.resolver.resolve(mainElement); |
| 808 DiagnosticCollector collector = compiler.diagnosticCollector; | 836 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 809 Expect.equals(0, collector.warnings.length); | 837 Expect.equals(0, collector.warnings.length); |
| 810 Expect.equals(0, collector.errors.length); | 838 Expect.equals(0, collector.errors.length); |
| 811 ClassElement aElement = compiler.mainApp.find("E"); | 839 ClassElement aElement = compiler.mainApp.find("E"); |
| 812 Link<DartType> supertypes = aElement.allSupertypes; | 840 Link<DartType> supertypes = aElement.allSupertypes; |
| 813 Expect.equals(<String>['A<E>', 'D', 'Object'].toString(), | 841 Expect.equals(<String>['A<E>', 'D', 'Object'].toString(), |
| 814 asSortedStrings(supertypes).toString()); | 842 asSortedStrings(supertypes).toString()); |
| 815 }), | 843 }), |
| 816 MockCompiler.create((MockCompiler compiler) { | 844 MockCompiler.create((MockCompiler compiler) { |
| 817 compiler.parseScript("""class A<T> {} | 845 compiler.parseScript("""class A<T> {} |
| 818 class D extends A<int> implements A<double> {} | 846 class D extends A<int> implements A<double> {} |
| 819 main() { return new D(); }"""); | 847 main() { return new D(); }"""); |
| 820 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 848 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 821 compiler.resolver.resolve(mainElement); | 849 compiler.resolver.resolve(mainElement); |
| 822 DiagnosticCollector collector = compiler.diagnosticCollector; | 850 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 823 Expect.equals(0, collector.warnings.length); | 851 Expect.equals(0, collector.warnings.length); |
| 824 Expect.equals(1, collector.errors.length); | 852 Expect.equals(1, collector.errors.length); |
| 825 Expect.equals(MessageKind.MULTI_INHERITANCE, | 853 Expect.equals( |
| 826 collector.errors.first.message.kind); | 854 MessageKind.MULTI_INHERITANCE, collector.errors.first.message.kind); |
| 827 Expect.equals(0, collector.crashes.length); | 855 Expect.equals(0, collector.crashes.length); |
| 828 }), | 856 }), |
| 829 ]); | 857 ]); |
| 830 } | 858 } |
| 831 | 859 |
| 832 Future testEnumDeclaration() { | 860 Future testEnumDeclaration() { |
| 833 final MAIN = "main"; | 861 final MAIN = "main"; |
| 834 return Future.wait([ | 862 return Future.wait([ |
| 835 MockCompiler.create((MockCompiler compiler) { | 863 MockCompiler.create((MockCompiler compiler) { |
| 836 compiler.parseScript("""enum Enum {} | 864 compiler.parseScript("""enum Enum {} |
| 837 main() { Enum e; }"""); | 865 main() { Enum e; }"""); |
| 838 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 866 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 839 compiler.resolver.resolve(mainElement); | 867 compiler.resolver.resolve(mainElement); |
| 840 DiagnosticCollector collector = compiler.diagnosticCollector; | 868 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 841 Expect.equals(0, collector.warnings.length, | 869 Expect.equals(0, collector.warnings.length, |
| 842 'Unexpected warnings: ${collector.warnings}'); | 870 'Unexpected warnings: ${collector.warnings}'); |
| 843 Expect.equals(1, collector.errors.length, | 871 Expect.equals( |
| 844 'Unexpected errors: ${collector.errors}'); | 872 1, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
| 845 }), | 873 }), |
| 846 | |
| 847 MockCompiler.create((MockCompiler compiler) { | 874 MockCompiler.create((MockCompiler compiler) { |
| 848 compiler.parseScript("""enum Enum { A } | 875 compiler.parseScript("""enum Enum { A } |
| 849 main() { Enum e = Enum.A; }"""); | 876 main() { Enum e = Enum.A; }"""); |
| 850 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 877 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 851 compiler.resolver.resolve(mainElement); | 878 compiler.resolver.resolve(mainElement); |
| 852 DiagnosticCollector collector = compiler.diagnosticCollector; | 879 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 853 Expect.equals(0, collector.warnings.length, | 880 Expect.equals(0, collector.warnings.length, |
| 854 'Unexpected warnings: ${collector.warnings}'); | 881 'Unexpected warnings: ${collector.warnings}'); |
| 855 Expect.equals(0, collector.errors.length, | 882 Expect.equals( |
| 856 'Unexpected errors: ${collector.errors}'); | 883 0, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
| 857 }), | 884 }), |
| 858 | |
| 859 MockCompiler.create((MockCompiler compiler) { | 885 MockCompiler.create((MockCompiler compiler) { |
| 860 compiler.parseScript("""enum Enum { A } | 886 compiler.parseScript("""enum Enum { A } |
| 861 main() { Enum e = Enum.B; }"""); | 887 main() { Enum e = Enum.B; }"""); |
| 862 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 888 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 863 compiler.resolver.resolve(mainElement); | 889 compiler.resolver.resolve(mainElement); |
| 864 DiagnosticCollector collector = compiler.diagnosticCollector; | 890 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 865 Expect.equals(1, collector.warnings.length, | 891 Expect.equals(1, collector.warnings.length, |
| 866 'Unexpected warnings: ${collector.warnings}'); | 892 'Unexpected warnings: ${collector.warnings}'); |
| 867 Expect.equals(MessageKind.UNDEFINED_GETTER, | 893 Expect.equals( |
| 868 collector.warnings.first.message.kind); | 894 MessageKind.UNDEFINED_GETTER, collector.warnings.first.message.kind); |
| 869 Expect.equals(0, collector.errors.length, | 895 Expect.equals( |
| 870 'Unexpected errors: ${collector.errors}'); | 896 0, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
| 871 }), | 897 }), |
| 872 | |
| 873 MockCompiler.create((MockCompiler compiler) { | 898 MockCompiler.create((MockCompiler compiler) { |
| 874 compiler.parseScript("""enum Enum { A } | 899 compiler.parseScript("""enum Enum { A } |
| 875 main() { List values = Enum.values; }"""); | 900 main() { List values = Enum.values; }"""); |
| 876 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 901 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 877 compiler.resolver.resolve(mainElement); | 902 compiler.resolver.resolve(mainElement); |
| 878 DiagnosticCollector collector = compiler.diagnosticCollector; | 903 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 879 Expect.equals(0, collector.warnings.length, | 904 Expect.equals(0, collector.warnings.length, |
| 880 'Unexpected warnings: ${collector.warnings}'); | 905 'Unexpected warnings: ${collector.warnings}'); |
| 881 Expect.equals(0, collector.errors.length, | 906 Expect.equals( |
| 882 'Unexpected errors: ${collector.errors}'); | 907 0, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
| 883 }), | 908 }), |
| 884 | |
| 885 MockCompiler.create((MockCompiler compiler) { | 909 MockCompiler.create((MockCompiler compiler) { |
| 886 compiler.parseScript("""enum Enum { A } | 910 compiler.parseScript("""enum Enum { A } |
| 887 main() { new Enum(0, ''); }"""); | 911 main() { new Enum(0, ''); }"""); |
| 888 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 912 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 889 compiler.resolver.resolve(mainElement); | 913 compiler.resolver.resolve(mainElement); |
| 890 DiagnosticCollector collector = compiler.diagnosticCollector; | 914 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 891 Expect.equals(0, collector.warnings.length, | 915 Expect.equals(0, collector.warnings.length, |
| 892 'Unexpected warnings: ${collector.warnings}'); | 916 'Unexpected warnings: ${collector.warnings}'); |
| 893 Expect.equals(1, collector.errors.length, | 917 Expect.equals( |
| 894 'Unexpected errors: ${collector.errors}'); | 918 1, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
| 895 Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM, | 919 Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM, |
| 896 collector.errors.first.message.kind); | 920 collector.errors.first.message.kind); |
| 897 }), | 921 }), |
| 898 | |
| 899 MockCompiler.create((MockCompiler compiler) { | 922 MockCompiler.create((MockCompiler compiler) { |
| 900 compiler.parseScript("""enum Enum { A } | 923 compiler.parseScript("""enum Enum { A } |
| 901 main() { const Enum(0, ''); }"""); | 924 main() { const Enum(0, ''); }"""); |
| 902 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 925 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
| 903 compiler.resolver.resolve(mainElement); | 926 compiler.resolver.resolve(mainElement); |
| 904 DiagnosticCollector collector = compiler.diagnosticCollector; | 927 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 905 Expect.equals(0, collector.warnings.length, | 928 Expect.equals(0, collector.warnings.length, |
| 906 'Unexpected warnings: ${collector.warnings}'); | 929 'Unexpected warnings: ${collector.warnings}'); |
| 907 Expect.equals(1, collector.errors.length, | 930 Expect.equals( |
| 908 'Unexpected errors: ${collector.errors}'); | 931 1, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
| 909 Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM, | 932 Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM, |
| 910 collector.errors.first.message.kind); | 933 collector.errors.first.message.kind); |
| 911 }), | 934 }), |
| 912 ]); | 935 ]); |
| 913 } | 936 } |
| 914 | 937 |
| 915 Future testInitializers() { | 938 Future testInitializers() { |
| 916 return Future.forEach([ | 939 return Future.forEach([ |
| 917 () { | 940 () { |
| 918 String script = | 941 String script = """class A { |
| 919 """class A { | |
| 920 int foo; int bar; | 942 int foo; int bar; |
| 921 A() : this.foo = 1, bar = 2; | 943 A() : this.foo = 1, bar = 2; |
| 922 }"""; | 944 }"""; |
| 923 return resolveConstructor(script, "A a = new A();", "A", "", 2); | 945 return resolveConstructor(script, "A a = new A();", "A", "", 2); |
| 924 }, | 946 }, |
| 925 () { | 947 () { |
| 926 String script = | 948 String script = """class A { |
| 927 """class A { | |
| 928 int foo; A a; | 949 int foo; A a; |
| 929 A() : a.foo = 1; | 950 A() : a.foo = 1; |
| 930 }"""; | 951 }"""; |
| 931 return resolveConstructor(script, "A a = new A();", "A", "", 0, | 952 return resolveConstructor(script, "A a = new A();", "A", "", 0, |
| 932 expectedWarnings: [], | 953 expectedWarnings: [], |
| 933 expectedErrors: [MessageKind.INVALID_RECEIVER_IN_INITIALIZER]); | 954 expectedErrors: [MessageKind.INVALID_RECEIVER_IN_INITIALIZER]); |
| 934 }, | 955 }, |
| 935 () { | 956 () { |
| 936 String script = | 957 String script = """class A { |
| 937 """class A { | |
| 938 int foo; | 958 int foo; |
| 939 A() : this.foo = 1, this.foo = 2; | 959 A() : this.foo = 1, this.foo = 2; |
| 940 }"""; | 960 }"""; |
| 941 return resolveConstructor(script, "A a = new A();", "A", "", 2, | 961 return resolveConstructor(script, "A a = new A();", "A", "", 2, |
| 942 expectedInfos: [MessageKind.ALREADY_INITIALIZED], | 962 expectedInfos: [MessageKind.ALREADY_INITIALIZED], |
| 943 expectedErrors: [MessageKind.DUPLICATE_INITIALIZER]); | 963 expectedErrors: [MessageKind.DUPLICATE_INITIALIZER]); |
| 944 }, | 964 }, |
| 945 () { | 965 () { |
| 946 String script = | 966 String script = """class A { |
| 947 """class A { | |
| 948 A() : this.foo = 1; | 967 A() : this.foo = 1; |
| 949 }"""; | 968 }"""; |
| 950 return resolveConstructor(script, "A a = new A();", "A", "", 1, | 969 return resolveConstructor(script, "A a = new A();", "A", "", 1, |
| 951 expectedWarnings: [], | 970 expectedWarnings: [], expectedErrors: [MessageKind.CANNOT_RESOLVE]); |
| 952 expectedErrors: [MessageKind.CANNOT_RESOLVE]); | |
| 953 }, | 971 }, |
| 954 () { | 972 () { |
| 955 String script = | 973 String script = """class A { |
| 956 """class A { | |
| 957 int foo; | 974 int foo; |
| 958 int bar; | 975 int bar; |
| 959 A() : this.foo = bar; | 976 A() : this.foo = bar; |
| 960 }"""; | 977 }"""; |
| 961 return resolveConstructor(script, "A a = new A();", "A", "", 2, | 978 return resolveConstructor(script, "A a = new A();", "A", "", 2, |
| 962 expectedWarnings: [], | 979 expectedWarnings: [], |
| 963 expectedErrors: [MessageKind.NO_INSTANCE_AVAILABLE]); | 980 expectedErrors: [MessageKind.NO_INSTANCE_AVAILABLE]); |
| 964 }, | 981 }, |
| 965 () { | 982 () { |
| 966 String script = | 983 String script = """class A { |
| 967 """class A { | |
| 968 int foo() => 42; | 984 int foo() => 42; |
| 969 A() : foo(); | 985 A() : foo(); |
| 970 }"""; | 986 }"""; |
| 971 return resolveConstructor(script, "A a = new A();", "A", "", 0, | 987 return resolveConstructor(script, "A a = new A();", "A", "", 0, |
| 972 expectedWarnings: [], | 988 expectedWarnings: [], |
| 973 expectedErrors: [MessageKind.CONSTRUCTOR_CALL_EXPECTED]); | 989 expectedErrors: [MessageKind.CONSTRUCTOR_CALL_EXPECTED]); |
| 974 }, | 990 }, |
| 975 () { | 991 () { |
| 976 String script = | 992 String script = """class A { |
| 977 """class A { | |
| 978 int i; | 993 int i; |
| 979 A.a() : this.b(0); | 994 A.a() : this.b(0); |
| 980 A.b(int i); | 995 A.b(int i); |
| 981 }"""; | 996 }"""; |
| 982 return resolveConstructor(script, "A a = new A.a();", "A", "a", 1); | 997 return resolveConstructor(script, "A a = new A.a();", "A", "a", 1); |
| 983 }, | 998 }, |
| 984 () { | 999 () { |
| 985 String script = | 1000 String script = """class A { |
| 986 """class A { | |
| 987 int i; | 1001 int i; |
| 988 A.a() : i = 42, this(0); | 1002 A.a() : i = 42, this(0); |
| 989 A(int i); | 1003 A(int i); |
| 990 }"""; | 1004 }"""; |
| 991 return resolveConstructor(script, "A a = new A.a();", "A", "a", 2, | 1005 return resolveConstructor(script, "A a = new A.a();", "A", "a", 2, |
| 992 expectedWarnings: [], | 1006 expectedWarnings: [], |
| 993 expectedErrors: | 1007 expectedErrors: [ |
| 994 [MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER]); | 1008 MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER |
| 1009 ]); |
| 995 }, | 1010 }, |
| 996 () { | 1011 () { |
| 997 String script = | 1012 String script = """class A { |
| 998 """class A { | |
| 999 int i; | 1013 int i; |
| 1000 A(i); | 1014 A(i); |
| 1001 } | 1015 } |
| 1002 class B extends A { | 1016 class B extends A { |
| 1003 B() : super(0); | 1017 B() : super(0); |
| 1004 }"""; | 1018 }"""; |
| 1005 return resolveConstructor(script, "B a = new B();", "B", "", 1); | 1019 return resolveConstructor(script, "B a = new B();", "B", "", 1); |
| 1006 }, | 1020 }, |
| 1007 () { | 1021 () { |
| 1008 String script = | 1022 String script = """class A { |
| 1009 """class A { | |
| 1010 int i; | 1023 int i; |
| 1011 A(i); | 1024 A(i); |
| 1012 } | 1025 } |
| 1013 class B extends A { | 1026 class B extends A { |
| 1014 B() : super(0), super(1); | 1027 B() : super(0), super(1); |
| 1015 }"""; | 1028 }"""; |
| 1016 return resolveConstructor(script, "B b = new B();", "B", "", 2, | 1029 return resolveConstructor(script, "B b = new B();", "B", "", 2, |
| 1017 expectedWarnings: [], | 1030 expectedWarnings: [], |
| 1018 expectedErrors: [MessageKind.DUPLICATE_SUPER_INITIALIZER]); | 1031 expectedErrors: [MessageKind.DUPLICATE_SUPER_INITIALIZER]); |
| 1019 }, | 1032 }, |
| 1020 () { | 1033 () { |
| 1021 String script = ""; | 1034 String script = ""; |
| 1022 final INVALID_OBJECT = | 1035 final INVALID_OBJECT = const { |
| 1023 const { 'Object': 'class Object { Object() : super(); }' }; | 1036 'Object': 'class Object { Object() : super(); }' |
| 1024 return resolveConstructor(script, | 1037 }; |
| 1025 "Object o = new Object();", "Object", "", 1, | 1038 return resolveConstructor( |
| 1039 script, "Object o = new Object();", "Object", "", 1, |
| 1026 expectedWarnings: [], | 1040 expectedWarnings: [], |
| 1027 expectedErrors: [MessageKind.SUPER_INITIALIZER_IN_OBJECT], | 1041 expectedErrors: [MessageKind.SUPER_INITIALIZER_IN_OBJECT], |
| 1028 corelib: INVALID_OBJECT); | 1042 corelib: INVALID_OBJECT); |
| 1029 }, | 1043 }, |
| 1030 ], (f) => f()); | 1044 ], (f) => f()); |
| 1031 } | 1045 } |
| 1032 | 1046 |
| 1033 Future testConstantExpressions() { | 1047 Future testConstantExpressions() { |
| 1034 const Map<String, List<String>> testedConstants = const { | 1048 const Map<String, List<String>> testedConstants = const { |
| 1035 'null': const ['null'], | 1049 'null': const ['null'], |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1051 r'"a${0}b${1}"': const ['"a"', '0', '"b"', '1', '""', r'"a${0}b${1}"'], | 1065 r'"a${0}b${1}"': const ['"a"', '0', '"b"', '1', '""', r'"a${0}b${1}"'], |
| 1052 'true || false': const ['true', 'false', 'true || false'], | 1066 'true || false': const ['true', 'false', 'true || false'], |
| 1053 'true && false': const ['true', 'false', 'true && false'], | 1067 'true && false': const ['true', 'false', 'true && false'], |
| 1054 '!true': const ['true', '!true'], | 1068 '!true': const ['true', '!true'], |
| 1055 'const []': const ['const []'], | 1069 'const []': const ['const []'], |
| 1056 'const <int>[]': const ['const <int>[]'], | 1070 'const <int>[]': const ['const <int>[]'], |
| 1057 'const [0, 1, 2]': const ['0', '1', '2', 'const [0, 1, 2]'], | 1071 'const [0, 1, 2]': const ['0', '1', '2', 'const [0, 1, 2]'], |
| 1058 'const <int>[0, 1, 2]': const ['0', '1', '2', 'const <int>[0, 1, 2]'], | 1072 'const <int>[0, 1, 2]': const ['0', '1', '2', 'const <int>[0, 1, 2]'], |
| 1059 'const {}': const ['const {}'], | 1073 'const {}': const ['const {}'], |
| 1060 'const <String, int>{}': const ['const <String, int>{}'], | 1074 'const <String, int>{}': const ['const <String, int>{}'], |
| 1061 'const {"a": 0, "b": 1, "c": 2}': | 1075 'const {"a": 0, "b": 1, "c": 2}': const [ |
| 1062 const ['"a"', '0', '"b"', '1', '"c"', '2', | 1076 '"a"', |
| 1063 'const {"a": 0, "b": 1, "c": 2}'], | 1077 '0', |
| 1064 'const <String, int>{"a": 0, "b": 1, "c": 2}': | 1078 '"b"', |
| 1065 const ['"a"', '0', '"b"', '1', '"c"', '2', | 1079 '1', |
| 1066 'const <String, int>{"a": 0, "b": 1, "c": 2}'], | 1080 '"c"', |
| 1081 '2', |
| 1082 'const {"a": 0, "b": 1, "c": 2}' |
| 1083 ], |
| 1084 'const <String, int>{"a": 0, "b": 1, "c": 2}': const [ |
| 1085 '"a"', |
| 1086 '0', |
| 1087 '"b"', |
| 1088 '1', |
| 1089 '"c"', |
| 1090 '2', |
| 1091 'const <String, int>{"a": 0, "b": 1, "c": 2}' |
| 1092 ], |
| 1067 }; | 1093 }; |
| 1068 return Future.forEach(testedConstants.keys, (String constant) { | 1094 return Future.forEach(testedConstants.keys, (String constant) { |
| 1069 return MockCompiler.create((MockCompiler compiler) { | 1095 return MockCompiler.create((MockCompiler compiler) { |
| 1070 CollectingTreeElements elements = | 1096 CollectingTreeElements elements = |
| 1071 compiler.resolveStatement("main() => $constant;"); | 1097 compiler.resolveStatement("main() => $constant;"); |
| 1072 List<String> expectedConstants = testedConstants[constant]; | 1098 List<String> expectedConstants = testedConstants[constant]; |
| 1073 DiagnosticCollector collector = compiler.diagnosticCollector; | 1099 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 1074 Expect.equals(0, collector.warnings.length); | 1100 Expect.equals(0, collector.warnings.length); |
| 1075 Expect.equals(0, collector.errors.length); | 1101 Expect.equals(0, collector.errors.length); |
| 1076 List<ConstantExpression> constants = elements.constants; | 1102 List<ConstantExpression> constants = elements.constants; |
| 1077 String constantsText = | 1103 String constantsText = |
| 1078 '[${constants.map((c) => c.toDartText()).join(', ')}]'; | 1104 '[${constants.map((c) => c.toDartText()).join(', ')}]'; |
| 1079 Expect.equals(expectedConstants.length, constants.length, | 1105 Expect.equals( |
| 1106 expectedConstants.length, |
| 1107 constants.length, |
| 1080 "Expected ${expectedConstants.length} constants for `${constant}` " | 1108 "Expected ${expectedConstants.length} constants for `${constant}` " |
| 1081 "found $constantsText."); | 1109 "found $constantsText."); |
| 1082 for (int index = 0; index < expectedConstants.length; index++) { | 1110 for (int index = 0; index < expectedConstants.length; index++) { |
| 1083 Expect.equals(expectedConstants[index], constants[index].toDartText(), | 1111 Expect.equals( |
| 1112 expectedConstants[index], |
| 1113 constants[index].toDartText(), |
| 1084 "Expected ${expectedConstants} for `$constant`, " | 1114 "Expected ${expectedConstants} for `$constant`, " |
| 1085 "found $constantsText."); | 1115 "found $constantsText."); |
| 1086 } | 1116 } |
| 1087 }); | 1117 }); |
| 1088 }); | 1118 }); |
| 1089 } | 1119 } |
| 1090 | 1120 |
| 1091 map(ResolverVisitor visitor) { | 1121 map(ResolverVisitor visitor) { |
| 1092 CollectingTreeElements elements = visitor.registry.mapping; | 1122 CollectingTreeElements elements = visitor.registry.mapping; |
| 1093 return elements.map; | 1123 return elements.map; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1108 compiler.diagnosticHandler = createHandler(compiler, source); | 1138 compiler.diagnosticHandler = createHandler(compiler, source); |
| 1109 return compiler.run(uri).then((_) { | 1139 return compiler.run(uri).then((_) { |
| 1110 return compiler; | 1140 return compiler; |
| 1111 }); | 1141 }); |
| 1112 } | 1142 } |
| 1113 | 1143 |
| 1114 checkMemberResolved(compiler, className, memberName) { | 1144 checkMemberResolved(compiler, className, memberName) { |
| 1115 ClassElement cls = findElement(compiler, className); | 1145 ClassElement cls = findElement(compiler, className); |
| 1116 Element memberElement = cls.lookupLocalMember(memberName); | 1146 Element memberElement = cls.lookupLocalMember(memberName); |
| 1117 Expect.isNotNull(memberElement); | 1147 Expect.isNotNull(memberElement); |
| 1118 Expect.isTrue( | 1148 Expect.isTrue(compiler.enqueuer.resolution.hasBeenProcessed(memberElement)); |
| 1119 compiler.enqueuer.resolution.hasBeenProcessed(memberElement)); | |
| 1120 } | 1149 } |
| 1121 | 1150 |
| 1122 testToString() { | 1151 testToString() { |
| 1123 final script = r"class C { toString() => 'C'; } main() { '${new C()}'; }"; | 1152 final script = r"class C { toString() => 'C'; } main() { '${new C()}'; }"; |
| 1124 asyncTest(() => compileScript(script).then((compiler) { | 1153 asyncTest(() => compileScript(script).then((compiler) { |
| 1125 checkMemberResolved(compiler, 'C', 'toString'); | 1154 checkMemberResolved(compiler, 'C', 'toString'); |
| 1126 })); | 1155 })); |
| 1127 } | 1156 } |
| 1128 | 1157 |
| 1129 operatorName(op, isUnary) { | 1158 operatorName(op, isUnary) { |
| 1130 return Elements.constructOperatorName(op, isUnary); | 1159 return Elements.constructOperatorName(op, isUnary); |
| 1131 } | 1160 } |
| 1132 | 1161 |
| 1133 testIndexedOperator() { | 1162 testIndexedOperator() { |
| 1134 final script = r""" | 1163 final script = r""" |
| 1135 class C { | 1164 class C { |
| 1136 operator[](ix) => ix; | 1165 operator[](ix) => ix; |
| 1137 operator[]=(ix, v) {} | 1166 operator[]=(ix, v) {} |
| 1138 } | 1167 } |
| 1139 main() { var c = new C(); c[0]++; }"""; | 1168 main() { var c = new C(); c[0]++; }"""; |
| 1140 asyncTest(() => compileScript(script).then((compiler) { | 1169 asyncTest(() => compileScript(script).then((compiler) { |
| 1141 checkMemberResolved(compiler, 'C', operatorName('[]', false)); | 1170 checkMemberResolved(compiler, 'C', operatorName('[]', false)); |
| 1142 checkMemberResolved(compiler, 'C', operatorName('[]=', false)); | 1171 checkMemberResolved(compiler, 'C', operatorName('[]=', false)); |
| 1143 })); | 1172 })); |
| 1144 } | 1173 } |
| 1145 | 1174 |
| 1146 testIncrementsAndDecrements() { | 1175 testIncrementsAndDecrements() { |
| 1147 final script = r""" | 1176 final script = r""" |
| 1148 class A { operator+(o)=>null; } | 1177 class A { operator+(o)=>null; } |
| 1149 class B { operator+(o)=>null; } | 1178 class B { operator+(o)=>null; } |
| 1150 class C { operator-(o)=>null; } | 1179 class C { operator-(o)=>null; } |
| 1151 class D { operator-(o)=>null; } | 1180 class D { operator-(o)=>null; } |
| 1152 main() { | 1181 main() { |
| 1153 var a = new A(); | 1182 var a = new A(); |
| 1154 a++; | 1183 a++; |
| 1155 var b = new B(); | 1184 var b = new B(); |
| 1156 ++b; | 1185 ++b; |
| 1157 var c = new C(); | 1186 var c = new C(); |
| 1158 c--; | 1187 c--; |
| 1159 var d = new D(); | 1188 var d = new D(); |
| 1160 --d; | 1189 --d; |
| 1161 }"""; | 1190 }"""; |
| 1162 asyncTest(() => compileScript(script).then((compiler) { | 1191 asyncTest(() => compileScript(script).then((compiler) { |
| 1163 checkMemberResolved(compiler, 'A', operatorName('+', false)); | 1192 checkMemberResolved(compiler, 'A', operatorName('+', false)); |
| 1164 checkMemberResolved(compiler, 'B', operatorName('+', false)); | 1193 checkMemberResolved(compiler, 'B', operatorName('+', false)); |
| 1165 checkMemberResolved(compiler, 'C', operatorName('-', false)); | 1194 checkMemberResolved(compiler, 'C', operatorName('-', false)); |
| 1166 checkMemberResolved(compiler, 'D', operatorName('-', false)); | 1195 checkMemberResolved(compiler, 'D', operatorName('-', false)); |
| 1167 })); | 1196 })); |
| 1168 } | 1197 } |
| 1169 | 1198 |
| 1170 testOverrideHashCodeCheck() { | 1199 testOverrideHashCodeCheck() { |
| 1171 final script = r""" | 1200 final script = r""" |
| 1172 class A { | 1201 class A { |
| 1173 operator==(other) => true; | 1202 operator==(other) => true; |
| 1174 } | 1203 } |
| 1175 class B { | 1204 class B { |
| 1176 operator==(other) => true; | 1205 operator==(other) => true; |
| 1177 get hashCode => 0; | 1206 get hashCode => 0; |
| 1178 } | 1207 } |
| 1179 main() { | 1208 main() { |
| 1180 new A() == new B(); | 1209 new A() == new B(); |
| 1181 }"""; | 1210 }"""; |
| 1182 asyncTest(() => compileScript(script).then((compiler) { | 1211 asyncTest(() => compileScript(script).then((compiler) { |
| 1183 DiagnosticCollector collector = compiler.diagnosticCollector; | 1212 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 1184 Expect.equals(0, collector.warnings.length); | 1213 Expect.equals(0, collector.warnings.length); |
| 1185 Expect.equals(0, collector.infos.length); | 1214 Expect.equals(0, collector.infos.length); |
| 1186 Expect.equals(1, collector.hints.length); | 1215 Expect.equals(1, collector.hints.length); |
| 1187 Expect.equals(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, | 1216 Expect.equals(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, |
| 1188 collector.hints.first.message.kind); | 1217 collector.hints.first.message.kind); |
| 1189 Expect.equals(0, collector.errors.length); | 1218 Expect.equals(0, collector.errors.length); |
| 1190 })); | 1219 })); |
| 1191 } | 1220 } |
| 1192 | 1221 |
| 1193 testConstConstructorAndNonFinalFields() { | 1222 testConstConstructorAndNonFinalFields() { |
| 1194 void expect(compiler, List errors, List infos) { | 1223 void expect(compiler, List errors, List infos) { |
| 1195 DiagnosticCollector collector = compiler.diagnosticCollector; | 1224 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 1196 Expect.equals(errors.length, collector.errors.length); | 1225 Expect.equals(errors.length, collector.errors.length); |
| 1197 for (int i = 0 ; i < errors.length ; i++) { | 1226 for (int i = 0; i < errors.length; i++) { |
| 1198 Expect.equals(errors[i], collector.errors.elementAt(i).message.kind); | 1227 Expect.equals(errors[i], collector.errors.elementAt(i).message.kind); |
| 1199 } | 1228 } |
| 1200 Expect.equals(0, collector.warnings.length); | 1229 Expect.equals(0, collector.warnings.length); |
| 1201 Expect.equals(infos.length, collector.infos.length); | 1230 Expect.equals(infos.length, collector.infos.length); |
| 1202 for (int i = 0 ; i < infos.length ; i++) { | 1231 for (int i = 0; i < infos.length; i++) { |
| 1203 Expect.equals(infos[i], collector.infos.elementAt(i).message.kind); | 1232 Expect.equals(infos[i], collector.infos.elementAt(i).message.kind); |
| 1204 } | 1233 } |
| 1205 } | 1234 } |
| 1206 | 1235 |
| 1207 final script1 = r""" | 1236 final script1 = r""" |
| 1208 class A { | 1237 class A { |
| 1209 var a; | 1238 var a; |
| 1210 const A(this.a); | 1239 const A(this.a); |
| 1211 } | 1240 } |
| 1212 main() { | 1241 main() { |
| 1213 new A(0); | 1242 new A(0); |
| 1214 }"""; | 1243 }"""; |
| 1215 asyncTest(() => compileScript(script1).then((compiler) { | 1244 asyncTest(() => compileScript(script1).then((compiler) { |
| 1216 expect(compiler, | 1245 expect(compiler, [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS], |
| 1217 [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS], | 1246 [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD]); |
| 1218 [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD]); | 1247 })); |
| 1219 })); | |
| 1220 | 1248 |
| 1221 final script2 = r""" | 1249 final script2 = r""" |
| 1222 class A { | 1250 class A { |
| 1223 var a; | 1251 var a; |
| 1224 var b; | 1252 var b; |
| 1225 const A(this.a, this.b); | 1253 const A(this.a, this.b); |
| 1226 const A.named(this.a, this.b); | 1254 const A.named(this.a, this.b); |
| 1227 } | 1255 } |
| 1228 main() { | 1256 main() { |
| 1229 new A(0, 1); | 1257 new A(0, 1); |
| 1230 }"""; | 1258 }"""; |
| 1231 asyncTest(() => compileScript(script2).then((compiler) { | 1259 asyncTest(() => compileScript(script2).then((compiler) { |
| 1232 expect(compiler, | 1260 expect(compiler, [ |
| 1233 [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS], | 1261 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS |
| 1234 [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, | 1262 ], [ |
| 1235 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, | 1263 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, |
| 1236 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD, | 1264 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, |
| 1237 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD]); | 1265 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD, |
| 1238 })); | 1266 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD |
| 1267 ]); |
| 1268 })); |
| 1239 } | 1269 } |
| 1240 | 1270 |
| 1241 testCantAssignMethods() { | 1271 testCantAssignMethods() { |
| 1242 // Can't override local functions | 1272 // Can't override local functions |
| 1243 checkWarningOn(''' | 1273 checkWarningOn( |
| 1274 ''' |
| 1244 main() { | 1275 main() { |
| 1245 mname() { mname = 2; }; | 1276 mname() { mname = 2; }; |
| 1246 mname(); | 1277 mname(); |
| 1247 } | 1278 } |
| 1248 ''', [MessageKind.ASSIGNING_METHOD]); | 1279 ''', |
| 1280 [MessageKind.ASSIGNING_METHOD]); |
| 1249 | 1281 |
| 1250 checkWarningOn(''' | 1282 checkWarningOn( |
| 1283 ''' |
| 1251 main() { | 1284 main() { |
| 1252 mname() { }; | 1285 mname() { }; |
| 1253 mname = 3; | 1286 mname = 3; |
| 1254 } | 1287 } |
| 1255 ''', [MessageKind.ASSIGNING_METHOD]); | 1288 ''', |
| 1289 [MessageKind.ASSIGNING_METHOD]); |
| 1256 | 1290 |
| 1257 // Can't override top-level functions | 1291 // Can't override top-level functions |
| 1258 checkWarningOn(''' | 1292 checkWarningOn( |
| 1293 ''' |
| 1259 m() {} | 1294 m() {} |
| 1260 main() { m = 4; } | 1295 main() { m = 4; } |
| 1261 ''', [MessageKind.ASSIGNING_METHOD, | 1296 ''', |
| 1262 // TODO(johnniwinther): Avoid duplicate warnings. | 1297 [ |
| 1263 MessageKind.NOT_ASSIGNABLE]); | 1298 MessageKind.ASSIGNING_METHOD, |
| 1299 // TODO(johnniwinther): Avoid duplicate warnings. |
| 1300 MessageKind.NOT_ASSIGNABLE |
| 1301 ]); |
| 1264 | 1302 |
| 1265 // Can't override instance methods | 1303 // Can't override instance methods |
| 1266 checkWarningOn(''' | 1304 checkWarningOn( |
| 1305 ''' |
| 1267 main() { new B().bar(); } | 1306 main() { new B().bar(); } |
| 1268 class B { | 1307 class B { |
| 1269 mname() {} | 1308 mname() {} |
| 1270 bar() { | 1309 bar() { |
| 1271 mname = () => null; | 1310 mname = () => null; |
| 1272 } | 1311 } |
| 1273 } | 1312 } |
| 1274 ''', [MessageKind.UNDEFINED_SETTER]); | 1313 ''', |
| 1275 checkWarningOn(''' | 1314 [MessageKind.UNDEFINED_SETTER]); |
| 1315 checkWarningOn( |
| 1316 ''' |
| 1276 main() { new B().bar(); } | 1317 main() { new B().bar(); } |
| 1277 class B { | 1318 class B { |
| 1278 mname() {} | 1319 mname() {} |
| 1279 bar() { | 1320 bar() { |
| 1280 this.mname = () => null; | 1321 this.mname = () => null; |
| 1281 } | 1322 } |
| 1282 } | 1323 } |
| 1283 ''', [MessageKind.UNDEFINED_SETTER]); | 1324 ''', |
| 1325 [MessageKind.UNDEFINED_SETTER]); |
| 1284 | 1326 |
| 1285 // Can't override super methods | 1327 // Can't override super methods |
| 1286 checkWarningOn(''' | 1328 checkWarningOn( |
| 1329 ''' |
| 1287 main() { new B().bar(); } | 1330 main() { new B().bar(); } |
| 1288 class A { | 1331 class A { |
| 1289 mname() {} | 1332 mname() {} |
| 1290 } | 1333 } |
| 1291 class B extends A { | 1334 class B extends A { |
| 1292 bar() { | 1335 bar() { |
| 1293 super.mname = () => 6; | 1336 super.mname = () => 6; |
| 1294 } | 1337 } |
| 1295 } | 1338 } |
| 1296 ''', [MessageKind.ASSIGNING_METHOD_IN_SUPER, | 1339 ''', |
| 1297 // TODO(johnniwinther): Avoid duplicate warnings. | 1340 [ |
| 1298 MessageKind.UNDEFINED_SETTER]); | 1341 MessageKind.ASSIGNING_METHOD_IN_SUPER, |
| 1342 // TODO(johnniwinther): Avoid duplicate warnings. |
| 1343 MessageKind.UNDEFINED_SETTER |
| 1344 ]); |
| 1299 | 1345 |
| 1300 // But index operators should be OK | 1346 // But index operators should be OK |
| 1301 checkWarningOn(''' | 1347 checkWarningOn( |
| 1348 ''' |
| 1302 main() { new B().bar(); } | 1349 main() { new B().bar(); } |
| 1303 class B { | 1350 class B { |
| 1304 operator[]=(x, y) {} | 1351 operator[]=(x, y) {} |
| 1305 bar() { | 1352 bar() { |
| 1306 this[1] = 3; // This is OK | 1353 this[1] = 3; // This is OK |
| 1307 } | 1354 } |
| 1308 } | 1355 } |
| 1309 ''', []); | 1356 ''', |
| 1310 checkWarningOn(''' | 1357 []); |
| 1358 checkWarningOn( |
| 1359 ''' |
| 1311 main() { new B().bar(); } | 1360 main() { new B().bar(); } |
| 1312 class A { | 1361 class A { |
| 1313 operator[]=(x, y) {} | 1362 operator[]=(x, y) {} |
| 1314 } | 1363 } |
| 1315 class B extends A { | 1364 class B extends A { |
| 1316 bar() { | 1365 bar() { |
| 1317 super[1] = 3; // This is OK | 1366 super[1] = 3; // This is OK |
| 1318 } | 1367 } |
| 1319 } | 1368 } |
| 1320 ''', []); | 1369 ''', |
| 1370 []); |
| 1321 } | 1371 } |
| 1322 | 1372 |
| 1323 testCantAssignFinalAndConsts() { | 1373 testCantAssignFinalAndConsts() { |
| 1324 // Can't write final or const locals. | 1374 // Can't write final or const locals. |
| 1325 checkWarningOn(''' | 1375 checkWarningOn( |
| 1376 ''' |
| 1326 main() { | 1377 main() { |
| 1327 final x = 1; | 1378 final x = 1; |
| 1328 x = 2; | 1379 x = 2; |
| 1329 } | 1380 } |
| 1330 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | 1381 ''', |
| 1331 checkWarningOn(''' | 1382 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
| 1383 checkWarningOn( |
| 1384 ''' |
| 1332 main() { | 1385 main() { |
| 1333 const x = 1; | 1386 const x = 1; |
| 1334 x = 2; | 1387 x = 2; |
| 1335 } | 1388 } |
| 1336 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | 1389 ''', |
| 1337 checkWarningOn(''' | 1390 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
| 1391 checkWarningOn( |
| 1392 ''' |
| 1338 final x = 1; | 1393 final x = 1; |
| 1339 main() { x = 3; } | 1394 main() { x = 3; } |
| 1340 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | 1395 ''', |
| 1396 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
| 1341 | 1397 |
| 1342 checkWarningOn(''' | 1398 checkWarningOn( |
| 1399 ''' |
| 1343 const x = 1; | 1400 const x = 1; |
| 1344 main() { x = 3; } | 1401 main() { x = 3; } |
| 1345 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | 1402 ''', |
| 1403 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
| 1346 | 1404 |
| 1347 // Detect assignments to final fields: | 1405 // Detect assignments to final fields: |
| 1348 checkWarningOn(''' | 1406 checkWarningOn( |
| 1407 ''' |
| 1349 main() => new B().m(); | 1408 main() => new B().m(); |
| 1350 class B { | 1409 class B { |
| 1351 final x = 1; | 1410 final x = 1; |
| 1352 m() { x = 2; } | 1411 m() { x = 2; } |
| 1353 } | 1412 } |
| 1354 ''', [MessageKind.UNDEFINED_SETTER]); | 1413 ''', |
| 1414 [MessageKind.UNDEFINED_SETTER]); |
| 1355 | 1415 |
| 1356 // ... even if 'this' is explicit: | 1416 // ... even if 'this' is explicit: |
| 1357 checkWarningOn(''' | 1417 checkWarningOn( |
| 1418 ''' |
| 1358 main() => new B().m(); | 1419 main() => new B().m(); |
| 1359 class B { | 1420 class B { |
| 1360 final x = 1; | 1421 final x = 1; |
| 1361 m() { this.x = 2; } | 1422 m() { this.x = 2; } |
| 1362 } | 1423 } |
| 1363 ''', [MessageKind.UNDEFINED_SETTER]); | 1424 ''', |
| 1425 [MessageKind.UNDEFINED_SETTER]); |
| 1364 | 1426 |
| 1365 // ... and in super class: | 1427 // ... and in super class: |
| 1366 checkWarningOn(''' | 1428 checkWarningOn( |
| 1429 ''' |
| 1367 main() => new B().m(); | 1430 main() => new B().m(); |
| 1368 class A { | 1431 class A { |
| 1369 final x = 1; | 1432 final x = 1; |
| 1370 } | 1433 } |
| 1371 class B extends A { | 1434 class B extends A { |
| 1372 m() { super.x = 2; } | 1435 m() { super.x = 2; } |
| 1373 } | 1436 } |
| 1374 ''', [MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, | 1437 ''', |
| 1375 // TODO(johnniwinther): Avoid duplicate warnings. | 1438 [ |
| 1376 MessageKind.UNDEFINED_SETTER]); | 1439 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, |
| 1440 // TODO(johnniwinther): Avoid duplicate warnings. |
| 1441 MessageKind.UNDEFINED_SETTER |
| 1442 ]); |
| 1377 | 1443 |
| 1378 // But non-final fields are OK: | 1444 // But non-final fields are OK: |
| 1379 checkWarningOn(''' | 1445 checkWarningOn( |
| 1446 ''' |
| 1380 main() => new B().m(); | 1447 main() => new B().m(); |
| 1381 class A { | 1448 class A { |
| 1382 int x = 1; | 1449 int x = 1; |
| 1383 } | 1450 } |
| 1384 class B extends A { | 1451 class B extends A { |
| 1385 m() { super.x = 2; } | 1452 m() { super.x = 2; } |
| 1386 } | 1453 } |
| 1387 ''', []); | 1454 ''', |
| 1455 []); |
| 1388 | 1456 |
| 1389 // Check getter without setter. | 1457 // Check getter without setter. |
| 1390 checkWarningOn(''' | 1458 checkWarningOn( |
| 1459 ''' |
| 1391 main() => new B().m(); | 1460 main() => new B().m(); |
| 1392 class A { | 1461 class A { |
| 1393 get x => 1; | 1462 get x => 1; |
| 1394 } | 1463 } |
| 1395 class B extends A { | 1464 class B extends A { |
| 1396 m() { super.x = 2; } | 1465 m() { super.x = 2; } |
| 1397 } | 1466 } |
| 1398 ''', [MessageKind.UNDEFINED_SUPER_SETTER, | 1467 ''', |
| 1399 // TODO(johnniwinther): Avoid duplicate warnings. | 1468 [ |
| 1400 MessageKind.UNDEFINED_SETTER]); | 1469 MessageKind.UNDEFINED_SUPER_SETTER, |
| 1470 // TODO(johnniwinther): Avoid duplicate warnings. |
| 1471 MessageKind.UNDEFINED_SETTER |
| 1472 ]); |
| 1401 } | 1473 } |
| 1402 | 1474 |
| 1403 /// Helper to test that [script] produces all the given [warnings]. | 1475 /// Helper to test that [script] produces all the given [warnings]. |
| 1404 checkWarningOn(String script, List<MessageKind> warnings) { | 1476 checkWarningOn(String script, List<MessageKind> warnings) { |
| 1405 Expect.isTrue(warnings.length >= 0 && warnings.length <= 2); | 1477 Expect.isTrue(warnings.length >= 0 && warnings.length <= 2); |
| 1406 asyncTest(() => compileScript(script).then((compiler) { | 1478 asyncTest(() => compileScript(script).then((compiler) { |
| 1407 DiagnosticCollector collector = compiler.diagnosticCollector; | 1479 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 1408 Expect.equals(0, collector.errors.length, | 1480 Expect.equals(0, collector.errors.length, |
| 1409 'Unexpected errors in\n$script\n${collector.errors}'); | 1481 'Unexpected errors in\n$script\n${collector.errors}'); |
| 1410 Expect.equals(warnings.length, collector.warnings.length, | 1482 Expect.equals( |
| 1411 'Unexpected warnings in\n$script\n' | 1483 warnings.length, |
| 1412 'Expected:$warnings\nFound:${collector.warnings}'); | 1484 collector.warnings.length, |
| 1413 for (int i = 0; i < warnings.length; i++) { | 1485 'Unexpected warnings in\n$script\n' |
| 1414 Expect.equals(warnings[i], collector.warnings.elementAt(i).message.kind); | 1486 'Expected:$warnings\nFound:${collector.warnings}'); |
| 1415 } | 1487 for (int i = 0; i < warnings.length; i++) { |
| 1416 })); | 1488 Expect.equals( |
| 1489 warnings[i], collector.warnings.elementAt(i).message.kind); |
| 1490 } |
| 1491 })); |
| 1417 } | 1492 } |
| 1418 | 1493 |
| 1419 testAwaitHint() { | 1494 testAwaitHint() { |
| 1420 check(String script, {String className, String functionName}) { | 1495 check(String script, {String className, String functionName}) { |
| 1421 var prefix = className == null | 1496 var prefix = className == null |
| 1422 ? "Cannot resolve 'await'" | 1497 ? "Cannot resolve 'await'" |
| 1423 : "No member named 'await' in class '$className'"; | 1498 : "No member named 'await' in class '$className'"; |
| 1424 var where = functionName == null | 1499 var where = |
| 1425 ? 'the enclosing function' : "'$functionName'"; | 1500 functionName == null ? 'the enclosing function' : "'$functionName'"; |
| 1426 asyncTest(() => compileScript(script).then((compiler) { | 1501 asyncTest(() => compileScript(script).then((compiler) { |
| 1427 DiagnosticCollector collector = compiler.diagnosticCollector; | 1502 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 1428 Expect.equals(0, collector.errors.length); | 1503 Expect.equals(0, collector.errors.length); |
| 1429 Expect.equals(1, collector.warnings.length); | 1504 Expect.equals(1, collector.warnings.length); |
| 1430 Expect.equals("$prefix.\n" | 1505 Expect.equals( |
| 1431 "Did you mean to add the 'async' marker to $where?", | 1506 "$prefix.\n" |
| 1432 '${collector.warnings.first.message}'); | 1507 "Did you mean to add the 'async' marker to $where?", |
| 1433 })); | 1508 '${collector.warnings.first.message}'); |
| 1509 })); |
| 1434 } | 1510 } |
| 1435 check('main() { await -3; }', functionName: 'main'); | 1511 check('main() { await -3; }', functionName: 'main'); |
| 1436 check('main() { () => await -3; }'); | 1512 check('main() { () => await -3; }'); |
| 1437 check('foo() => await -3; main() => foo();', functionName: 'foo'); | 1513 check('foo() => await -3; main() => foo();', functionName: 'foo'); |
| 1438 check(''' | 1514 check( |
| 1515 ''' |
| 1439 class A { | 1516 class A { |
| 1440 m() => await - 3; | 1517 m() => await - 3; |
| 1441 } | 1518 } |
| 1442 main() => new A().m(); | 1519 main() => new A().m(); |
| 1443 ''', className: 'A', functionName: 'm'); | 1520 ''', |
| 1444 check(''' | 1521 className: 'A', |
| 1522 functionName: 'm'); |
| 1523 check( |
| 1524 ''' |
| 1445 class A { | 1525 class A { |
| 1446 static m() => await - 3; | 1526 static m() => await - 3; |
| 1447 } | 1527 } |
| 1448 main() => A.m(); | 1528 main() => A.m(); |
| 1449 ''', functionName: 'm'); | 1529 ''', |
| 1450 check(''' | 1530 functionName: 'm'); |
| 1531 check( |
| 1532 ''' |
| 1451 class A { | 1533 class A { |
| 1452 m() => () => await - 3; | 1534 m() => () => await - 3; |
| 1453 } | 1535 } |
| 1454 main() => new A().m(); | 1536 main() => new A().m(); |
| 1455 ''', className: 'A'); | 1537 ''', |
| 1538 className: 'A'); |
| 1456 } | 1539 } |
| OLD | NEW |