| 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.dart'; | 7 import '../common.dart'; |
| 8 import '../common/names.dart' show | 8 import '../common/names.dart' show |
| 9 Selectors; | 9 Selectors; |
| 10 import '../compiler.dart' show | 10 import '../compiler.dart' show |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 JumpTarget element = registry.getTargetDefinition(statement); | 221 JumpTarget element = registry.getTargetDefinition(statement); |
| 222 if (element == null) { | 222 if (element == null) { |
| 223 element = new JumpTargetX(statement, | 223 element = new JumpTargetX(statement, |
| 224 statementScope.nestingLevel, | 224 statementScope.nestingLevel, |
| 225 enclosingElement); | 225 enclosingElement); |
| 226 registry.defineTarget(statement, element); | 226 registry.defineTarget(statement, element); |
| 227 } | 227 } |
| 228 return element; | 228 return element; |
| 229 } | 229 } |
| 230 | 230 |
| 231 doInCheckContext(action()) { | |
| 232 bool wasInCheckContext = inCheckContext; | |
| 233 inCheckContext = true; | |
| 234 var result = action(); | |
| 235 inCheckContext = wasInCheckContext; | |
| 236 return result; | |
| 237 } | |
| 238 | |
| 239 doInPromotionScope(Node node, action()) { | 231 doInPromotionScope(Node node, action()) { |
| 240 promotionScope = promotionScope.prepend(node); | 232 promotionScope = promotionScope.prepend(node); |
| 241 var result = action(); | 233 var result = action(); |
| 242 promotionScope = promotionScope.tail; | 234 promotionScope = promotionScope.tail; |
| 243 return result; | 235 return result; |
| 244 } | 236 } |
| 245 | 237 |
| 246 inStaticContext(action(), | 238 inStaticContext(action(), |
| 247 {bool inConstantInitializer: false}) { | 239 {bool inConstantInitializer: false}) { |
| 248 bool wasInstanceContext = inInstanceContext; | 240 bool wasInstanceContext = inInstanceContext; |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 632 // Run the body in a fresh statement scope. | 624 // Run the body in a fresh statement scope. |
| 633 StatementScope oldStatementScope = statementScope; | 625 StatementScope oldStatementScope = statementScope; |
| 634 statementScope = new StatementScope(); | 626 statementScope = new StatementScope(); |
| 635 visit(node.body); | 627 visit(node.body); |
| 636 statementScope = oldStatementScope; | 628 statementScope = oldStatementScope; |
| 637 | 629 |
| 638 scope = oldScope; | 630 scope = oldScope; |
| 639 enclosingElement = previousEnclosingElement; | 631 enclosingElement = previousEnclosingElement; |
| 640 | 632 |
| 641 registry.registerClosure(function); | 633 registry.registerClosure(function); |
| 642 registry.registerInstantiatedClass(compiler.functionClass); | |
| 643 return const NoneResult(); | 634 return const NoneResult(); |
| 644 } | 635 } |
| 645 | 636 |
| 646 ResolutionResult visitIf(If node) { | 637 ResolutionResult visitIf(If node) { |
| 647 doInPromotionScope(node.condition.expression, () => visit(node.condition)); | 638 doInPromotionScope(node.condition.expression, () => visit(node.condition)); |
| 648 doInPromotionScope(node.thenPart, | 639 doInPromotionScope(node.thenPart, |
| 649 () => visitIn(node.thenPart, new BlockScope(scope))); | 640 () => visitIn(node.thenPart, new BlockScope(scope))); |
| 650 visitIn(node.elsePart, new BlockScope(scope)); | 641 visitIn(node.elsePart, new BlockScope(scope)); |
| 651 return const NoneResult(); | 642 return const NoneResult(); |
| 652 } | 643 } |
| (...skipping 2872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3525 } | 3516 } |
| 3526 | 3517 |
| 3527 ConstantResult visitLiteralNull(LiteralNull node) { | 3518 ConstantResult visitLiteralNull(LiteralNull node) { |
| 3528 registry.registerInstantiatedType(coreTypes.nullType); | 3519 registry.registerInstantiatedType(coreTypes.nullType); |
| 3529 ConstantExpression constant = new NullConstantExpression(); | 3520 ConstantExpression constant = new NullConstantExpression(); |
| 3530 registry.setConstant(node, constant); | 3521 registry.setConstant(node, constant); |
| 3531 return new ConstantResult(node, constant); | 3522 return new ConstantResult(node, constant); |
| 3532 } | 3523 } |
| 3533 | 3524 |
| 3534 ConstantResult visitLiteralSymbol(LiteralSymbol node) { | 3525 ConstantResult visitLiteralSymbol(LiteralSymbol node) { |
| 3535 registry.registerInstantiatedClass(compiler.symbolClass); | |
| 3536 registry.registerStaticUse(compiler.symbolConstructor.declaration); | |
| 3537 String name = node.slowNameString; | 3526 String name = node.slowNameString; |
| 3538 registry.registerConstSymbol(name); | 3527 registry.registerConstSymbol(name); |
| 3539 if (!validateSymbol(node, name, reportError: false)) { | 3528 if (!validateSymbol(node, name, reportError: false)) { |
| 3540 reporter.reportErrorMessage( | 3529 reporter.reportErrorMessage( |
| 3541 node, | 3530 node, |
| 3542 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, | 3531 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, |
| 3543 {'value': name}); | 3532 {'value': name}); |
| 3544 } | 3533 } |
| 3545 analyzeConstantDeferred(node); | 3534 analyzeConstantDeferred(node); |
| 3546 ConstantExpression constant = new SymbolConstantExpression(name); | 3535 ConstantExpression constant = new SymbolConstantExpression(name); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3643 // TODO(johnniwinther): Create constant constructor for this case and | 3632 // TODO(johnniwinther): Create constant constructor for this case and |
| 3644 // let evaluation detect the cyclicity. | 3633 // let evaluation detect the cyclicity. |
| 3645 isValidAsConstant = false; | 3634 isValidAsConstant = false; |
| 3646 } | 3635 } |
| 3647 } | 3636 } |
| 3648 | 3637 |
| 3649 // Check that the target constructor is type compatible with the | 3638 // Check that the target constructor is type compatible with the |
| 3650 // redirecting constructor. | 3639 // redirecting constructor. |
| 3651 ClassElement targetClass = redirectionTarget.enclosingClass; | 3640 ClassElement targetClass = redirectionTarget.enclosingClass; |
| 3652 InterfaceType type = registry.getType(node); | 3641 InterfaceType type = registry.getType(node); |
| 3653 FunctionType targetType = redirectionTarget.computeType(resolution) | 3642 FunctionType targetConstructorType = |
| 3654 .subst(type.typeArguments, targetClass.typeVariables); | 3643 redirectionTarget.computeType(resolution) |
| 3644 .subst(type.typeArguments, targetClass.typeVariables); |
| 3655 FunctionType constructorType = constructor.computeType(resolution); | 3645 FunctionType constructorType = constructor.computeType(resolution); |
| 3656 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); | 3646 bool isSubtype = compiler.types.isSubtype( |
| 3647 targetConstructorType, constructorType); |
| 3657 if (!isSubtype) { | 3648 if (!isSubtype) { |
| 3658 reporter.reportWarningMessage( | 3649 reporter.reportWarningMessage( |
| 3659 node, | 3650 node, |
| 3660 MessageKind.NOT_ASSIGNABLE, | 3651 MessageKind.NOT_ASSIGNABLE, |
| 3661 {'fromType': targetType, 'toType': constructorType}); | 3652 {'fromType': targetConstructorType, 'toType': constructorType}); |
| 3662 // TODO(johnniwinther): Handle this (potentially) erroneous case. | 3653 // TODO(johnniwinther): Handle this (potentially) erroneous case. |
| 3663 isValidAsConstant = false; | 3654 isValidAsConstant = false; |
| 3664 } | 3655 } |
| 3665 | 3656 |
| 3666 redirectionTarget.computeType(resolution); | 3657 redirectionTarget.computeType(resolution); |
| 3667 FunctionSignature targetSignature = redirectionTarget.functionSignature; | 3658 FunctionSignature targetSignature = redirectionTarget.functionSignature; |
| 3668 constructor.computeType(resolution); | 3659 constructor.computeType(resolution); |
| 3669 FunctionSignature constructorSignature = constructor.functionSignature; | 3660 FunctionSignature constructorSignature = constructor.functionSignature; |
| 3670 if (!targetSignature.isCompatibleWith(constructorSignature)) { | 3661 if (!targetSignature.isCompatibleWith(constructorSignature)) { |
| 3671 assert(!isSubtype); | 3662 assert(!isSubtype); |
| 3672 registry.registerThrowNoSuchMethod(); | 3663 registry.registerThrowNoSuchMethod(); |
| 3673 isValidAsConstant = false; | 3664 isValidAsConstant = false; |
| 3674 } | 3665 } |
| 3675 | 3666 |
| 3676 // Register a post process to check for cycles in the redirection chain and | 3667 // Register a post process to check for cycles in the redirection chain and |
| 3677 // set the actual generative constructor at the end of the chain. | 3668 // set the actual generative constructor at the end of the chain. |
| 3678 addDeferredAction(constructor, () { | 3669 addDeferredAction(constructor, () { |
| 3679 compiler.resolver.resolveRedirectionChain(constructor, node); | 3670 compiler.resolver.resolveRedirectionChain(constructor, node); |
| 3680 }); | 3671 }); |
| 3681 | 3672 |
| 3682 registry.registerStaticUse(redirectionTarget); | 3673 registry.registerStaticUse(redirectionTarget); |
| 3683 // TODO(johnniwinther): Register the effective target type instead. | 3674 // TODO(johnniwinther): Register the effective target type instead. |
| 3684 registry.registerInstantiatedClass( | 3675 registry.registerInstantiatedType( |
| 3685 redirectionTarget.enclosingClass.declaration); | 3676 redirectionTarget.enclosingClass.thisType |
| 3677 .subst(type.typeArguments, targetClass.typeVariables)); |
| 3686 if (isSymbolConstructor) { | 3678 if (isSymbolConstructor) { |
| 3687 registry.registerSymbolConstructor(); | 3679 registry.registerSymbolConstructor(); |
| 3688 } | 3680 } |
| 3689 if (isValidAsConstant) { | 3681 if (isValidAsConstant) { |
| 3690 List<String> names = <String>[]; | 3682 List<String> names = <String>[]; |
| 3691 List<ConstantExpression> arguments = <ConstantExpression>[]; | 3683 List<ConstantExpression> arguments = <ConstantExpression>[]; |
| 3692 int index = 0; | 3684 int index = 0; |
| 3693 constructorSignature.forEachParameter((ParameterElement parameter) { | 3685 constructorSignature.forEachParameter((ParameterElement parameter) { |
| 3694 if (parameter.isNamed) { | 3686 if (parameter.isNamed) { |
| 3695 String name = parameter.name; | 3687 String name = parameter.name; |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3988 } | 3980 } |
| 3989 | 3981 |
| 3990 DartType resolveTypeAnnotation(TypeAnnotation node, | 3982 DartType resolveTypeAnnotation(TypeAnnotation node, |
| 3991 {bool malformedIsError: false, | 3983 {bool malformedIsError: false, |
| 3992 bool deferredIsMalformed: true}) { | 3984 bool deferredIsMalformed: true}) { |
| 3993 DartType type = typeResolver.resolveTypeAnnotation( | 3985 DartType type = typeResolver.resolveTypeAnnotation( |
| 3994 this, node, malformedIsError: malformedIsError, | 3986 this, node, malformedIsError: malformedIsError, |
| 3995 deferredIsMalformed: deferredIsMalformed); | 3987 deferredIsMalformed: deferredIsMalformed); |
| 3996 if (inCheckContext) { | 3988 if (inCheckContext) { |
| 3997 registry.registerCheckedModeCheck(type); | 3989 registry.registerCheckedModeCheck(type); |
| 3998 registry.registerRequiredType(type, enclosingElement); | |
| 3999 } | 3990 } |
| 4000 return type; | 3991 return type; |
| 4001 } | 3992 } |
| 4002 | 3993 |
| 4003 ResolutionResult visitLiteralList(LiteralList node) { | 3994 ResolutionResult visitLiteralList(LiteralList node) { |
| 4004 bool isValidAsConstant = true; | 3995 bool isValidAsConstant = true; |
| 4005 sendIsMemberAccess = false; | 3996 sendIsMemberAccess = false; |
| 4006 | 3997 |
| 4007 NodeList arguments = node.typeArguments; | 3998 NodeList arguments = node.typeArguments; |
| 4008 DartType typeArgument; | 3999 DartType typeArgument; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 4032 } | 4023 } |
| 4033 listType = coreTypes.listType(typeArgument); | 4024 listType = coreTypes.listType(typeArgument); |
| 4034 } else { | 4025 } else { |
| 4035 listType = coreTypes.listType(); | 4026 listType = coreTypes.listType(); |
| 4036 } | 4027 } |
| 4037 registry.registerLiteralList( | 4028 registry.registerLiteralList( |
| 4038 node, | 4029 node, |
| 4039 listType, | 4030 listType, |
| 4040 isConstant: node.isConst, | 4031 isConstant: node.isConst, |
| 4041 isEmpty: node.elements.isEmpty); | 4032 isEmpty: node.elements.isEmpty); |
| 4042 registry.registerRequiredType(listType, enclosingElement); | |
| 4043 if (node.isConst) { | 4033 if (node.isConst) { |
| 4044 List<ConstantExpression> constantExpressions = <ConstantExpression>[]; | 4034 List<ConstantExpression> constantExpressions = <ConstantExpression>[]; |
| 4045 inConstantContext(() { | 4035 inConstantContext(() { |
| 4046 for (Node element in node.elements) { | 4036 for (Node element in node.elements) { |
| 4047 ResolutionResult elementResult = visit(element); | 4037 ResolutionResult elementResult = visit(element); |
| 4048 if (isValidAsConstant && elementResult.isConstant) { | 4038 if (isValidAsConstant && elementResult.isConstant) { |
| 4049 constantExpressions.add(elementResult.constant); | 4039 constantExpressions.add(elementResult.constant); |
| 4050 } else { | 4040 } else { |
| 4051 isValidAsConstant = false; | 4041 isValidAsConstant = false; |
| 4052 } | 4042 } |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4356 reporter.reportErrorMessage( | 4346 reporter.reportErrorMessage( |
| 4357 arguments, | 4347 arguments, |
| 4358 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 4348 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 4359 isValidAsConstant = false; | 4349 isValidAsConstant = false; |
| 4360 } | 4350 } |
| 4361 registry.registerMapLiteral( | 4351 registry.registerMapLiteral( |
| 4362 node, | 4352 node, |
| 4363 mapType, | 4353 mapType, |
| 4364 isConstant: node.isConst, | 4354 isConstant: node.isConst, |
| 4365 isEmpty: node.entries.isEmpty); | 4355 isEmpty: node.entries.isEmpty); |
| 4366 registry.registerRequiredType(mapType, enclosingElement); | 4356 |
| 4367 if (node.isConst) { | 4357 if (node.isConst) { |
| 4368 | |
| 4369 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; | 4358 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; |
| 4370 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; | 4359 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; |
| 4371 inConstantContext(() { | 4360 inConstantContext(() { |
| 4372 for (LiteralMapEntry entry in node.entries) { | 4361 for (LiteralMapEntry entry in node.entries) { |
| 4373 ResolutionResult keyResult = visit(entry.key); | 4362 ResolutionResult keyResult = visit(entry.key); |
| 4374 ResolutionResult valueResult = visit(entry.value); | 4363 ResolutionResult valueResult = visit(entry.value); |
| 4375 if (isValidAsConstant && | 4364 if (isValidAsConstant && |
| 4376 keyResult.isConstant && | 4365 keyResult.isConstant && |
| 4377 valueResult.isConstant) { | 4366 valueResult.isConstant) { |
| 4378 keyExpressions.add(keyResult.constant); | 4367 keyExpressions.add(keyResult.constant); |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4652 TypeAnnotation type = declaration.type; | 4641 TypeAnnotation type = declaration.type; |
| 4653 if (type != null) { | 4642 if (type != null) { |
| 4654 reporter.reportErrorMessage( | 4643 reporter.reportErrorMessage( |
| 4655 type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); | 4644 type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); |
| 4656 } | 4645 } |
| 4657 } | 4646 } |
| 4658 } | 4647 } |
| 4659 } | 4648 } |
| 4660 | 4649 |
| 4661 Scope blockScope = new BlockScope(scope); | 4650 Scope blockScope = new BlockScope(scope); |
| 4662 doInCheckContext(() => visitIn(node.type, blockScope)); | 4651 TypeResult exceptionTypeResult = visitIn(node.type, blockScope); |
| 4663 visitIn(node.formals, blockScope); | 4652 visitIn(node.formals, blockScope); |
| 4664 var oldInCatchBlock = inCatchBlock; | 4653 var oldInCatchBlock = inCatchBlock; |
| 4665 inCatchBlock = true; | 4654 inCatchBlock = true; |
| 4666 visitIn(node.block, blockScope); | 4655 visitIn(node.block, blockScope); |
| 4667 inCatchBlock = oldInCatchBlock; | 4656 inCatchBlock = oldInCatchBlock; |
| 4668 | 4657 |
| 4669 if (node.type != null && exceptionDefinition != null) { | 4658 if (exceptionTypeResult != null) { |
| 4670 DartType exceptionType = registry.getType(node.type); | 4659 DartType exceptionType = exceptionTypeResult.type; |
| 4671 Node exceptionVariable = exceptionDefinition.definitions.nodes.head; | 4660 if (exceptionDefinition != null) { |
| 4672 VariableElementX exceptionElement = | 4661 Node exceptionVariable = exceptionDefinition.definitions.nodes.head; |
| 4673 registry.getDefinition(exceptionVariable); | 4662 VariableElementX exceptionElement = |
| 4674 exceptionElement.variables.type = exceptionType; | 4663 registry.getDefinition(exceptionVariable); |
| 4664 exceptionElement.variables.type = exceptionType; |
| 4665 } |
| 4666 registry.registerOnCatchType(exceptionType); |
| 4675 } | 4667 } |
| 4676 if (stackTraceDefinition != null) { | 4668 if (stackTraceDefinition != null) { |
| 4677 Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head; | 4669 Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head; |
| 4678 VariableElementX stackTraceElement = | 4670 VariableElementX stackTraceElement = |
| 4679 registry.getDefinition(stackTraceVariable); | 4671 registry.getDefinition(stackTraceVariable); |
| 4680 registry.registerInstantiatedClass(compiler.stackTraceClass); | 4672 InterfaceType stackTraceType = coreTypes.stackTraceType; |
| 4681 stackTraceElement.variables.type = compiler.stackTraceClass.rawType; | 4673 stackTraceElement.variables.type = stackTraceType; |
| 4682 } | 4674 } |
| 4683 return const NoneResult(); | 4675 return const NoneResult(); |
| 4684 } | 4676 } |
| 4685 } | 4677 } |
| 4686 | 4678 |
| 4687 /// Looks up [name] in [scope] and unwraps the result. | 4679 /// Looks up [name] in [scope] and unwraps the result. |
| 4688 Element lookupInScope(DiagnosticReporter reporter, Node node, | 4680 Element lookupInScope(DiagnosticReporter reporter, Node node, |
| 4689 Scope scope, String name) { | 4681 Scope scope, String name) { |
| 4690 return Elements.unwrap(scope.lookup(name), reporter, node); | 4682 return Elements.unwrap(scope.lookup(name), reporter, node); |
| 4691 } | 4683 } |
| OLD | NEW |