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 library dart2js.resolution.members; | 5 library dart2js.resolution.members; |
6 | 6 |
7 import '../common/names.dart' show | 7 import '../common/names.dart' show |
8 Selectors; | 8 Selectors; |
9 import '../compiler.dart' show | 9 import '../compiler.dart' show |
10 Compiler; | 10 Compiler; |
11 import '../constants/constructors.dart' show | 11 import '../constants/constructors.dart' show |
12 RedirectingFactoryConstantConstructor; | 12 RedirectingFactoryConstantConstructor; |
13 import '../constants/expressions.dart'; | 13 import '../constants/expressions.dart'; |
14 import '../constants/values.dart'; | 14 import '../constants/values.dart'; |
15 import '../core_types.dart'; | 15 import '../core_types.dart'; |
16 import '../dart_types.dart'; | 16 import '../dart_types.dart'; |
17 import '../diagnostics/diagnostic_listener.dart' show | 17 import '../diagnostics/diagnostic_listener.dart' show |
18 DiagnosticMessage; | 18 DiagnosticMessage, |
| 19 DiagnosticReporter; |
19 import '../diagnostics/invariant.dart' show | 20 import '../diagnostics/invariant.dart' show |
20 invariant; | 21 invariant; |
21 import '../diagnostics/messages.dart' show | 22 import '../diagnostics/messages.dart' show |
22 MessageKind; | 23 MessageKind; |
23 import '../diagnostics/spannable.dart' show | 24 import '../diagnostics/spannable.dart' show |
24 Spannable; | 25 Spannable; |
25 import '../elements/elements.dart'; | 26 import '../elements/elements.dart'; |
26 import '../elements/modelx.dart' show | 27 import '../elements/modelx.dart' show |
27 ConstructorElementX, | 28 ConstructorElementX, |
28 ErroneousElementX, | 29 ErroneousElementX, |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 if (enclosingElement is FunctionElement) { | 198 if (enclosingElement is FunctionElement) { |
198 FunctionElement function = enclosingElement; | 199 FunctionElement function = enclosingElement; |
199 return function.asyncMarker; | 200 return function.asyncMarker; |
200 } | 201 } |
201 return AsyncMarker.SYNC; | 202 return AsyncMarker.SYNC; |
202 } | 203 } |
203 | 204 |
204 Element reportLookupErrorIfAny(Element result, Node node, String name) { | 205 Element reportLookupErrorIfAny(Element result, Node node, String name) { |
205 if (!Elements.isUnresolved(result)) { | 206 if (!Elements.isUnresolved(result)) { |
206 if (!inInstanceContext && result.isInstanceMember) { | 207 if (!inInstanceContext && result.isInstanceMember) { |
207 compiler.reportErrorMessage( | 208 reporter.reportErrorMessage( |
208 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); | 209 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); |
209 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, | 210 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, |
210 {'name': name}, | 211 {'name': name}, |
211 name, enclosingElement); | 212 name, enclosingElement); |
212 } else if (result.isAmbiguous) { | 213 } else if (result.isAmbiguous) { |
213 AmbiguousElement ambiguous = result; | 214 AmbiguousElement ambiguous = result; |
214 return reportAndCreateErroneousElement( | 215 return reportAndCreateErroneousElement( |
215 node, | 216 node, |
216 name, | 217 name, |
217 ambiguous.messageKind, | 218 ambiguous.messageKind, |
218 ambiguous.messageArguments, | 219 ambiguous.messageArguments, |
219 infos: ambiguous.computeInfos(enclosingElement, compiler), | 220 infos: ambiguous.computeInfos(enclosingElement, reporter), |
220 isError: true); | 221 isError: true); |
221 } | 222 } |
222 } | 223 } |
223 return result; | 224 return result; |
224 } | 225 } |
225 | 226 |
226 // Create, or reuse an already created, target element for a statement. | 227 // Create, or reuse an already created, target element for a statement. |
227 JumpTarget getOrDefineTarget(Node statement) { | 228 JumpTarget getOrDefineTarget(Node statement) { |
228 JumpTarget element = registry.getTargetDefinition(statement); | 229 JumpTarget element = registry.getTargetDefinition(statement); |
229 if (element == null) { | 230 if (element == null) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 } | 295 } |
295 | 296 |
296 ErroneousElement reportAndCreateErroneousElement( | 297 ErroneousElement reportAndCreateErroneousElement( |
297 Node node, | 298 Node node, |
298 String name, | 299 String name, |
299 MessageKind kind, | 300 MessageKind kind, |
300 Map arguments, | 301 Map arguments, |
301 {List<DiagnosticMessage> infos: const <DiagnosticMessage>[], | 302 {List<DiagnosticMessage> infos: const <DiagnosticMessage>[], |
302 bool isError: false}) { | 303 bool isError: false}) { |
303 if (isError) { | 304 if (isError) { |
304 compiler.reportError( | 305 reporter.reportError( |
305 compiler.createMessage(node, kind, arguments), infos); | 306 reporter.createMessage(node, kind, arguments), infos); |
306 } else { | 307 } else { |
307 compiler.reportWarning( | 308 reporter.reportWarning( |
308 compiler.createMessage(node, kind, arguments), infos); | 309 reporter.createMessage(node, kind, arguments), infos); |
309 } | 310 } |
310 // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass | 311 // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass |
311 // of [ErroneousElementX]. For example, [ErroneousFieldElementX], | 312 // of [ErroneousElementX]. For example, [ErroneousFieldElementX], |
312 // [ErroneousConstructorElementX], etc. | 313 // [ErroneousConstructorElementX], etc. |
313 return new ErroneousElementX(kind, arguments, name, enclosingElement); | 314 return new ErroneousElementX(kind, arguments, name, enclosingElement); |
314 } | 315 } |
315 | 316 |
316 /// Report a warning or error on an unresolved access in non-instance context. | 317 /// Report a warning or error on an unresolved access in non-instance context. |
317 /// | 318 /// |
318 /// The [ErroneousElement] corresponding to the message is returned. | 319 /// The [ErroneousElement] corresponding to the message is returned. |
(...skipping 28 matching lines...) Expand all Loading... |
347 kind = MessageKind.CANNOT_RESOLVE; | 348 kind = MessageKind.CANNOT_RESOLVE; |
348 } | 349 } |
349 registry.registerThrowNoSuchMethod(); | 350 registry.registerThrowNoSuchMethod(); |
350 return reportAndCreateErroneousElement( | 351 return reportAndCreateErroneousElement( |
351 node, name, kind, arguments, isError: inInitializer); | 352 node, name, kind, arguments, isError: inInitializer); |
352 } | 353 } |
353 | 354 |
354 ResolutionResult visitIdentifier(Identifier node) { | 355 ResolutionResult visitIdentifier(Identifier node) { |
355 if (node.isThis()) { | 356 if (node.isThis()) { |
356 if (!inInstanceContext) { | 357 if (!inInstanceContext) { |
357 compiler.reportErrorMessage( | 358 reporter.reportErrorMessage( |
358 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); | 359 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); |
359 } | 360 } |
360 return const NoneResult(); | 361 return const NoneResult(); |
361 } else if (node.isSuper()) { | 362 } else if (node.isSuper()) { |
362 if (!inInstanceContext) { | 363 if (!inInstanceContext) { |
363 compiler.reportErrorMessage( | 364 reporter.reportErrorMessage( |
364 node, MessageKind.NO_SUPER_IN_STATIC); | 365 node, MessageKind.NO_SUPER_IN_STATIC); |
365 } | 366 } |
366 if ((ElementCategory.SUPER & allowedCategory) == 0) { | 367 if ((ElementCategory.SUPER & allowedCategory) == 0) { |
367 compiler.reportErrorMessage( | 368 reporter.reportErrorMessage( |
368 node, MessageKind.INVALID_USE_OF_SUPER); | 369 node, MessageKind.INVALID_USE_OF_SUPER); |
369 } | 370 } |
370 return const NoneResult(); | 371 return const NoneResult(); |
371 } else { | 372 } else { |
372 String name = node.source; | 373 String name = node.source; |
373 Element element = lookupInScope(compiler, node, scope, name); | 374 Element element = lookupInScope(reporter, node, scope, name); |
374 if (Elements.isUnresolved(element) && name == 'dynamic') { | 375 if (Elements.isUnresolved(element) && name == 'dynamic') { |
375 // TODO(johnniwinther): Remove this hack when we can return more complex | 376 // TODO(johnniwinther): Remove this hack when we can return more complex |
376 // objects than [Element] from this method. | 377 // objects than [Element] from this method. |
377 element = compiler.typeClass; | 378 element = compiler.typeClass; |
378 // Set the type to be `dynamic` to mark that this is a type literal. | 379 // Set the type to be `dynamic` to mark that this is a type literal. |
379 registry.setType(node, const DynamicType()); | 380 registry.setType(node, const DynamicType()); |
380 } | 381 } |
381 element = reportLookupErrorIfAny(element, node, name); | 382 element = reportLookupErrorIfAny(element, node, name); |
382 if (element == null) { | 383 if (element == null) { |
383 if (!inInstanceContext) { | 384 if (!inInstanceContext) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 final ClassElement classElement = constructor.enclosingClass; | 445 final ClassElement classElement = constructor.enclosingClass; |
445 return classElement.lookupConstructor(selector.name); | 446 return classElement.lookupConstructor(selector.name); |
446 } | 447 } |
447 return null; | 448 return null; |
448 } | 449 } |
449 | 450 |
450 void setupFunction(FunctionExpression node, FunctionElement function) { | 451 void setupFunction(FunctionExpression node, FunctionElement function) { |
451 Element enclosingElement = function.enclosingElement; | 452 Element enclosingElement = function.enclosingElement; |
452 if (node.modifiers.isStatic && | 453 if (node.modifiers.isStatic && |
453 enclosingElement.kind != ElementKind.CLASS) { | 454 enclosingElement.kind != ElementKind.CLASS) { |
454 compiler.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC); | 455 reporter.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC); |
455 } | 456 } |
456 | 457 |
457 scope = new MethodScope(scope, function); | 458 scope = new MethodScope(scope, function); |
458 // Put the parameters in scope. | 459 // Put the parameters in scope. |
459 FunctionSignature functionParameters = function.functionSignature; | 460 FunctionSignature functionParameters = function.functionSignature; |
460 Link<Node> parameterNodes = (node.parameters == null) | 461 Link<Node> parameterNodes = (node.parameters == null) |
461 ? const Link<Node>() : node.parameters.nodes; | 462 ? const Link<Node>() : node.parameters.nodes; |
462 functionParameters.forEachParameter((ParameterElementX element) { | 463 functionParameters.forEachParameter((ParameterElementX element) { |
463 // TODO(karlklose): should be a list of [FormalElement]s, but the actual | 464 // TODO(karlklose): should be a list of [FormalElement]s, but the actual |
464 // implementation uses [Element]. | 465 // implementation uses [Element]. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 if (inCheckContext) { | 501 if (inCheckContext) { |
501 functionParameters.forEachParameter((ParameterElement element) { | 502 functionParameters.forEachParameter((ParameterElement element) { |
502 registry.registerIsCheck(element.type); | 503 registry.registerIsCheck(element.type); |
503 }); | 504 }); |
504 } | 505 } |
505 } | 506 } |
506 | 507 |
507 ResolutionResult visitAssert(Assert node) { | 508 ResolutionResult visitAssert(Assert node) { |
508 if (!compiler.enableAssertMessage) { | 509 if (!compiler.enableAssertMessage) { |
509 if (node.hasMessage) { | 510 if (node.hasMessage) { |
510 compiler.reportErrorMessage( | 511 reporter.reportErrorMessage( |
511 node, MessageKind.EXPERIMENTAL_ASSERT_MESSAGE); | 512 node, MessageKind.EXPERIMENTAL_ASSERT_MESSAGE); |
512 } | 513 } |
513 } | 514 } |
514 // TODO(sra): We could completely ignore the assert in production mode if we | 515 // TODO(sra): We could completely ignore the assert in production mode if we |
515 // didn't need it to be resolved for type checking. | 516 // didn't need it to be resolved for type checking. |
516 registry.registerAssert(node.hasMessage); | 517 registry.registerAssert(node.hasMessage); |
517 visit(node.condition); | 518 visit(node.condition); |
518 visit(node.message); | 519 visit(node.message); |
519 return const NoneResult(); | 520 return const NoneResult(); |
520 } | 521 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 /// [inFunctionDeclaration] is `true` when the current node is the immediate | 596 /// [inFunctionDeclaration] is `true` when the current node is the immediate |
596 /// child of a function declaration. | 597 /// child of a function declaration. |
597 /// | 598 /// |
598 /// This is used to distinguish local function declarations from anonymous | 599 /// This is used to distinguish local function declarations from anonymous |
599 /// function expressions. | 600 /// function expressions. |
600 ResolutionResult visitFunctionExpression( | 601 ResolutionResult visitFunctionExpression( |
601 FunctionExpression node, | 602 FunctionExpression node, |
602 {bool inFunctionDeclaration: false}) { | 603 {bool inFunctionDeclaration: false}) { |
603 bool doAddToScope = inFunctionDeclaration; | 604 bool doAddToScope = inFunctionDeclaration; |
604 if (!inFunctionDeclaration && node.name != null) { | 605 if (!inFunctionDeclaration && node.name != null) { |
605 compiler.reportErrorMessage( | 606 reporter.reportErrorMessage( |
606 node.name, | 607 node.name, |
607 MessageKind.NAMED_FUNCTION_EXPRESSION, | 608 MessageKind.NAMED_FUNCTION_EXPRESSION, |
608 {'name': node.name}); | 609 {'name': node.name}); |
609 } | 610 } |
610 visit(node.returnType); | 611 visit(node.returnType); |
611 String name; | 612 String name; |
612 if (node.name == null) { | 613 if (node.name == null) { |
613 name = ""; | 614 name = ""; |
614 } else { | 615 } else { |
615 name = node.name.asIdentifier().source; | 616 name = node.name.asIdentifier().source; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 if (seenNamedArguments.containsKey(source)) { | 761 if (seenNamedArguments.containsKey(source)) { |
761 reportDuplicateDefinition( | 762 reportDuplicateDefinition( |
762 source, | 763 source, |
763 argument, | 764 argument, |
764 seenNamedArguments[source]); | 765 seenNamedArguments[source]); |
765 isValidAsConstant = false; | 766 isValidAsConstant = false; |
766 } else { | 767 } else { |
767 seenNamedArguments[source] = namedArgument; | 768 seenNamedArguments[source] = namedArgument; |
768 } | 769 } |
769 } else if (!seenNamedArguments.isEmpty) { | 770 } else if (!seenNamedArguments.isEmpty) { |
770 compiler.reportErrorMessage( | 771 reporter.reportErrorMessage( |
771 argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); | 772 argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); |
772 isValidAsConstant = false; | 773 isValidAsConstant = false; |
773 } | 774 } |
774 argumentCount++; | 775 argumentCount++; |
775 } | 776 } |
776 sendIsMemberAccess = oldSendIsMemberAccess; | 777 sendIsMemberAccess = oldSendIsMemberAccess; |
777 return new ArgumentsResult( | 778 return new ArgumentsResult( |
778 new CallStructure(argumentCount, namedArguments), | 779 new CallStructure(argumentCount, namedArguments), |
779 argumentResults, | 780 argumentResults, |
780 isValidAsConstant: isValidAsConstant); | 781 isValidAsConstant: isValidAsConstant); |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1246 case UnaryOperatorKind.COMPLEMENT: | 1247 case UnaryOperatorKind.COMPLEMENT: |
1247 isValidConstant = | 1248 isValidConstant = |
1248 knownExpressionType == coreTypes.intType; | 1249 knownExpressionType == coreTypes.intType; |
1249 break; | 1250 break; |
1250 case UnaryOperatorKind.NEGATE: | 1251 case UnaryOperatorKind.NEGATE: |
1251 isValidConstant = | 1252 isValidConstant = |
1252 knownExpressionType == coreTypes.intType || | 1253 knownExpressionType == coreTypes.intType || |
1253 knownExpressionType == coreTypes.doubleType; | 1254 knownExpressionType == coreTypes.doubleType; |
1254 break; | 1255 break; |
1255 case UnaryOperatorKind.NOT: | 1256 case UnaryOperatorKind.NOT: |
1256 compiler.internalError(node, | 1257 reporter.internalError(node, |
1257 "Unexpected user definable unary operator: $operator"); | 1258 "Unexpected user definable unary operator: $operator"); |
1258 } | 1259 } |
1259 if (isValidConstant) { | 1260 if (isValidConstant) { |
1260 // TODO(johnniwinther): Handle potentially invalid constant | 1261 // TODO(johnniwinther): Handle potentially invalid constant |
1261 // expressions. | 1262 // expressions. |
1262 ConstantExpression constant = | 1263 ConstantExpression constant = |
1263 new UnaryConstantExpression(operator, expressionConstant); | 1264 new UnaryConstantExpression(operator, expressionConstant); |
1264 registry.setConstant(node, constant); | 1265 registry.setConstant(node, constant); |
1265 result = new ConstantResult(node, constant); | 1266 result = new ConstantResult(node, constant); |
1266 } | 1267 } |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1464 isValidConstant = | 1465 isValidConstant = |
1465 knownLeftType == coreTypes.intType && | 1466 knownLeftType == coreTypes.intType && |
1466 knownRightType == coreTypes.intType; | 1467 knownRightType == coreTypes.intType; |
1467 break; | 1468 break; |
1468 case BinaryOperatorKind.INDEX: | 1469 case BinaryOperatorKind.INDEX: |
1469 isValidConstant = false; | 1470 isValidConstant = false; |
1470 break; | 1471 break; |
1471 case BinaryOperatorKind.LOGICAL_AND: | 1472 case BinaryOperatorKind.LOGICAL_AND: |
1472 case BinaryOperatorKind.LOGICAL_OR: | 1473 case BinaryOperatorKind.LOGICAL_OR: |
1473 case BinaryOperatorKind.IF_NULL: | 1474 case BinaryOperatorKind.IF_NULL: |
1474 compiler.internalError( | 1475 reporter.internalError( |
1475 node, "Unexpected binary operator '${operator}'."); | 1476 node, "Unexpected binary operator '${operator}'."); |
1476 break; | 1477 break; |
1477 } | 1478 } |
1478 if (isValidConstant) { | 1479 if (isValidConstant) { |
1479 // TODO(johnniwinther): Handle potentially invalid constant | 1480 // TODO(johnniwinther): Handle potentially invalid constant |
1480 // expressions. | 1481 // expressions. |
1481 ConstantExpression constant = new BinaryConstantExpression( | 1482 ConstantExpression constant = new BinaryConstantExpression( |
1482 leftResult.constant, | 1483 leftResult.constant, |
1483 operator, | 1484 operator, |
1484 rightResult.constant); | 1485 rightResult.constant); |
(...skipping 30 matching lines...) Expand all Loading... |
1515 case BinaryOperatorKind.LTEQ: | 1516 case BinaryOperatorKind.LTEQ: |
1516 case BinaryOperatorKind.LT: | 1517 case BinaryOperatorKind.LT: |
1517 case BinaryOperatorKind.AND: | 1518 case BinaryOperatorKind.AND: |
1518 case BinaryOperatorKind.OR: | 1519 case BinaryOperatorKind.OR: |
1519 case BinaryOperatorKind.XOR: | 1520 case BinaryOperatorKind.XOR: |
1520 sendStructure = new BinaryStructure(semantics, operator); | 1521 sendStructure = new BinaryStructure(semantics, operator); |
1521 break; | 1522 break; |
1522 case BinaryOperatorKind.LOGICAL_AND: | 1523 case BinaryOperatorKind.LOGICAL_AND: |
1523 case BinaryOperatorKind.LOGICAL_OR: | 1524 case BinaryOperatorKind.LOGICAL_OR: |
1524 case BinaryOperatorKind.IF_NULL: | 1525 case BinaryOperatorKind.IF_NULL: |
1525 compiler.internalError( | 1526 reporter.internalError( |
1526 node, "Unexpected binary operator '${operator}'."); | 1527 node, "Unexpected binary operator '${operator}'."); |
1527 break; | 1528 break; |
1528 } | 1529 } |
1529 registry.registerSendStructure(node, sendStructure); | 1530 registry.registerSendStructure(node, sendStructure); |
1530 } | 1531 } |
1531 return result; | 1532 return result; |
1532 } | 1533 } |
1533 | 1534 |
1534 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. | 1535 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. |
1535 ResolutionResult handleExpressionInvoke(Send node) { | 1536 ResolutionResult handleExpressionInvoke(Send node) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 new UniverseSelector(selector, null)); | 1581 new UniverseSelector(selector, null)); |
1581 } | 1582 } |
1582 registry.registerSendStructure(node, | 1583 registry.registerSendStructure(node, |
1583 new InvokeStructure(accessSemantics, selector)); | 1584 new InvokeStructure(accessSemantics, selector)); |
1584 // TODO(23998): Remove this when all information goes through | 1585 // TODO(23998): Remove this when all information goes through |
1585 // the [SendStructure]. | 1586 // the [SendStructure]. |
1586 registry.setSelector(node, selector); | 1587 registry.setSelector(node, selector); |
1587 return const NoneResult(); | 1588 return const NoneResult(); |
1588 } else { | 1589 } else { |
1589 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. | 1590 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. |
1590 compiler.internalError( | 1591 reporter.internalError( |
1591 node, "Unexpected node '$node'."); | 1592 node, "Unexpected node '$node'."); |
1592 } | 1593 } |
1593 return const NoneResult(); | 1594 return const NoneResult(); |
1594 } | 1595 } |
1595 | 1596 |
1596 /// Handle access of a super property, like `super.foo` and `super.foo()`. | 1597 /// Handle access of a super property, like `super.foo` and `super.foo()`. |
1597 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { | 1598 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { |
1598 Element target; | 1599 Element target; |
1599 Selector selector; | 1600 Selector selector; |
1600 CallStructure callStructure; | 1601 CallStructure callStructure; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1635 new UniverseSelector(selector, null)); | 1636 new UniverseSelector(selector, null)); |
1636 break; | 1637 break; |
1637 case AccessKind.SUPER_SETTER: | 1638 case AccessKind.SUPER_SETTER: |
1638 case AccessKind.UNRESOLVED_SUPER: | 1639 case AccessKind.UNRESOLVED_SUPER: |
1639 // NoSuchMethod registered in [computeSuperSemantics]. | 1640 // NoSuchMethod registered in [computeSuperSemantics]. |
1640 break; | 1641 break; |
1641 case AccessKind.INVALID: | 1642 case AccessKind.INVALID: |
1642 // 'super' is not allowed. | 1643 // 'super' is not allowed. |
1643 break; | 1644 break; |
1644 default: | 1645 default: |
1645 compiler.internalError( | 1646 reporter.internalError( |
1646 node, "Unexpected super property access $semantics."); | 1647 node, "Unexpected super property access $semantics."); |
1647 break; | 1648 break; |
1648 } | 1649 } |
1649 registry.registerSendStructure(node, | 1650 registry.registerSendStructure(node, |
1650 isIncompatibleInvoke | 1651 isIncompatibleInvoke |
1651 ? new IncompatibleInvokeStructure(semantics, selector) | 1652 ? new IncompatibleInvokeStructure(semantics, selector) |
1652 : new InvokeStructure(semantics, selector)); | 1653 : new InvokeStructure(semantics, selector)); |
1653 } else { | 1654 } else { |
1654 switch (semantics.kind) { | 1655 switch (semantics.kind) { |
1655 case AccessKind.SUPER_METHOD: | 1656 case AccessKind.SUPER_METHOD: |
1656 // TODO(johnniwinther): Method this should be registered as a | 1657 // TODO(johnniwinther): Method this should be registered as a |
1657 // closurization. | 1658 // closurization. |
1658 registry.registerStaticUse(semantics.element); | 1659 registry.registerStaticUse(semantics.element); |
1659 break; | 1660 break; |
1660 case AccessKind.SUPER_FIELD: | 1661 case AccessKind.SUPER_FIELD: |
1661 case AccessKind.SUPER_FINAL_FIELD: | 1662 case AccessKind.SUPER_FINAL_FIELD: |
1662 case AccessKind.SUPER_GETTER: | 1663 case AccessKind.SUPER_GETTER: |
1663 registry.registerStaticUse(semantics.element); | 1664 registry.registerStaticUse(semantics.element); |
1664 break; | 1665 break; |
1665 case AccessKind.SUPER_SETTER: | 1666 case AccessKind.SUPER_SETTER: |
1666 case AccessKind.UNRESOLVED_SUPER: | 1667 case AccessKind.UNRESOLVED_SUPER: |
1667 // NoSuchMethod registered in [computeSuperSemantics]. | 1668 // NoSuchMethod registered in [computeSuperSemantics]. |
1668 break; | 1669 break; |
1669 case AccessKind.INVALID: | 1670 case AccessKind.INVALID: |
1670 // 'super' is not allowed. | 1671 // 'super' is not allowed. |
1671 break; | 1672 break; |
1672 default: | 1673 default: |
1673 compiler.internalError( | 1674 reporter.internalError( |
1674 node, "Unexpected super property access $semantics."); | 1675 node, "Unexpected super property access $semantics."); |
1675 break; | 1676 break; |
1676 } | 1677 } |
1677 registry.registerSendStructure(node, new GetStructure(semantics)); | 1678 registry.registerSendStructure(node, new GetStructure(semantics)); |
1678 } | 1679 } |
1679 target = semantics.element; | 1680 target = semantics.element; |
1680 | 1681 |
1681 // TODO(23998): Remove these when all information goes through | 1682 // TODO(23998): Remove these when all information goes through |
1682 // the [SendStructure]. | 1683 // the [SendStructure]. |
1683 registry.useElement(node, target); | 1684 registry.useElement(node, target); |
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 ResolutionResult handleAmbiguousSend( | 2512 ResolutionResult handleAmbiguousSend( |
2512 Send node, | 2513 Send node, |
2513 Name name, | 2514 Name name, |
2514 AmbiguousElement element) { | 2515 AmbiguousElement element) { |
2515 | 2516 |
2516 ErroneousElement error = reportAndCreateErroneousElement( | 2517 ErroneousElement error = reportAndCreateErroneousElement( |
2517 node, | 2518 node, |
2518 name.text, | 2519 name.text, |
2519 element.messageKind, | 2520 element.messageKind, |
2520 element.messageArguments, | 2521 element.messageArguments, |
2521 infos: element.computeInfos(enclosingElement, compiler)); | 2522 infos: element.computeInfos(enclosingElement, reporter)); |
2522 registry.registerThrowNoSuchMethod(); | 2523 registry.registerThrowNoSuchMethod(); |
2523 | 2524 |
2524 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. | 2525 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. |
2525 AccessSemantics semantics = new StaticAccess.unresolved(error); | 2526 AccessSemantics semantics = new StaticAccess.unresolved(error); |
2526 return handleErroneousAccess(node, name, semantics); | 2527 return handleErroneousAccess(node, name, semantics); |
2527 } | 2528 } |
2528 | 2529 |
2529 /// Handle update to an ambiguous element, that is, a name imported twice. | 2530 /// Handle update to an ambiguous element, that is, a name imported twice. |
2530 ResolutionResult handleAmbiguousUpdate( | 2531 ResolutionResult handleAmbiguousUpdate( |
2531 SendSet node, | 2532 SendSet node, |
2532 Name name, | 2533 Name name, |
2533 AmbiguousElement element) { | 2534 AmbiguousElement element) { |
2534 | 2535 |
2535 ErroneousElement error = reportAndCreateErroneousElement( | 2536 ErroneousElement error = reportAndCreateErroneousElement( |
2536 node, | 2537 node, |
2537 name.text, | 2538 name.text, |
2538 element.messageKind, | 2539 element.messageKind, |
2539 element.messageArguments, | 2540 element.messageArguments, |
2540 infos: element.computeInfos(enclosingElement, compiler)); | 2541 infos: element.computeInfos(enclosingElement, reporter)); |
2541 registry.registerThrowNoSuchMethod(); | 2542 registry.registerThrowNoSuchMethod(); |
2542 | 2543 |
2543 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. | 2544 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. |
2544 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); | 2545 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); |
2545 return handleUpdate(node, name, accessSemantics); | 2546 return handleUpdate(node, name, accessSemantics); |
2546 } | 2547 } |
2547 | 2548 |
2548 /// Report access of an instance [member] from a non-instance context. | 2549 /// Report access of an instance [member] from a non-instance context. |
2549 AccessSemantics reportStaticInstanceAccess(Send node, Name name) { | 2550 AccessSemantics reportStaticInstanceAccess(Send node, Name name) { |
2550 ErroneousElement error = reportAndCreateErroneousElement( | 2551 ErroneousElement error = reportAndCreateErroneousElement( |
(...skipping 29 matching lines...) Expand all Loading... |
2580 break; | 2581 break; |
2581 case AccessKind.PARAMETER: | 2582 case AccessKind.PARAMETER: |
2582 case AccessKind.FINAL_PARAMETER: | 2583 case AccessKind.FINAL_PARAMETER: |
2583 case AccessKind.LOCAL_VARIABLE: | 2584 case AccessKind.LOCAL_VARIABLE: |
2584 case AccessKind.FINAL_LOCAL_VARIABLE: | 2585 case AccessKind.FINAL_LOCAL_VARIABLE: |
2585 selector = callStructure.callSelector; | 2586 selector = callStructure.callSelector; |
2586 registry.registerDynamicInvocation( | 2587 registry.registerDynamicInvocation( |
2587 new UniverseSelector(selector, null)); | 2588 new UniverseSelector(selector, null)); |
2588 break; | 2589 break; |
2589 default: | 2590 default: |
2590 compiler.internalError(node, | 2591 reporter.internalError(node, |
2591 "Unexpected local access $semantics."); | 2592 "Unexpected local access $semantics."); |
2592 break; | 2593 break; |
2593 } | 2594 } |
2594 registry.registerSendStructure(node, | 2595 registry.registerSendStructure(node, |
2595 isIncompatibleInvoke | 2596 isIncompatibleInvoke |
2596 ? new IncompatibleInvokeStructure(semantics, selector) | 2597 ? new IncompatibleInvokeStructure(semantics, selector) |
2597 : new InvokeStructure(semantics, selector)); | 2598 : new InvokeStructure(semantics, selector)); |
2598 } else { | 2599 } else { |
2599 switch (semantics.kind) { | 2600 switch (semantics.kind) { |
2600 case AccessKind.LOCAL_VARIABLE: | 2601 case AccessKind.LOCAL_VARIABLE: |
(...skipping 25 matching lines...) Expand all Loading... |
2626 if (element.isConst) { | 2627 if (element.isConst) { |
2627 result = new ConstantResult( | 2628 result = new ConstantResult( |
2628 node, | 2629 node, |
2629 new VariableConstantExpression(element), | 2630 new VariableConstantExpression(element), |
2630 element: element); | 2631 element: element); |
2631 } else { | 2632 } else { |
2632 result = new ElementResult(element); | 2633 result = new ElementResult(element); |
2633 } | 2634 } |
2634 break; | 2635 break; |
2635 default: | 2636 default: |
2636 compiler.internalError(node, | 2637 reporter.internalError(node, |
2637 "Unexpected local access $semantics."); | 2638 "Unexpected local access $semantics."); |
2638 break; | 2639 break; |
2639 } | 2640 } |
2640 selector = new Selector.getter(name); | 2641 selector = new Selector.getter(name); |
2641 registry.registerSendStructure(node, new GetStructure(semantics)); | 2642 registry.registerSendStructure(node, new GetStructure(semantics)); |
2642 } | 2643 } |
2643 | 2644 |
2644 // TODO(23998): Remove these when all information goes through | 2645 // TODO(23998): Remove these when all information goes through |
2645 // the [SendStructure]. | 2646 // the [SendStructure]. |
2646 registry.useElement(node, element); | 2647 registry.useElement(node, element); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2716 } else { | 2717 } else { |
2717 member = element; | 2718 member = element; |
2718 } | 2719 } |
2719 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery | 2720 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
2720 // of parse errors to make [element] erroneous. Fix this! | 2721 // of parse errors to make [element] erroneous. Fix this! |
2721 member.computeType(resolution); | 2722 member.computeType(resolution); |
2722 | 2723 |
2723 | 2724 |
2724 if (member == compiler.mirrorSystemGetNameFunction && | 2725 if (member == compiler.mirrorSystemGetNameFunction && |
2725 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 2726 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
2726 compiler.reportHintMessage( | 2727 reporter.reportHintMessage( |
2727 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, | 2728 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, |
2728 {'class': compiler.mirrorSystemClass.name, | 2729 {'class': compiler.mirrorSystemClass.name, |
2729 'name': compiler.mirrorSystemGetNameFunction.name}); | 2730 'name': compiler.mirrorSystemGetNameFunction.name}); |
2730 } | 2731 } |
2731 | 2732 |
2732 Selector selector; | 2733 Selector selector; |
2733 AccessSemantics semantics = | 2734 AccessSemantics semantics = |
2734 computeStaticOrTopLevelAccessSemantics(node, member); | 2735 computeStaticOrTopLevelAccessSemantics(node, member); |
2735 if (node.isCall) { | 2736 if (node.isCall) { |
2736 ArgumentsResult argumentsResult = | 2737 ArgumentsResult argumentsResult = |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2774 break; | 2775 break; |
2775 case AccessKind.STATIC_SETTER: | 2776 case AccessKind.STATIC_SETTER: |
2776 case AccessKind.TOPLEVEL_SETTER: | 2777 case AccessKind.TOPLEVEL_SETTER: |
2777 case AccessKind.UNRESOLVED: | 2778 case AccessKind.UNRESOLVED: |
2778 registry.registerThrowNoSuchMethod(); | 2779 registry.registerThrowNoSuchMethod(); |
2779 member = reportAndCreateErroneousElement( | 2780 member = reportAndCreateErroneousElement( |
2780 node.selector, name.text, | 2781 node.selector, name.text, |
2781 MessageKind.CANNOT_RESOLVE_GETTER, const {}); | 2782 MessageKind.CANNOT_RESOLVE_GETTER, const {}); |
2782 break; | 2783 break; |
2783 default: | 2784 default: |
2784 compiler.internalError(node, | 2785 reporter.internalError(node, |
2785 "Unexpected statically resolved access $semantics."); | 2786 "Unexpected statically resolved access $semantics."); |
2786 break; | 2787 break; |
2787 } | 2788 } |
2788 registry.registerSendStructure(node, | 2789 registry.registerSendStructure(node, |
2789 isIncompatibleInvoke | 2790 isIncompatibleInvoke |
2790 ? new IncompatibleInvokeStructure(semantics, selector) | 2791 ? new IncompatibleInvokeStructure(semantics, selector) |
2791 : new InvokeStructure(semantics, selector)); | 2792 : new InvokeStructure(semantics, selector)); |
2792 } else { | 2793 } else { |
2793 selector = new Selector.getter(name); | 2794 selector = new Selector.getter(name); |
2794 switch (semantics.kind) { | 2795 switch (semantics.kind) { |
(...skipping 14 matching lines...) Expand all Loading... |
2809 break; | 2810 break; |
2810 case AccessKind.STATIC_SETTER: | 2811 case AccessKind.STATIC_SETTER: |
2811 case AccessKind.TOPLEVEL_SETTER: | 2812 case AccessKind.TOPLEVEL_SETTER: |
2812 case AccessKind.UNRESOLVED: | 2813 case AccessKind.UNRESOLVED: |
2813 registry.registerThrowNoSuchMethod(); | 2814 registry.registerThrowNoSuchMethod(); |
2814 member = reportAndCreateErroneousElement( | 2815 member = reportAndCreateErroneousElement( |
2815 node.selector, name.text, | 2816 node.selector, name.text, |
2816 MessageKind.CANNOT_RESOLVE_GETTER, const {}); | 2817 MessageKind.CANNOT_RESOLVE_GETTER, const {}); |
2817 break; | 2818 break; |
2818 default: | 2819 default: |
2819 compiler.internalError(node, | 2820 reporter.internalError(node, |
2820 "Unexpected statically resolved access $semantics."); | 2821 "Unexpected statically resolved access $semantics."); |
2821 break; | 2822 break; |
2822 } | 2823 } |
2823 registry.registerSendStructure(node, new GetStructure(semantics)); | 2824 registry.registerSendStructure(node, new GetStructure(semantics)); |
2824 if (member.isConst) { | 2825 if (member.isConst) { |
2825 FieldElement field = member; | 2826 FieldElement field = member; |
2826 result = new ConstantResult( | 2827 result = new ConstantResult( |
2827 node, new VariableConstantExpression(field), element: field); | 2828 node, new VariableConstantExpression(field), element: field); |
2828 } else { | 2829 } else { |
2829 result = new ElementResult(member); | 2830 result = new ElementResult(member); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2972 return handleTypedefTypeLiteralAccess(node, name, element); | 2973 return handleTypedefTypeLiteralAccess(node, name, element); |
2973 } else if (element.isTypeVariable) { | 2974 } else if (element.isTypeVariable) { |
2974 return handleTypeVariableTypeLiteralAccess(node, name, element); | 2975 return handleTypeVariableTypeLiteralAccess(node, name, element); |
2975 } else if (element.isPrefix) { | 2976 } else if (element.isPrefix) { |
2976 return handleLibraryPrefix(node, name, element); | 2977 return handleLibraryPrefix(node, name, element); |
2977 } else if (element.isLocal) { | 2978 } else if (element.isLocal) { |
2978 return handleLocalAccess(node, name, element); | 2979 return handleLocalAccess(node, name, element); |
2979 } else if (element.isStatic || element.isTopLevel) { | 2980 } else if (element.isStatic || element.isTopLevel) { |
2980 return handleStaticOrTopLevelAccess(node, name, element); | 2981 return handleStaticOrTopLevelAccess(node, name, element); |
2981 } | 2982 } |
2982 return compiler.internalError(node, "Unexpected resolved send: $element"); | 2983 return reporter.internalError(node, "Unexpected resolved send: $element"); |
2983 } | 2984 } |
2984 | 2985 |
2985 /// Handle update to resolved [element]. | 2986 /// Handle update to resolved [element]. |
2986 ResolutionResult handleResolvedSendSet( | 2987 ResolutionResult handleResolvedSendSet( |
2987 SendSet node, Name name, Element element) { | 2988 SendSet node, Name name, Element element) { |
2988 if (element.isAmbiguous) { | 2989 if (element.isAmbiguous) { |
2989 return handleAmbiguousUpdate(node, name, element); | 2990 return handleAmbiguousUpdate(node, name, element); |
2990 } | 2991 } |
2991 if (element.isErroneous) { | 2992 if (element.isErroneous) { |
2992 // This handles elements with parser errors. | 2993 // This handles elements with parser errors. |
(...skipping 17 matching lines...) Expand all Loading... |
3010 // `C = b`, `C++`, or 'C += b` where 'F' is a typedef. | 3011 // `C = b`, `C++`, or 'C += b` where 'F' is a typedef. |
3011 return handleTypedefTypeLiteralUpdate(node, name, element); | 3012 return handleTypedefTypeLiteralUpdate(node, name, element); |
3012 } else if (element.isTypeVariable) { | 3013 } else if (element.isTypeVariable) { |
3013 // `T = b`, `T++`, or 'T += b` where 'T' is a type variable. | 3014 // `T = b`, `T++`, or 'T += b` where 'T' is a type variable. |
3014 return handleTypeVariableTypeLiteralUpdate(node, name, element); | 3015 return handleTypeVariableTypeLiteralUpdate(node, name, element); |
3015 } else if (element.isLocal) { | 3016 } else if (element.isLocal) { |
3016 return handleLocalUpdate(node, name, element); | 3017 return handleLocalUpdate(node, name, element); |
3017 } else if (element.isStatic || element.isTopLevel) { | 3018 } else if (element.isStatic || element.isTopLevel) { |
3018 return handleStaticOrTopLevelUpdate(node, name, element); | 3019 return handleStaticOrTopLevelUpdate(node, name, element); |
3019 } | 3020 } |
3020 return compiler.internalError(node, "Unexpected resolved send: $element"); | 3021 return reporter.internalError(node, "Unexpected resolved send: $element"); |
3021 } | 3022 } |
3022 | 3023 |
3023 /// Handle an unqualified [Send], that is where the `node.receiver` is null, | 3024 /// Handle an unqualified [Send], that is where the `node.receiver` is null, |
3024 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. | 3025 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. |
3025 ResolutionResult handleUnqualifiedSend(Send node) { | 3026 ResolutionResult handleUnqualifiedSend(Send node) { |
3026 Identifier selector = node.selector.asIdentifier(); | 3027 Identifier selector = node.selector.asIdentifier(); |
3027 if (selector == null) { | 3028 if (selector == null) { |
3028 // `(){}()` and `(foo)()`. | 3029 // `(){}()` and `(foo)()`. |
3029 return handleExpressionInvoke(node); | 3030 return handleExpressionInvoke(node); |
3030 } | 3031 } |
3031 String text = selector.source; | 3032 String text = selector.source; |
3032 if (text == 'this') { | 3033 if (text == 'this') { |
3033 // `this()`. | 3034 // `this()`. |
3034 return handleThisAccess(node); | 3035 return handleThisAccess(node); |
3035 } | 3036 } |
3036 // `name` or `name()` | 3037 // `name` or `name()` |
3037 Name name = new Name(text, enclosingElement.library); | 3038 Name name = new Name(text, enclosingElement.library); |
3038 Element element = lookupInScope(compiler, node, scope, text); | 3039 Element element = lookupInScope(reporter, node, scope, text); |
3039 if (element == null) { | 3040 if (element == null) { |
3040 if (text == 'dynamic') { | 3041 if (text == 'dynamic') { |
3041 // `dynamic` or `dynamic()` where 'dynamic' is not declared in the | 3042 // `dynamic` or `dynamic()` where 'dynamic' is not declared in the |
3042 // current scope. | 3043 // current scope. |
3043 return handleDynamicTypeLiteralAccess(node); | 3044 return handleDynamicTypeLiteralAccess(node); |
3044 } else if (inInstanceContext) { | 3045 } else if (inInstanceContext) { |
3045 // Implicitly `this.name`. | 3046 // Implicitly `this.name`. |
3046 return handleThisPropertyAccess(node, name); | 3047 return handleThisPropertyAccess(node, name); |
3047 } else { | 3048 } else { |
3048 // Create [ErroneousElement] for unresolved access. | 3049 // Create [ErroneousElement] for unresolved access. |
3049 ErroneousElement error = reportCannotResolve(node, text); | 3050 ErroneousElement error = reportCannotResolve(node, text); |
3050 return handleUnresolvedAccess(node, name, error); | 3051 return handleUnresolvedAccess(node, name, error); |
3051 } | 3052 } |
3052 } else { | 3053 } else { |
3053 return handleResolvedSend(node, name, element); | 3054 return handleResolvedSend(node, name, element); |
3054 } | 3055 } |
3055 } | 3056 } |
3056 | 3057 |
3057 /// Handle an unqualified [SendSet], that is where the `node.receiver` is | 3058 /// Handle an unqualified [SendSet], that is where the `node.receiver` is |
3058 /// null, like `a = b`, `a++`, and `a += b`. | 3059 /// null, like `a = b`, `a++`, and `a += b`. |
3059 ResolutionResult handleUnqualifiedSendSet(SendSet node) { | 3060 ResolutionResult handleUnqualifiedSendSet(SendSet node) { |
3060 Identifier selector = node.selector.asIdentifier(); | 3061 Identifier selector = node.selector.asIdentifier(); |
3061 String text = selector.source; | 3062 String text = selector.source; |
3062 Name name = new Name(text, enclosingElement.library); | 3063 Name name = new Name(text, enclosingElement.library); |
3063 Element element = lookupInScope(compiler, node, scope, text); | 3064 Element element = lookupInScope(reporter, node, scope, text); |
3064 if (element == null) { | 3065 if (element == null) { |
3065 if (text == 'dynamic') { | 3066 if (text == 'dynamic') { |
3066 // `dynamic = b`, `dynamic++`, or `dynamic += b` where 'dynamic' is not | 3067 // `dynamic = b`, `dynamic++`, or `dynamic += b` where 'dynamic' is not |
3067 // declared in the current scope. | 3068 // declared in the current scope. |
3068 return handleDynamicTypeLiteralUpdate(node); | 3069 return handleDynamicTypeLiteralUpdate(node); |
3069 } else if (inInstanceContext) { | 3070 } else if (inInstanceContext) { |
3070 // Left-hand side is implicitly `this.name`. | 3071 // Left-hand side is implicitly `this.name`. |
3071 return handleThisPropertyUpdate(node, name, null); | 3072 return handleThisPropertyUpdate(node, name, null); |
3072 } else { | 3073 } else { |
3073 // Create [ErroneousElement] for unresolved access. | 3074 // Create [ErroneousElement] for unresolved access. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3107 void handleForeignCall(Send node, | 3108 void handleForeignCall(Send node, |
3108 Element target, | 3109 Element target, |
3109 CallStructure callStructure) { | 3110 CallStructure callStructure) { |
3110 if (target != null && compiler.backend.isForeign(target)) { | 3111 if (target != null && compiler.backend.isForeign(target)) { |
3111 registry.registerForeignCall(node, target, callStructure, this); | 3112 registry.registerForeignCall(node, target, callStructure, this); |
3112 } | 3113 } |
3113 } | 3114 } |
3114 | 3115 |
3115 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. | 3116 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. |
3116 DartType resolveTypeFromString(Node node, String typeName) { | 3117 DartType resolveTypeFromString(Node node, String typeName) { |
3117 Element element = lookupInScope(compiler, node, scope, typeName); | 3118 Element element = lookupInScope(reporter, node, scope, typeName); |
3118 if (element == null) return null; | 3119 if (element == null) return null; |
3119 if (element is! ClassElement) return null; | 3120 if (element is! ClassElement) return null; |
3120 ClassElement cls = element; | 3121 ClassElement cls = element; |
3121 cls.ensureResolved(resolution); | 3122 cls.ensureResolved(resolution); |
3122 return cls.computeType(resolution); | 3123 return cls.computeType(resolution); |
3123 } | 3124 } |
3124 | 3125 |
3125 /// Handle index operations like `a[b] = c`, `a[b] += c`, and `a[b]++`. | 3126 /// Handle index operations like `a[b] = c`, `a[b] += c`, and `a[b]++`. |
3126 ResolutionResult handleIndexSendSet(SendSet node) { | 3127 ResolutionResult handleIndexSendSet(SendSet node) { |
3127 String operatorText = node.assignmentOperator.source; | 3128 String operatorText = node.assignmentOperator.source; |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3329 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 3330 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
3330 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 3331 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
3331 // `super.a = b`. | 3332 // `super.a = b`. |
3332 if (semantics == null) { | 3333 if (semantics == null) { |
3333 semantics = | 3334 semantics = |
3334 computeSuperAccessSemanticsForSelector( | 3335 computeSuperAccessSemanticsForSelector( |
3335 node, setterSelector, alternateName: name); | 3336 node, setterSelector, alternateName: name); |
3336 registry.registerStaticInvocation(semantics.setter); | 3337 registry.registerStaticInvocation(semantics.setter); |
3337 switch (semantics.kind) { | 3338 switch (semantics.kind) { |
3338 case AccessKind.SUPER_FINAL_FIELD: | 3339 case AccessKind.SUPER_FINAL_FIELD: |
3339 compiler.reportWarningMessage( | 3340 reporter.reportWarningMessage( |
3340 node, | 3341 node, |
3341 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, | 3342 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, |
3342 {'name': name, | 3343 {'name': name, |
3343 'superclassName': semantics.setter.enclosingClass.name}); | 3344 'superclassName': semantics.setter.enclosingClass.name}); |
3344 // TODO(johnniwinther): This shouldn't be needed. | 3345 // TODO(johnniwinther): This shouldn't be needed. |
3345 registry.registerDynamicInvocation( | 3346 registry.registerDynamicInvocation( |
3346 new UniverseSelector(setterSelector, null)); | 3347 new UniverseSelector(setterSelector, null)); |
3347 registry.registerSuperNoSuchMethod(); | 3348 registry.registerSuperNoSuchMethod(); |
3348 break; | 3349 break; |
3349 case AccessKind.SUPER_METHOD: | 3350 case AccessKind.SUPER_METHOD: |
3350 compiler.reportWarningMessage( | 3351 reporter.reportWarningMessage( |
3351 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, | 3352 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, |
3352 {'name': name, | 3353 {'name': name, |
3353 'superclassName': semantics.setter.enclosingClass.name}); | 3354 'superclassName': semantics.setter.enclosingClass.name}); |
3354 // TODO(johnniwinther): This shouldn't be needed. | 3355 // TODO(johnniwinther): This shouldn't be needed. |
3355 registry.registerDynamicInvocation( | 3356 registry.registerDynamicInvocation( |
3356 new UniverseSelector(setterSelector, null)); | 3357 new UniverseSelector(setterSelector, null)); |
3357 registry.registerSuperNoSuchMethod(); | 3358 registry.registerSuperNoSuchMethod(); |
3358 break; | 3359 break; |
3359 default: | 3360 default: |
3360 registry.registerStaticInvocation(semantics.setter); | 3361 registry.registerStaticInvocation(semantics.setter); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3542 registry.setConstant(node, constant); | 3543 registry.setConstant(node, constant); |
3543 return new ConstantResult(node, constant); | 3544 return new ConstantResult(node, constant); |
3544 } | 3545 } |
3545 | 3546 |
3546 ConstantResult visitLiteralSymbol(LiteralSymbol node) { | 3547 ConstantResult visitLiteralSymbol(LiteralSymbol node) { |
3547 registry.registerInstantiatedClass(compiler.symbolClass); | 3548 registry.registerInstantiatedClass(compiler.symbolClass); |
3548 registry.registerStaticUse(compiler.symbolConstructor.declaration); | 3549 registry.registerStaticUse(compiler.symbolConstructor.declaration); |
3549 String name = node.slowNameString; | 3550 String name = node.slowNameString; |
3550 registry.registerConstSymbol(name); | 3551 registry.registerConstSymbol(name); |
3551 if (!validateSymbol(node, name, reportError: false)) { | 3552 if (!validateSymbol(node, name, reportError: false)) { |
3552 compiler.reportErrorMessage( | 3553 reporter.reportErrorMessage( |
3553 node, | 3554 node, |
3554 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, | 3555 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, |
3555 {'value': name}); | 3556 {'value': name}); |
3556 } | 3557 } |
3557 analyzeConstantDeferred(node); | 3558 analyzeConstantDeferred(node); |
3558 ConstantExpression constant = new SymbolConstantExpression(name); | 3559 ConstantExpression constant = new SymbolConstantExpression(name); |
3559 registry.setConstant(node, constant); | 3560 registry.setConstant(node, constant); |
3560 return new ConstantResult(node, constant); | 3561 return new ConstantResult(node, constant); |
3561 } | 3562 } |
3562 | 3563 |
(...skipping 12 matching lines...) Expand all Loading... |
3575 | 3576 |
3576 ResolutionResult visitNodeList(NodeList node) { | 3577 ResolutionResult visitNodeList(NodeList node) { |
3577 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 3578 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
3578 visit(link.head); | 3579 visit(link.head); |
3579 } | 3580 } |
3580 return const NoneResult(); | 3581 return const NoneResult(); |
3581 } | 3582 } |
3582 | 3583 |
3583 ResolutionResult visitRethrow(Rethrow node) { | 3584 ResolutionResult visitRethrow(Rethrow node) { |
3584 if (!inCatchBlock) { | 3585 if (!inCatchBlock) { |
3585 compiler.reportErrorMessage( | 3586 reporter.reportErrorMessage( |
3586 node, MessageKind.THROW_WITHOUT_EXPRESSION); | 3587 node, MessageKind.THROW_WITHOUT_EXPRESSION); |
3587 } | 3588 } |
3588 return const NoneResult(); | 3589 return const NoneResult(); |
3589 } | 3590 } |
3590 | 3591 |
3591 ResolutionResult visitReturn(Return node) { | 3592 ResolutionResult visitReturn(Return node) { |
3592 Node expression = node.expression; | 3593 Node expression = node.expression; |
3593 if (expression != null) { | 3594 if (expression != null) { |
3594 if (enclosingElement.isGenerativeConstructor) { | 3595 if (enclosingElement.isGenerativeConstructor) { |
3595 // It is a compile-time error if a return statement of the form | 3596 // It is a compile-time error if a return statement of the form |
3596 // `return e;` appears in a generative constructor. (Dart Language | 3597 // `return e;` appears in a generative constructor. (Dart Language |
3597 // Specification 13.12.) | 3598 // Specification 13.12.) |
3598 compiler.reportErrorMessage( | 3599 reporter.reportErrorMessage( |
3599 expression, | 3600 expression, |
3600 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); | 3601 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); |
3601 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { | 3602 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { |
3602 compiler.reportErrorMessage( | 3603 reporter.reportErrorMessage( |
3603 node, | 3604 node, |
3604 MessageKind.RETURN_IN_GENERATOR, | 3605 MessageKind.RETURN_IN_GENERATOR, |
3605 {'modifier': currentAsyncMarker}); | 3606 {'modifier': currentAsyncMarker}); |
3606 } | 3607 } |
3607 } | 3608 } |
3608 visit(node.expression); | 3609 visit(node.expression); |
3609 return const NoneResult(); | 3610 return const NoneResult(); |
3610 } | 3611 } |
3611 | 3612 |
3612 ResolutionResult visitYield(Yield node) { | 3613 ResolutionResult visitYield(Yield node) { |
3613 compiler.streamClass.ensureResolved(resolution); | 3614 compiler.streamClass.ensureResolved(resolution); |
3614 compiler.iterableClass.ensureResolved(resolution); | 3615 compiler.iterableClass.ensureResolved(resolution); |
3615 visit(node.expression); | 3616 visit(node.expression); |
3616 return const NoneResult(); | 3617 return const NoneResult(); |
3617 } | 3618 } |
3618 | 3619 |
3619 ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { | 3620 ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { |
3620 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; | 3621 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; |
3621 if (!enclosingElement.isFactoryConstructor) { | 3622 if (!enclosingElement.isFactoryConstructor) { |
3622 compiler.reportErrorMessage( | 3623 reporter.reportErrorMessage( |
3623 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 3624 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
3624 compiler.reportHintMessage( | 3625 reporter.reportHintMessage( |
3625 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); | 3626 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); |
3626 } | 3627 } |
3627 ConstructorElementX constructor = enclosingElement; | 3628 ConstructorElementX constructor = enclosingElement; |
3628 bool isConstConstructor = constructor.isConst; | 3629 bool isConstConstructor = constructor.isConst; |
3629 bool isValidAsConstant = isConstConstructor; | 3630 bool isValidAsConstant = isConstConstructor; |
3630 ConstructorElement redirectionTarget = resolveRedirectingFactory( | 3631 ConstructorElement redirectionTarget = resolveRedirectingFactory( |
3631 node, inConstContext: isConstConstructor).element; | 3632 node, inConstContext: isConstConstructor).element; |
3632 constructor.immediateRedirectionTarget = redirectionTarget; | 3633 constructor.immediateRedirectionTarget = redirectionTarget; |
3633 | 3634 |
3634 Node constructorReference = node.constructorReference; | 3635 Node constructorReference = node.constructorReference; |
3635 if (constructorReference is Send) { | 3636 if (constructorReference is Send) { |
3636 constructor.redirectionDeferredPrefix = | 3637 constructor.redirectionDeferredPrefix = |
3637 compiler.deferredLoadTask.deferredPrefixElement(constructorReference, | 3638 compiler.deferredLoadTask.deferredPrefixElement(constructorReference, |
3638 registry.mapping); | 3639 registry.mapping); |
3639 } | 3640 } |
3640 | 3641 |
3641 registry.setRedirectingTargetConstructor(node, redirectionTarget); | 3642 registry.setRedirectingTargetConstructor(node, redirectionTarget); |
3642 if (Elements.isUnresolved(redirectionTarget)) { | 3643 if (Elements.isUnresolved(redirectionTarget)) { |
3643 registry.registerThrowNoSuchMethod(); | 3644 registry.registerThrowNoSuchMethod(); |
3644 return const NoneResult(); | 3645 return const NoneResult(); |
3645 } else { | 3646 } else { |
3646 if (isConstConstructor && | 3647 if (isConstConstructor && |
3647 !redirectionTarget.isConst) { | 3648 !redirectionTarget.isConst) { |
3648 compiler.reportErrorMessage( | 3649 reporter.reportErrorMessage( |
3649 node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 3650 node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
3650 isValidAsConstant = false; | 3651 isValidAsConstant = false; |
3651 } | 3652 } |
3652 if (redirectionTarget == constructor) { | 3653 if (redirectionTarget == constructor) { |
3653 compiler.reportErrorMessage( | 3654 reporter.reportErrorMessage( |
3654 node, MessageKind.CYCLIC_REDIRECTING_FACTORY); | 3655 node, MessageKind.CYCLIC_REDIRECTING_FACTORY); |
3655 // TODO(johnniwinther): Create constant constructor for this case and | 3656 // TODO(johnniwinther): Create constant constructor for this case and |
3656 // let evaluation detect the cyclicity. | 3657 // let evaluation detect the cyclicity. |
3657 isValidAsConstant = false; | 3658 isValidAsConstant = false; |
3658 } | 3659 } |
3659 } | 3660 } |
3660 | 3661 |
3661 // Check that the target constructor is type compatible with the | 3662 // Check that the target constructor is type compatible with the |
3662 // redirecting constructor. | 3663 // redirecting constructor. |
3663 ClassElement targetClass = redirectionTarget.enclosingClass; | 3664 ClassElement targetClass = redirectionTarget.enclosingClass; |
3664 InterfaceType type = registry.getType(node); | 3665 InterfaceType type = registry.getType(node); |
3665 FunctionType targetType = redirectionTarget.computeType(resolution) | 3666 FunctionType targetType = redirectionTarget.computeType(resolution) |
3666 .subst(type.typeArguments, targetClass.typeVariables); | 3667 .subst(type.typeArguments, targetClass.typeVariables); |
3667 FunctionType constructorType = constructor.computeType(resolution); | 3668 FunctionType constructorType = constructor.computeType(resolution); |
3668 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); | 3669 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); |
3669 if (!isSubtype) { | 3670 if (!isSubtype) { |
3670 compiler.reportWarningMessage( | 3671 reporter.reportWarningMessage( |
3671 node, | 3672 node, |
3672 MessageKind.NOT_ASSIGNABLE, | 3673 MessageKind.NOT_ASSIGNABLE, |
3673 {'fromType': targetType, 'toType': constructorType}); | 3674 {'fromType': targetType, 'toType': constructorType}); |
3674 // TODO(johnniwinther): Handle this (potentially) erroneous case. | 3675 // TODO(johnniwinther): Handle this (potentially) erroneous case. |
3675 isValidAsConstant = false; | 3676 isValidAsConstant = false; |
3676 } | 3677 } |
3677 | 3678 |
3678 redirectionTarget.computeType(resolution); | 3679 redirectionTarget.computeType(resolution); |
3679 FunctionSignature targetSignature = redirectionTarget.functionSignature; | 3680 FunctionSignature targetSignature = redirectionTarget.functionSignature; |
3680 constructor.computeType(resolution); | 3681 constructor.computeType(resolution); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3753 Node modifierNode; | 3754 Node modifierNode; |
3754 for (Link<Node> nodes = modifiers.nodes.nodes; | 3755 for (Link<Node> nodes = modifiers.nodes.nodes; |
3755 !nodes.isEmpty; | 3756 !nodes.isEmpty; |
3756 nodes = nodes.tail) { | 3757 nodes = nodes.tail) { |
3757 if (modifier == nodes.head.asIdentifier().source) { | 3758 if (modifier == nodes.head.asIdentifier().source) { |
3758 modifierNode = nodes.head; | 3759 modifierNode = nodes.head; |
3759 break; | 3760 break; |
3760 } | 3761 } |
3761 } | 3762 } |
3762 assert(modifierNode != null); | 3763 assert(modifierNode != null); |
3763 compiler.reportErrorMessage( | 3764 reporter.reportErrorMessage( |
3764 modifierNode, MessageKind.EXTRANEOUS_MODIFIER, | 3765 modifierNode, MessageKind.EXTRANEOUS_MODIFIER, |
3765 {'modifier': modifier}); | 3766 {'modifier': modifier}); |
3766 } | 3767 } |
3767 if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) { | 3768 if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) { |
3768 reportExtraModifier('final'); | 3769 reportExtraModifier('final'); |
3769 } | 3770 } |
3770 if (modifiers.isVar && (modifiers.isConst || node.type != null)) { | 3771 if (modifiers.isVar && (modifiers.isConst || node.type != null)) { |
3771 reportExtraModifier('var'); | 3772 reportExtraModifier('var'); |
3772 } | 3773 } |
3773 if (enclosingElement.isFunction) { | 3774 if (enclosingElement.isFunction) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3830 constructor.computeType(resolution); | 3831 constructor.computeType(resolution); |
3831 if (!callSelector.applies(constructor, compiler.world)) { | 3832 if (!callSelector.applies(constructor, compiler.world)) { |
3832 registry.registerThrowNoSuchMethod(); | 3833 registry.registerThrowNoSuchMethod(); |
3833 } | 3834 } |
3834 | 3835 |
3835 // [constructor] might be the implementation element | 3836 // [constructor] might be the implementation element |
3836 // and only declaration elements may be registered. | 3837 // and only declaration elements may be registered. |
3837 registry.registerStaticUse(constructor.declaration); | 3838 registry.registerStaticUse(constructor.declaration); |
3838 ClassElement cls = constructor.enclosingClass; | 3839 ClassElement cls = constructor.enclosingClass; |
3839 if (cls.isEnumClass && currentClass != cls) { | 3840 if (cls.isEnumClass && currentClass != cls) { |
3840 compiler.reportErrorMessage( | 3841 reporter.reportErrorMessage( |
3841 node, | 3842 node, |
3842 MessageKind.CANNOT_INSTANTIATE_ENUM, | 3843 MessageKind.CANNOT_INSTANTIATE_ENUM, |
3843 {'enumName': cls.name}); | 3844 {'enumName': cls.name}); |
3844 isValidAsConstant = false; | 3845 isValidAsConstant = false; |
3845 } | 3846 } |
3846 | 3847 |
3847 InterfaceType type = registry.getType(node); | 3848 InterfaceType type = registry.getType(node); |
3848 if (node.isConst && type.containsTypeVariables) { | 3849 if (node.isConst && type.containsTypeVariables) { |
3849 compiler.reportErrorMessage( | 3850 reporter.reportErrorMessage( |
3850 node.send.selector, | 3851 node.send.selector, |
3851 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 3852 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
3852 isValidAsConstant = false; | 3853 isValidAsConstant = false; |
3853 } | 3854 } |
3854 // TODO(johniwinther): Avoid registration of `type` in face of redirecting | 3855 // TODO(johniwinther): Avoid registration of `type` in face of redirecting |
3855 // factory constructors. | 3856 // factory constructors. |
3856 registry.registerInstantiatedType(type); | 3857 registry.registerInstantiatedType(type); |
3857 if (constructor.isGenerativeConstructor && cls.isAbstract) { | 3858 if (constructor.isGenerativeConstructor && cls.isAbstract) { |
3858 isValidAsConstant = false; | 3859 isValidAsConstant = false; |
3859 } | 3860 } |
3860 | 3861 |
3861 if (isSymbolConstructor) { | 3862 if (isSymbolConstructor) { |
3862 if (node.isConst) { | 3863 if (node.isConst) { |
3863 Node argumentNode = node.send.arguments.head; | 3864 Node argumentNode = node.send.arguments.head; |
3864 ConstantExpression constant = | 3865 ConstantExpression constant = |
3865 compiler.resolver.constantCompiler.compileNode( | 3866 compiler.resolver.constantCompiler.compileNode( |
3866 argumentNode, registry.mapping); | 3867 argumentNode, registry.mapping); |
3867 ConstantValue name = compiler.constants.getConstantValue(constant); | 3868 ConstantValue name = compiler.constants.getConstantValue(constant); |
3868 if (!name.isString) { | 3869 if (!name.isString) { |
3869 DartType type = name.getType(coreTypes); | 3870 DartType type = name.getType(coreTypes); |
3870 compiler.reportErrorMessage( | 3871 reporter.reportErrorMessage( |
3871 argumentNode, | 3872 argumentNode, |
3872 MessageKind.STRING_EXPECTED, | 3873 MessageKind.STRING_EXPECTED, |
3873 {'type': type}); | 3874 {'type': type}); |
3874 } else { | 3875 } else { |
3875 StringConstantValue stringConstant = name; | 3876 StringConstantValue stringConstant = name; |
3876 String nameString = stringConstant.toDartString().slowToString(); | 3877 String nameString = stringConstant.toDartString().slowToString(); |
3877 if (validateSymbol(argumentNode, nameString)) { | 3878 if (validateSymbol(argumentNode, nameString)) { |
3878 registry.registerConstSymbol(nameString); | 3879 registry.registerConstSymbol(nameString); |
3879 } | 3880 } |
3880 } | 3881 } |
3881 } else { | 3882 } else { |
3882 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( | 3883 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( |
3883 enclosingElement)) { | 3884 enclosingElement)) { |
3884 compiler.reportHintMessage( | 3885 reporter.reportHintMessage( |
3885 node.newToken, MessageKind.NON_CONST_BLOAT, | 3886 node.newToken, MessageKind.NON_CONST_BLOAT, |
3886 {'name': compiler.symbolClass.name}); | 3887 {'name': compiler.symbolClass.name}); |
3887 } | 3888 } |
3888 registry.registerNewSymbol(); | 3889 registry.registerNewSymbol(); |
3889 } | 3890 } |
3890 } else if (isMirrorsUsedConstant) { | 3891 } else if (isMirrorsUsedConstant) { |
3891 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); | 3892 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); |
3892 } | 3893 } |
3893 if (node.isConst) { | 3894 if (node.isConst) { |
3894 analyzeConstantDeferred(node); | 3895 analyzeConstantDeferred(node); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3928 void checkConstMapKeysDontOverrideEquals(Spannable spannable, | 3929 void checkConstMapKeysDontOverrideEquals(Spannable spannable, |
3929 MapConstantValue map) { | 3930 MapConstantValue map) { |
3930 for (ConstantValue key in map.keys) { | 3931 for (ConstantValue key in map.keys) { |
3931 if (!key.isObject) continue; | 3932 if (!key.isObject) continue; |
3932 ObjectConstantValue objectConstant = key; | 3933 ObjectConstantValue objectConstant = key; |
3933 DartType keyType = objectConstant.type; | 3934 DartType keyType = objectConstant.type; |
3934 ClassElement cls = keyType.element; | 3935 ClassElement cls = keyType.element; |
3935 if (cls == compiler.stringClass) continue; | 3936 if (cls == compiler.stringClass) continue; |
3936 Element equals = cls.lookupMember('=='); | 3937 Element equals = cls.lookupMember('=='); |
3937 if (equals.enclosingClass != compiler.objectClass) { | 3938 if (equals.enclosingClass != compiler.objectClass) { |
3938 compiler.reportErrorMessage( | 3939 reporter.reportErrorMessage( |
3939 spannable, | 3940 spannable, |
3940 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, | 3941 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, |
3941 {'type': keyType}); | 3942 {'type': keyType}); |
3942 } | 3943 } |
3943 } | 3944 } |
3944 } | 3945 } |
3945 | 3946 |
3946 void analyzeConstant(Node node, {enforceConst: true}) { | 3947 void analyzeConstant(Node node, {enforceConst: true}) { |
3947 ConstantExpression constant = | 3948 ConstantExpression constant = |
3948 compiler.resolver.constantCompiler.compileNode( | 3949 compiler.resolver.constantCompiler.compileNode( |
(...skipping 13 matching lines...) Expand all Loading... |
3962 void analyzeConstantDeferred(Node node, {bool enforceConst: true}) { | 3963 void analyzeConstantDeferred(Node node, {bool enforceConst: true}) { |
3963 addDeferredAction(enclosingElement, () { | 3964 addDeferredAction(enclosingElement, () { |
3964 analyzeConstant(node, enforceConst: enforceConst); | 3965 analyzeConstant(node, enforceConst: enforceConst); |
3965 }); | 3966 }); |
3966 } | 3967 } |
3967 | 3968 |
3968 bool validateSymbol(Node node, String name, {bool reportError: true}) { | 3969 bool validateSymbol(Node node, String name, {bool reportError: true}) { |
3969 if (name.isEmpty) return true; | 3970 if (name.isEmpty) return true; |
3970 if (name.startsWith('_')) { | 3971 if (name.startsWith('_')) { |
3971 if (reportError) { | 3972 if (reportError) { |
3972 compiler.reportErrorMessage( | 3973 reporter.reportErrorMessage( |
3973 node, MessageKind.PRIVATE_IDENTIFIER, {'value': name}); | 3974 node, MessageKind.PRIVATE_IDENTIFIER, {'value': name}); |
3974 } | 3975 } |
3975 return false; | 3976 return false; |
3976 } | 3977 } |
3977 if (!symbolValidationPattern.hasMatch(name)) { | 3978 if (!symbolValidationPattern.hasMatch(name)) { |
3978 if (reportError) { | 3979 if (reportError) { |
3979 compiler.reportErrorMessage( | 3980 reporter.reportErrorMessage( |
3980 node, MessageKind.INVALID_SYMBOL, {'value': name}); | 3981 node, MessageKind.INVALID_SYMBOL, {'value': name}); |
3981 } | 3982 } |
3982 return false; | 3983 return false; |
3983 } | 3984 } |
3984 return true; | 3985 return true; |
3985 } | 3986 } |
3986 | 3987 |
3987 /** | 3988 /** |
3988 * Try to resolve the constructor that is referred to by [node]. | 3989 * Try to resolve the constructor that is referred to by [node]. |
3989 * Note: this function may return an ErroneousFunctionElement instead of | 3990 * Note: this function may return an ErroneousFunctionElement instead of |
(...skipping 26 matching lines...) Expand all Loading... |
4016 ResolutionResult visitLiteralList(LiteralList node) { | 4017 ResolutionResult visitLiteralList(LiteralList node) { |
4017 bool isValidAsConstant = true; | 4018 bool isValidAsConstant = true; |
4018 sendIsMemberAccess = false; | 4019 sendIsMemberAccess = false; |
4019 | 4020 |
4020 NodeList arguments = node.typeArguments; | 4021 NodeList arguments = node.typeArguments; |
4021 DartType typeArgument; | 4022 DartType typeArgument; |
4022 if (arguments != null) { | 4023 if (arguments != null) { |
4023 Link<Node> nodes = arguments.nodes; | 4024 Link<Node> nodes = arguments.nodes; |
4024 if (nodes.isEmpty) { | 4025 if (nodes.isEmpty) { |
4025 // The syntax [: <>[] :] is not allowed. | 4026 // The syntax [: <>[] :] is not allowed. |
4026 compiler.reportErrorMessage( | 4027 reporter.reportErrorMessage( |
4027 arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 4028 arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
4028 isValidAsConstant = false; | 4029 isValidAsConstant = false; |
4029 } else { | 4030 } else { |
4030 typeArgument = resolveTypeAnnotation(nodes.head); | 4031 typeArgument = resolveTypeAnnotation(nodes.head); |
4031 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 4032 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
4032 compiler.reportWarningMessage( | 4033 reporter.reportWarningMessage( |
4033 nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 4034 nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
4034 resolveTypeAnnotation(nodes.head); | 4035 resolveTypeAnnotation(nodes.head); |
4035 } | 4036 } |
4036 } | 4037 } |
4037 } | 4038 } |
4038 DartType listType; | 4039 DartType listType; |
4039 if (typeArgument != null) { | 4040 if (typeArgument != null) { |
4040 if (node.isConst && typeArgument.containsTypeVariables) { | 4041 if (node.isConst && typeArgument.containsTypeVariables) { |
4041 compiler.reportErrorMessage( | 4042 reporter.reportErrorMessage( |
4042 arguments.nodes.head, | 4043 arguments.nodes.head, |
4043 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 4044 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
4044 isValidAsConstant = false; | 4045 isValidAsConstant = false; |
4045 } | 4046 } |
4046 listType = coreTypes.listType(typeArgument); | 4047 listType = coreTypes.listType(typeArgument); |
4047 } else { | 4048 } else { |
4048 listType = coreTypes.listType(); | 4049 listType = coreTypes.listType(); |
4049 } | 4050 } |
4050 registry.setType(node, listType); | 4051 registry.setType(node, listType); |
4051 registry.registerInstantiatedType(listType); | 4052 registry.registerInstantiatedType(listType); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4126 return new ConstantResult(node, constant); | 4127 return new ConstantResult(node, constant); |
4127 } | 4128 } |
4128 return const NoneResult(); | 4129 return const NoneResult(); |
4129 } | 4130 } |
4130 | 4131 |
4131 ResolutionResult visitBreakStatement(BreakStatement node) { | 4132 ResolutionResult visitBreakStatement(BreakStatement node) { |
4132 JumpTarget target; | 4133 JumpTarget target; |
4133 if (node.target == null) { | 4134 if (node.target == null) { |
4134 target = statementScope.currentBreakTarget(); | 4135 target = statementScope.currentBreakTarget(); |
4135 if (target == null) { | 4136 if (target == null) { |
4136 compiler.reportErrorMessage( | 4137 reporter.reportErrorMessage( |
4137 node, MessageKind.NO_BREAK_TARGET); | 4138 node, MessageKind.NO_BREAK_TARGET); |
4138 return const NoneResult(); | 4139 return const NoneResult(); |
4139 } | 4140 } |
4140 target.isBreakTarget = true; | 4141 target.isBreakTarget = true; |
4141 } else { | 4142 } else { |
4142 String labelName = node.target.source; | 4143 String labelName = node.target.source; |
4143 LabelDefinition label = statementScope.lookupLabel(labelName); | 4144 LabelDefinition label = statementScope.lookupLabel(labelName); |
4144 if (label == null) { | 4145 if (label == null) { |
4145 compiler.reportErrorMessage( | 4146 reporter.reportErrorMessage( |
4146 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 4147 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
4147 return const NoneResult(); | 4148 return const NoneResult(); |
4148 } | 4149 } |
4149 target = label.target; | 4150 target = label.target; |
4150 if (!target.statement.isValidBreakTarget()) { | 4151 if (!target.statement.isValidBreakTarget()) { |
4151 compiler.reportErrorMessage( | 4152 reporter.reportErrorMessage( |
4152 node.target, MessageKind.INVALID_BREAK); | 4153 node.target, MessageKind.INVALID_BREAK); |
4153 return const NoneResult(); | 4154 return const NoneResult(); |
4154 } | 4155 } |
4155 label.setBreakTarget(); | 4156 label.setBreakTarget(); |
4156 registry.useLabel(node, label); | 4157 registry.useLabel(node, label); |
4157 } | 4158 } |
4158 registry.registerTargetOf(node, target); | 4159 registry.registerTargetOf(node, target); |
4159 return const NoneResult(); | 4160 return const NoneResult(); |
4160 } | 4161 } |
4161 | 4162 |
4162 ResolutionResult visitContinueStatement(ContinueStatement node) { | 4163 ResolutionResult visitContinueStatement(ContinueStatement node) { |
4163 JumpTarget target; | 4164 JumpTarget target; |
4164 if (node.target == null) { | 4165 if (node.target == null) { |
4165 target = statementScope.currentContinueTarget(); | 4166 target = statementScope.currentContinueTarget(); |
4166 if (target == null) { | 4167 if (target == null) { |
4167 compiler.reportErrorMessage( | 4168 reporter.reportErrorMessage( |
4168 node, MessageKind.NO_CONTINUE_TARGET); | 4169 node, MessageKind.NO_CONTINUE_TARGET); |
4169 return const NoneResult(); | 4170 return const NoneResult(); |
4170 } | 4171 } |
4171 target.isContinueTarget = true; | 4172 target.isContinueTarget = true; |
4172 } else { | 4173 } else { |
4173 String labelName = node.target.source; | 4174 String labelName = node.target.source; |
4174 LabelDefinition label = statementScope.lookupLabel(labelName); | 4175 LabelDefinition label = statementScope.lookupLabel(labelName); |
4175 if (label == null) { | 4176 if (label == null) { |
4176 compiler.reportErrorMessage( | 4177 reporter.reportErrorMessage( |
4177 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 4178 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
4178 return const NoneResult(); | 4179 return const NoneResult(); |
4179 } | 4180 } |
4180 target = label.target; | 4181 target = label.target; |
4181 if (!target.statement.isValidContinueTarget()) { | 4182 if (!target.statement.isValidContinueTarget()) { |
4182 compiler.reportErrorMessage( | 4183 reporter.reportErrorMessage( |
4183 node.target, MessageKind.INVALID_CONTINUE); | 4184 node.target, MessageKind.INVALID_CONTINUE); |
4184 } | 4185 } |
4185 label.setContinueTarget(); | 4186 label.setContinueTarget(); |
4186 registry.useLabel(node, label); | 4187 registry.useLabel(node, label); |
4187 } | 4188 } |
4188 registry.registerTargetOf(node, target); | 4189 registry.registerTargetOf(node, target); |
4189 return const NoneResult(); | 4190 return const NoneResult(); |
4190 } | 4191 } |
4191 | 4192 |
4192 registerImplicitInvocation(Selector selector) { | 4193 registerImplicitInvocation(Selector selector) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4243 | 4244 |
4244 Send send = declaration.asSend(); | 4245 Send send = declaration.asSend(); |
4245 VariableDefinitions variableDefinitions = | 4246 VariableDefinitions variableDefinitions = |
4246 declaration.asVariableDefinitions(); | 4247 declaration.asVariableDefinitions(); |
4247 Element loopVariable; | 4248 Element loopVariable; |
4248 Selector loopVariableSelector; | 4249 Selector loopVariableSelector; |
4249 if (send != null) { | 4250 if (send != null) { |
4250 loopVariable = registry.getDefinition(send); | 4251 loopVariable = registry.getDefinition(send); |
4251 Identifier identifier = send.selector.asIdentifier(); | 4252 Identifier identifier = send.selector.asIdentifier(); |
4252 if (identifier == null) { | 4253 if (identifier == null) { |
4253 compiler.reportErrorMessage( | 4254 reporter.reportErrorMessage( |
4254 send.selector, MessageKind.INVALID_FOR_IN); | 4255 send.selector, MessageKind.INVALID_FOR_IN); |
4255 } else { | 4256 } else { |
4256 loopVariableSelector = new Selector.setter( | 4257 loopVariableSelector = new Selector.setter( |
4257 new Name(identifier.source, library)); | 4258 new Name(identifier.source, library)); |
4258 } | 4259 } |
4259 if (send.receiver != null) { | 4260 if (send.receiver != null) { |
4260 compiler.reportErrorMessage( | 4261 reporter.reportErrorMessage( |
4261 send.receiver, MessageKind.INVALID_FOR_IN); | 4262 send.receiver, MessageKind.INVALID_FOR_IN); |
4262 } | 4263 } |
4263 } else if (variableDefinitions != null) { | 4264 } else if (variableDefinitions != null) { |
4264 Link<Node> nodes = variableDefinitions.definitions.nodes; | 4265 Link<Node> nodes = variableDefinitions.definitions.nodes; |
4265 if (!nodes.tail.isEmpty) { | 4266 if (!nodes.tail.isEmpty) { |
4266 compiler.reportErrorMessage( | 4267 reporter.reportErrorMessage( |
4267 nodes.tail.head, MessageKind.INVALID_FOR_IN); | 4268 nodes.tail.head, MessageKind.INVALID_FOR_IN); |
4268 } | 4269 } |
4269 Node first = nodes.head; | 4270 Node first = nodes.head; |
4270 Identifier identifier = first.asIdentifier(); | 4271 Identifier identifier = first.asIdentifier(); |
4271 if (identifier == null) { | 4272 if (identifier == null) { |
4272 compiler.reportErrorMessage( | 4273 reporter.reportErrorMessage( |
4273 first, MessageKind.INVALID_FOR_IN); | 4274 first, MessageKind.INVALID_FOR_IN); |
4274 } else { | 4275 } else { |
4275 loopVariableSelector = new Selector.setter( | 4276 loopVariableSelector = new Selector.setter( |
4276 new Name(identifier.source, library)); | 4277 new Name(identifier.source, library)); |
4277 loopVariable = registry.getDefinition(identifier); | 4278 loopVariable = registry.getDefinition(identifier); |
4278 } | 4279 } |
4279 } else { | 4280 } else { |
4280 compiler.reportErrorMessage( | 4281 reporter.reportErrorMessage( |
4281 declaration, MessageKind.INVALID_FOR_IN); | 4282 declaration, MessageKind.INVALID_FOR_IN); |
4282 } | 4283 } |
4283 if (loopVariableSelector != null) { | 4284 if (loopVariableSelector != null) { |
4284 registry.setSelector(declaration, loopVariableSelector); | 4285 registry.setSelector(declaration, loopVariableSelector); |
4285 registerSend(loopVariableSelector, loopVariable); | 4286 registerSend(loopVariableSelector, loopVariable); |
4286 } else { | 4287 } else { |
4287 // The selector may only be null if we reported an error. | 4288 // The selector may only be null if we reported an error. |
4288 assert(invariant(declaration, compiler.compilationFailed)); | 4289 assert(invariant(declaration, compiler.compilationFailed)); |
4289 } | 4290 } |
4290 if (loopVariable != null) { | 4291 if (loopVariable != null) { |
(...skipping 16 matching lines...) Expand all Loading... |
4307 LabelDefinition element = targetElement.addLabel(label, labelName); | 4308 LabelDefinition element = targetElement.addLabel(label, labelName); |
4308 labelElements[labelName] = element; | 4309 labelElements[labelName] = element; |
4309 } | 4310 } |
4310 statementScope.enterLabelScope(labelElements); | 4311 statementScope.enterLabelScope(labelElements); |
4311 visit(node.statement); | 4312 visit(node.statement); |
4312 statementScope.exitLabelScope(); | 4313 statementScope.exitLabelScope(); |
4313 labelElements.forEach((String labelName, LabelDefinition element) { | 4314 labelElements.forEach((String labelName, LabelDefinition element) { |
4314 if (element.isTarget) { | 4315 if (element.isTarget) { |
4315 registry.defineLabel(element.label, element); | 4316 registry.defineLabel(element.label, element); |
4316 } else { | 4317 } else { |
4317 compiler.reportWarningMessage( | 4318 reporter.reportWarningMessage( |
4318 element.label, | 4319 element.label, |
4319 MessageKind.UNUSED_LABEL, | 4320 MessageKind.UNUSED_LABEL, |
4320 {'labelName': labelName}); | 4321 {'labelName': labelName}); |
4321 } | 4322 } |
4322 }); | 4323 }); |
4323 if (!targetElement.isTarget) { | 4324 if (!targetElement.isTarget) { |
4324 registry.undefineTarget(body); | 4325 registry.undefineTarget(body); |
4325 } | 4326 } |
4326 return const NoneResult(); | 4327 return const NoneResult(); |
4327 } | 4328 } |
4328 | 4329 |
4329 ResolutionResult visitLiteralMap(LiteralMap node) { | 4330 ResolutionResult visitLiteralMap(LiteralMap node) { |
4330 bool isValidAsConstant = true; | 4331 bool isValidAsConstant = true; |
4331 sendIsMemberAccess = false; | 4332 sendIsMemberAccess = false; |
4332 | 4333 |
4333 NodeList arguments = node.typeArguments; | 4334 NodeList arguments = node.typeArguments; |
4334 DartType keyTypeArgument; | 4335 DartType keyTypeArgument; |
4335 DartType valueTypeArgument; | 4336 DartType valueTypeArgument; |
4336 if (arguments != null) { | 4337 if (arguments != null) { |
4337 Link<Node> nodes = arguments.nodes; | 4338 Link<Node> nodes = arguments.nodes; |
4338 if (nodes.isEmpty) { | 4339 if (nodes.isEmpty) { |
4339 // The syntax [: <>{} :] is not allowed. | 4340 // The syntax [: <>{} :] is not allowed. |
4340 compiler.reportErrorMessage( | 4341 reporter.reportErrorMessage( |
4341 arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 4342 arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
4342 isValidAsConstant = false; | 4343 isValidAsConstant = false; |
4343 } else { | 4344 } else { |
4344 keyTypeArgument = resolveTypeAnnotation(nodes.head); | 4345 keyTypeArgument = resolveTypeAnnotation(nodes.head); |
4345 nodes = nodes.tail; | 4346 nodes = nodes.tail; |
4346 if (nodes.isEmpty) { | 4347 if (nodes.isEmpty) { |
4347 compiler.reportWarningMessage( | 4348 reporter.reportWarningMessage( |
4348 arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 4349 arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
4349 } else { | 4350 } else { |
4350 valueTypeArgument = resolveTypeAnnotation(nodes.head); | 4351 valueTypeArgument = resolveTypeAnnotation(nodes.head); |
4351 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 4352 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
4352 compiler.reportWarningMessage( | 4353 reporter.reportWarningMessage( |
4353 nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 4354 nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
4354 resolveTypeAnnotation(nodes.head); | 4355 resolveTypeAnnotation(nodes.head); |
4355 } | 4356 } |
4356 } | 4357 } |
4357 } | 4358 } |
4358 } | 4359 } |
4359 DartType mapType; | 4360 DartType mapType; |
4360 if (valueTypeArgument != null) { | 4361 if (valueTypeArgument != null) { |
4361 mapType = coreTypes.mapType(keyTypeArgument, valueTypeArgument); | 4362 mapType = coreTypes.mapType(keyTypeArgument, valueTypeArgument); |
4362 } else { | 4363 } else { |
4363 mapType = coreTypes.mapType(); | 4364 mapType = coreTypes.mapType(); |
4364 } | 4365 } |
4365 if (node.isConst && mapType.containsTypeVariables) { | 4366 if (node.isConst && mapType.containsTypeVariables) { |
4366 compiler.reportErrorMessage( | 4367 reporter.reportErrorMessage( |
4367 arguments, | 4368 arguments, |
4368 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 4369 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
4369 isValidAsConstant = false; | 4370 isValidAsConstant = false; |
4370 } | 4371 } |
4371 registry.registerMapLiteral(node, mapType, node.isConst); | 4372 registry.registerMapLiteral(node, mapType, node.isConst); |
4372 registry.registerRequiredType(mapType, enclosingElement); | 4373 registry.registerRequiredType(mapType, enclosingElement); |
4373 if (node.isConst) { | 4374 if (node.isConst) { |
4374 | 4375 |
4375 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; | 4376 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; |
4376 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; | 4377 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4454 ConstantValue value = compiler.constants.getConstantValue(constant); | 4455 ConstantValue value = compiler.constants.getConstantValue(constant); |
4455 DartType caseType = typeOfConstant(value); | 4456 DartType caseType = typeOfConstant(value); |
4456 | 4457 |
4457 if (firstCaseType == null) { | 4458 if (firstCaseType == null) { |
4458 firstCase = caseMatch; | 4459 firstCase = caseMatch; |
4459 firstCaseType = caseType; | 4460 firstCaseType = caseType; |
4460 | 4461 |
4461 // We only report the bad type on the first class element. All others | 4462 // We only report the bad type on the first class element. All others |
4462 // get a "type differs" error. | 4463 // get a "type differs" error. |
4463 if (caseType.element == compiler.doubleClass) { | 4464 if (caseType.element == compiler.doubleClass) { |
4464 compiler.reportErrorMessage( | 4465 reporter.reportErrorMessage( |
4465 node, | 4466 node, |
4466 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, | 4467 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, |
4467 {'type': "double"}); | 4468 {'type': "double"}); |
4468 } else if (caseType.element == compiler.functionClass) { | 4469 } else if (caseType.element == compiler.functionClass) { |
4469 compiler.reportErrorMessage( | 4470 reporter.reportErrorMessage( |
4470 node, MessageKind.SWITCH_CASE_FORBIDDEN, | 4471 node, MessageKind.SWITCH_CASE_FORBIDDEN, |
4471 {'type': "Function"}); | 4472 {'type': "Function"}); |
4472 } else if (value.isObject && overridesEquals(caseType)) { | 4473 } else if (value.isObject && overridesEquals(caseType)) { |
4473 compiler.reportErrorMessage( | 4474 reporter.reportErrorMessage( |
4474 firstCase.expression, | 4475 firstCase.expression, |
4475 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, | 4476 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, |
4476 {'type': caseType}); | 4477 {'type': caseType}); |
4477 } | 4478 } |
4478 } else { | 4479 } else { |
4479 if (caseType != firstCaseType) { | 4480 if (caseType != firstCaseType) { |
4480 if (error == null) { | 4481 if (error == null) { |
4481 error = compiler.createMessage( | 4482 error = reporter.createMessage( |
4482 node, | 4483 node, |
4483 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL, | 4484 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL, |
4484 {'type': firstCaseType}); | 4485 {'type': firstCaseType}); |
4485 infos.add(compiler.createMessage( | 4486 infos.add(reporter.createMessage( |
4486 firstCase.expression, | 4487 firstCase.expression, |
4487 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, | 4488 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, |
4488 {'type': firstCaseType})); | 4489 {'type': firstCaseType})); |
4489 } | 4490 } |
4490 infos.add(compiler.createMessage( | 4491 infos.add(reporter.createMessage( |
4491 caseMatch.expression, | 4492 caseMatch.expression, |
4492 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, | 4493 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, |
4493 {'type': caseType})); | 4494 {'type': caseType})); |
4494 } | 4495 } |
4495 } | 4496 } |
4496 } | 4497 } |
4497 } | 4498 } |
4498 if (error != null) { | 4499 if (error != null) { |
4499 compiler.reportError(error, infos); | 4500 reporter.reportError(error, infos); |
4500 } | 4501 } |
4501 } | 4502 } |
4502 | 4503 |
4503 ResolutionResult visitSwitchStatement(SwitchStatement node) { | 4504 ResolutionResult visitSwitchStatement(SwitchStatement node) { |
4504 node.expression.accept(this); | 4505 node.expression.accept(this); |
4505 | 4506 |
4506 JumpTarget breakElement = getOrDefineTarget(node); | 4507 JumpTarget breakElement = getOrDefineTarget(node); |
4507 Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{}; | 4508 Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{}; |
4508 Link<Node> cases = node.cases.nodes; | 4509 Link<Node> cases = node.cases.nodes; |
4509 while (!cases.isEmpty) { | 4510 while (!cases.isEmpty) { |
4510 SwitchCase switchCase = cases.head; | 4511 SwitchCase switchCase = cases.head; |
4511 for (Node labelOrCase in switchCase.labelsAndCases) { | 4512 for (Node labelOrCase in switchCase.labelsAndCases) { |
4512 CaseMatch caseMatch = labelOrCase.asCaseMatch(); | 4513 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
4513 if (caseMatch != null) { | 4514 if (caseMatch != null) { |
4514 analyzeConstantDeferred(caseMatch.expression); | 4515 analyzeConstantDeferred(caseMatch.expression); |
4515 continue; | 4516 continue; |
4516 } | 4517 } |
4517 Label label = labelOrCase; | 4518 Label label = labelOrCase; |
4518 String labelName = label.labelName; | 4519 String labelName = label.labelName; |
4519 | 4520 |
4520 LabelDefinition existingElement = continueLabels[labelName]; | 4521 LabelDefinition existingElement = continueLabels[labelName]; |
4521 if (existingElement != null) { | 4522 if (existingElement != null) { |
4522 // It's an error if the same label occurs twice in the same switch. | 4523 // It's an error if the same label occurs twice in the same switch. |
4523 compiler.reportError( | 4524 reporter.reportError( |
4524 compiler.createMessage( | 4525 reporter.createMessage( |
4525 label, | 4526 label, |
4526 MessageKind.DUPLICATE_LABEL, | 4527 MessageKind.DUPLICATE_LABEL, |
4527 {'labelName': labelName}), | 4528 {'labelName': labelName}), |
4528 <DiagnosticMessage>[ | 4529 <DiagnosticMessage>[ |
4529 compiler.createMessage( | 4530 reporter.createMessage( |
4530 existingElement.label, | 4531 existingElement.label, |
4531 MessageKind.EXISTING_LABEL, | 4532 MessageKind.EXISTING_LABEL, |
4532 {'labelName': labelName}), | 4533 {'labelName': labelName}), |
4533 ]); | 4534 ]); |
4534 } else { | 4535 } else { |
4535 // It's only a warning if it shadows another label. | 4536 // It's only a warning if it shadows another label. |
4536 existingElement = statementScope.lookupLabel(labelName); | 4537 existingElement = statementScope.lookupLabel(labelName); |
4537 if (existingElement != null) { | 4538 if (existingElement != null) { |
4538 compiler.reportWarning( | 4539 reporter.reportWarning( |
4539 compiler.createMessage( | 4540 reporter.createMessage( |
4540 label, | 4541 label, |
4541 MessageKind.DUPLICATE_LABEL, | 4542 MessageKind.DUPLICATE_LABEL, |
4542 {'labelName': labelName}), | 4543 {'labelName': labelName}), |
4543 <DiagnosticMessage>[ | 4544 <DiagnosticMessage>[ |
4544 compiler.createMessage( | 4545 reporter.createMessage( |
4545 existingElement.label, | 4546 existingElement.label, |
4546 MessageKind.EXISTING_LABEL, | 4547 MessageKind.EXISTING_LABEL, |
4547 {'labelName': labelName}), | 4548 {'labelName': labelName}), |
4548 ]); | 4549 ]); |
4549 } | 4550 } |
4550 } | 4551 } |
4551 | 4552 |
4552 JumpTarget targetElement = getOrDefineTarget(switchCase); | 4553 JumpTarget targetElement = getOrDefineTarget(switchCase); |
4553 LabelDefinition labelElement = targetElement.addLabel(label, labelName); | 4554 LabelDefinition labelElement = targetElement.addLabel(label, labelName); |
4554 registry.defineLabel(label, labelElement); | 4555 registry.defineLabel(label, labelElement); |
4555 continueLabels[labelName] = labelElement; | 4556 continueLabels[labelName] = labelElement; |
4556 } | 4557 } |
4557 cases = cases.tail; | 4558 cases = cases.tail; |
4558 // Test that only the last case, if any, is a default case. | 4559 // Test that only the last case, if any, is a default case. |
4559 if (switchCase.defaultKeyword != null && !cases.isEmpty) { | 4560 if (switchCase.defaultKeyword != null && !cases.isEmpty) { |
4560 compiler.reportErrorMessage( | 4561 reporter.reportErrorMessage( |
4561 switchCase, MessageKind.INVALID_CASE_DEFAULT); | 4562 switchCase, MessageKind.INVALID_CASE_DEFAULT); |
4562 } | 4563 } |
4563 } | 4564 } |
4564 | 4565 |
4565 addDeferredAction(enclosingElement, () { | 4566 addDeferredAction(enclosingElement, () { |
4566 checkCaseExpressions(node); | 4567 checkCaseExpressions(node); |
4567 }); | 4568 }); |
4568 | 4569 |
4569 statementScope.enterSwitch(breakElement, continueLabels); | 4570 statementScope.enterSwitch(breakElement, continueLabels); |
4570 node.cases.accept(this); | 4571 node.cases.accept(this); |
(...skipping 25 matching lines...) Expand all Loading... |
4596 return const NoneResult(); | 4597 return const NoneResult(); |
4597 } | 4598 } |
4598 | 4599 |
4599 ResolutionResult visitTryStatement(TryStatement node) { | 4600 ResolutionResult visitTryStatement(TryStatement node) { |
4600 // TODO(karlklose): also track the information about mutated variables, | 4601 // TODO(karlklose): also track the information about mutated variables, |
4601 // catch, and finally-block. | 4602 // catch, and finally-block. |
4602 registry.registerTryStatement(); | 4603 registry.registerTryStatement(); |
4603 | 4604 |
4604 visit(node.tryBlock); | 4605 visit(node.tryBlock); |
4605 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { | 4606 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { |
4606 compiler.reportErrorMessage( | 4607 reporter.reportErrorMessage( |
4607 node.getEndToken().next, MessageKind.NO_CATCH_NOR_FINALLY); | 4608 node.getEndToken().next, MessageKind.NO_CATCH_NOR_FINALLY); |
4608 } | 4609 } |
4609 visit(node.catchBlocks); | 4610 visit(node.catchBlocks); |
4610 visit(node.finallyBlock); | 4611 visit(node.finallyBlock); |
4611 return const NoneResult(); | 4612 return const NoneResult(); |
4612 } | 4613 } |
4613 | 4614 |
4614 ResolutionResult visitCatchBlock(CatchBlock node) { | 4615 ResolutionResult visitCatchBlock(CatchBlock node) { |
4615 registry.registerCatchStatement(); | 4616 registry.registerCatchStatement(); |
4616 // Check that if catch part is present, then | 4617 // Check that if catch part is present, then |
4617 // it has one or two formal parameters. | 4618 // it has one or two formal parameters. |
4618 VariableDefinitions exceptionDefinition; | 4619 VariableDefinitions exceptionDefinition; |
4619 VariableDefinitions stackTraceDefinition; | 4620 VariableDefinitions stackTraceDefinition; |
4620 if (node.formals != null) { | 4621 if (node.formals != null) { |
4621 Link<Node> formalsToProcess = node.formals.nodes; | 4622 Link<Node> formalsToProcess = node.formals.nodes; |
4622 if (formalsToProcess.isEmpty) { | 4623 if (formalsToProcess.isEmpty) { |
4623 compiler.reportErrorMessage( | 4624 reporter.reportErrorMessage( |
4624 node, MessageKind.EMPTY_CATCH_DECLARATION); | 4625 node, MessageKind.EMPTY_CATCH_DECLARATION); |
4625 } else { | 4626 } else { |
4626 exceptionDefinition = formalsToProcess.head.asVariableDefinitions(); | 4627 exceptionDefinition = formalsToProcess.head.asVariableDefinitions(); |
4627 formalsToProcess = formalsToProcess.tail; | 4628 formalsToProcess = formalsToProcess.tail; |
4628 if (!formalsToProcess.isEmpty) { | 4629 if (!formalsToProcess.isEmpty) { |
4629 stackTraceDefinition = formalsToProcess.head.asVariableDefinitions(); | 4630 stackTraceDefinition = formalsToProcess.head.asVariableDefinitions(); |
4630 formalsToProcess = formalsToProcess.tail; | 4631 formalsToProcess = formalsToProcess.tail; |
4631 if (!formalsToProcess.isEmpty) { | 4632 if (!formalsToProcess.isEmpty) { |
4632 for (Node extra in formalsToProcess) { | 4633 for (Node extra in formalsToProcess) { |
4633 compiler.reportErrorMessage( | 4634 reporter.reportErrorMessage( |
4634 extra, MessageKind.EXTRA_CATCH_DECLARATION); | 4635 extra, MessageKind.EXTRA_CATCH_DECLARATION); |
4635 } | 4636 } |
4636 } | 4637 } |
4637 registry.registerStackTraceInCatch(); | 4638 registry.registerStackTraceInCatch(); |
4638 } | 4639 } |
4639 } | 4640 } |
4640 | 4641 |
4641 // Check that the formals aren't optional and that they have no | 4642 // Check that the formals aren't optional and that they have no |
4642 // modifiers or type. | 4643 // modifiers or type. |
4643 for (Link<Node> link = node.formals.nodes; | 4644 for (Link<Node> link = node.formals.nodes; |
4644 !link.isEmpty; | 4645 !link.isEmpty; |
4645 link = link.tail) { | 4646 link = link.tail) { |
4646 // If the formal parameter is a node list, it means that it is a | 4647 // If the formal parameter is a node list, it means that it is a |
4647 // sequence of optional parameters. | 4648 // sequence of optional parameters. |
4648 NodeList nodeList = link.head.asNodeList(); | 4649 NodeList nodeList = link.head.asNodeList(); |
4649 if (nodeList != null) { | 4650 if (nodeList != null) { |
4650 compiler.reportErrorMessage( | 4651 reporter.reportErrorMessage( |
4651 nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); | 4652 nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); |
4652 } else { | 4653 } else { |
4653 VariableDefinitions declaration = link.head; | 4654 VariableDefinitions declaration = link.head; |
4654 for (Node modifier in declaration.modifiers.nodes) { | 4655 for (Node modifier in declaration.modifiers.nodes) { |
4655 compiler.reportErrorMessage( | 4656 reporter.reportErrorMessage( |
4656 modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); | 4657 modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); |
4657 } | 4658 } |
4658 TypeAnnotation type = declaration.type; | 4659 TypeAnnotation type = declaration.type; |
4659 if (type != null) { | 4660 if (type != null) { |
4660 compiler.reportErrorMessage( | 4661 reporter.reportErrorMessage( |
4661 type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); | 4662 type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); |
4662 } | 4663 } |
4663 } | 4664 } |
4664 } | 4665 } |
4665 } | 4666 } |
4666 | 4667 |
4667 Scope blockScope = new BlockScope(scope); | 4668 Scope blockScope = new BlockScope(scope); |
4668 doInCheckContext(() => visitIn(node.type, blockScope)); | 4669 doInCheckContext(() => visitIn(node.type, blockScope)); |
4669 visitIn(node.formals, blockScope); | 4670 visitIn(node.formals, blockScope); |
4670 var oldInCatchBlock = inCatchBlock; | 4671 var oldInCatchBlock = inCatchBlock; |
(...skipping 13 matching lines...) Expand all Loading... |
4684 VariableElementX stackTraceElement = | 4685 VariableElementX stackTraceElement = |
4685 registry.getDefinition(stackTraceVariable); | 4686 registry.getDefinition(stackTraceVariable); |
4686 registry.registerInstantiatedClass(compiler.stackTraceClass); | 4687 registry.registerInstantiatedClass(compiler.stackTraceClass); |
4687 stackTraceElement.variables.type = compiler.stackTraceClass.rawType; | 4688 stackTraceElement.variables.type = compiler.stackTraceClass.rawType; |
4688 } | 4689 } |
4689 return const NoneResult(); | 4690 return const NoneResult(); |
4690 } | 4691 } |
4691 } | 4692 } |
4692 | 4693 |
4693 /// Looks up [name] in [scope] and unwraps the result. | 4694 /// Looks up [name] in [scope] and unwraps the result. |
4694 Element lookupInScope(Compiler compiler, Node node, | 4695 Element lookupInScope(DiagnosticReporter reporter, Node node, |
4695 Scope scope, String name) { | 4696 Scope scope, String name) { |
4696 return Elements.unwrap(scope.lookup(name), compiler, node); | 4697 return Elements.unwrap(scope.lookup(name), reporter, node); |
4697 } | 4698 } |
OLD | NEW |