| 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 |