Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 engine.resolver; | 5 library engine.resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'ast.dart'; | 9 import 'ast.dart'; |
| 10 import 'constant.dart'; | 10 import 'constant.dart'; |
| (...skipping 2535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2546 * A flag indicating whether a variable declaration is within the body of a me thod or function. | 2546 * A flag indicating whether a variable declaration is within the body of a me thod or function. |
| 2547 */ | 2547 */ |
| 2548 bool _inFunction = false; | 2548 bool _inFunction = false; |
| 2549 | 2549 |
| 2550 /** | 2550 /** |
| 2551 * A flag indicating whether the class currently being visited can be used as a mixin. | 2551 * A flag indicating whether the class currently being visited can be used as a mixin. |
| 2552 */ | 2552 */ |
| 2553 bool _isValidMixin = false; | 2553 bool _isValidMixin = false; |
| 2554 | 2554 |
| 2555 /** | 2555 /** |
| 2556 * A collection holding the elements defined in a class that need to have | |
| 2557 * their function type fixed to take into account type parameters of the | |
| 2558 * enclosing class, or `null` if we are not currently processing nodes within | |
| 2559 * a class. | |
| 2560 */ | |
| 2561 List<ExecutableElementImpl> _functionTypesToFix = null; | |
| 2562 | |
| 2563 /** | |
| 2556 * A table mapping field names to field elements for the fields defined in the current class, or | 2564 * A table mapping field names to field elements for the fields defined in the current class, or |
| 2557 * `null` if we are not in the scope of a class. | 2565 * `null` if we are not in the scope of a class. |
| 2558 */ | 2566 */ |
| 2559 HashMap<String, FieldElement> _fieldMap; | 2567 HashMap<String, FieldElement> _fieldMap; |
| 2560 | 2568 |
| 2561 /** | 2569 /** |
| 2562 * Initialize a newly created element builder to build the elements for a comp ilation unit. | 2570 * Initialize a newly created element builder to build the elements for a comp ilation unit. |
| 2563 * | 2571 * |
| 2564 * @param initialHolder the element holder associated with the compilation uni t being built | 2572 * @param initialHolder the element holder associated with the compilation uni t being built |
| 2565 */ | 2573 */ |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2600 stackTraceParameter.staticElement = stackTrace; | 2608 stackTraceParameter.staticElement = stackTrace; |
| 2601 } | 2609 } |
| 2602 } | 2610 } |
| 2603 return super.visitCatchClause(node); | 2611 return super.visitCatchClause(node); |
| 2604 } | 2612 } |
| 2605 | 2613 |
| 2606 @override | 2614 @override |
| 2607 Object visitClassDeclaration(ClassDeclaration node) { | 2615 Object visitClassDeclaration(ClassDeclaration node) { |
| 2608 ElementHolder holder = new ElementHolder(); | 2616 ElementHolder holder = new ElementHolder(); |
| 2609 _isValidMixin = true; | 2617 _isValidMixin = true; |
| 2618 _functionTypesToFix = new List<ExecutableElementImpl>(); | |
| 2610 // | 2619 // |
| 2611 // Process field declarations before constructors and methods so that field | 2620 // Process field declarations before constructors and methods so that field |
| 2612 // formal parameters can be correctly resolved to their fields. | 2621 // formal parameters can be correctly resolved to their fields. |
| 2613 // | 2622 // |
| 2614 ElementHolder previousHolder = _currentHolder; | 2623 ElementHolder previousHolder = _currentHolder; |
| 2615 _currentHolder = holder; | 2624 _currentHolder = holder; |
| 2616 try { | 2625 try { |
| 2617 List<ClassMember> nonFields = new List<ClassMember>(); | 2626 List<ClassMember> nonFields = new List<ClassMember>(); |
| 2618 node.visitChildren( | 2627 node.visitChildren( |
| 2619 new _ElementBuilder_visitClassDeclaration(this, nonFields)); | 2628 new _ElementBuilder_visitClassDeclaration(this, nonFields)); |
| 2620 _buildFieldMap(holder.fieldsWithoutFlushing); | 2629 _buildFieldMap(holder.fieldsWithoutFlushing); |
| 2621 int count = nonFields.length; | 2630 int count = nonFields.length; |
| 2622 for (int i = 0; i < count; i++) { | 2631 for (int i = 0; i < count; i++) { |
| 2623 nonFields[i].accept(this); | 2632 nonFields[i].accept(this); |
| 2624 } | 2633 } |
| 2625 } finally { | 2634 } finally { |
| 2626 _currentHolder = previousHolder; | 2635 _currentHolder = previousHolder; |
| 2627 } | 2636 } |
| 2628 SimpleIdentifier className = node.name; | 2637 SimpleIdentifier className = node.name; |
| 2629 ClassElementImpl element = new ClassElementImpl.forNode(className); | 2638 ClassElementImpl element = new ClassElementImpl.forNode(className); |
| 2630 List<TypeParameterElement> typeParameters = holder.typeParameters; | 2639 List<TypeParameterElement> typeParameters = holder.typeParameters; |
| 2631 List<DartType> typeArguments = _createTypeParameterTypes(typeParameters); | 2640 List<DartType> typeArguments = _createTypeParameterTypes(typeParameters); |
| 2632 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element); | 2641 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element); |
| 2633 interfaceType.typeArguments = typeArguments; | 2642 interfaceType.typeArguments = typeArguments; |
| 2634 element.type = interfaceType; | 2643 element.type = interfaceType; |
| 2635 List<ConstructorElement> constructors = holder.constructors; | 2644 element.typeParameters = typeParameters; |
| 2636 if (constructors.length == 0) { | |
| 2637 // | |
| 2638 // Create the default constructor. | |
| 2639 // | |
| 2640 constructors = _createDefaultConstructors(interfaceType); | |
| 2641 } | |
| 2642 _setDocRange(element, node); | 2645 _setDocRange(element, node); |
| 2643 element.abstract = node.isAbstract; | 2646 element.abstract = node.isAbstract; |
| 2644 element.accessors = holder.accessors; | 2647 element.accessors = holder.accessors; |
| 2648 List<ConstructorElement> constructors = holder.constructors; | |
| 2649 if (constructors.isEmpty) { | |
| 2650 constructors = _createDefaultConstructors(element); | |
| 2651 } | |
| 2645 element.constructors = constructors; | 2652 element.constructors = constructors; |
| 2646 element.fields = holder.fields; | 2653 element.fields = holder.fields; |
| 2647 element.methods = holder.methods; | 2654 element.methods = holder.methods; |
| 2648 element.typeParameters = typeParameters; | |
| 2649 element.validMixin = _isValidMixin; | 2655 element.validMixin = _isValidMixin; |
| 2656 // Function types must be initialized after the enclosing element has been | |
| 2657 // set, for them to pick up the type parameters. | |
| 2658 for (ExecutableElementImpl e in _functionTypesToFix) { | |
| 2659 e.type = new FunctionTypeImpl(e); | |
| 2660 } | |
| 2661 _functionTypesToFix = null; | |
|
Brian Wilkerson
2015/11/16 20:53:04
Consider moving these six lines into a separate me
Jennifer Messerly
2015/11/16 21:45:44
Done. It does not appear to be needed in visitClas
| |
| 2650 _currentHolder.addType(element); | 2662 _currentHolder.addType(element); |
| 2651 className.staticElement = element; | 2663 className.staticElement = element; |
| 2652 _fieldMap = null; | 2664 _fieldMap = null; |
| 2653 holder.validate(); | 2665 holder.validate(); |
| 2654 return null; | 2666 return null; |
| 2655 } | 2667 } |
| 2656 | 2668 |
| 2657 /** | 2669 /** |
| 2658 * Implementation of this method should be synchronized with | 2670 * Implementation of this method should be synchronized with |
| 2659 * [visitClassDeclaration]. | 2671 * [visitClassDeclaration]. |
| 2660 */ | 2672 */ |
| 2661 void visitClassDeclarationIncrementally(ClassDeclaration node) { | 2673 void visitClassDeclarationIncrementally(ClassDeclaration node) { |
| 2662 // | 2674 // |
| 2663 // Process field declarations before constructors and methods so that field | 2675 // Process field declarations before constructors and methods so that field |
| 2664 // formal parameters can be correctly resolved to their fields. | 2676 // formal parameters can be correctly resolved to their fields. |
| 2665 // | 2677 // |
| 2666 ClassElement classElement = node.element; | 2678 ClassElement classElement = node.element; |
| 2667 _buildFieldMap(classElement.fields); | 2679 _buildFieldMap(classElement.fields); |
| 2668 } | 2680 } |
| 2669 | 2681 |
| 2670 @override | 2682 @override |
| 2671 Object visitClassTypeAlias(ClassTypeAlias node) { | 2683 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 2672 ElementHolder holder = new ElementHolder(); | 2684 ElementHolder holder = new ElementHolder(); |
| 2685 _functionTypesToFix = new List<ExecutableElementImpl>(); | |
|
Brian Wilkerson
2015/11/16 20:53:04
Can a ClassTypeAlias actually contain executable e
Jennifer Messerly
2015/11/16 21:45:44
Restored it mainly because the original code had i
| |
| 2673 _visitChildren(holder, node); | 2686 _visitChildren(holder, node); |
| 2674 SimpleIdentifier className = node.name; | 2687 SimpleIdentifier className = node.name; |
| 2675 ClassElementImpl element = new ClassElementImpl.forNode(className); | 2688 ClassElementImpl element = new ClassElementImpl.forNode(className); |
| 2676 element.abstract = node.abstractKeyword != null; | 2689 element.abstract = node.abstractKeyword != null; |
| 2677 element.mixinApplication = true; | 2690 element.mixinApplication = true; |
| 2678 List<TypeParameterElement> typeParameters = holder.typeParameters; | 2691 List<TypeParameterElement> typeParameters = holder.typeParameters; |
| 2679 element.typeParameters = typeParameters; | 2692 element.typeParameters = typeParameters; |
| 2680 List<DartType> typeArguments = _createTypeParameterTypes(typeParameters); | 2693 List<DartType> typeArguments = _createTypeParameterTypes(typeParameters); |
| 2681 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element); | 2694 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element); |
| 2682 interfaceType.typeArguments = typeArguments; | 2695 interfaceType.typeArguments = typeArguments; |
| 2683 element.type = interfaceType; | 2696 element.type = interfaceType; |
| 2697 // set default constructor's function type | |
| 2698 for (ExecutableElementImpl e in _functionTypesToFix) { | |
| 2699 e.type = new FunctionTypeImpl(e); | |
| 2700 } | |
| 2701 _functionTypesToFix = null; | |
| 2684 _currentHolder.addType(element); | 2702 _currentHolder.addType(element); |
| 2685 className.staticElement = element; | 2703 className.staticElement = element; |
| 2686 holder.validate(); | 2704 holder.validate(); |
| 2687 return null; | 2705 return null; |
| 2688 } | 2706 } |
| 2689 | 2707 |
| 2690 @override | 2708 @override |
| 2691 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 2709 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 2692 _isValidMixin = false; | 2710 _isValidMixin = false; |
| 2693 ElementHolder holder = new ElementHolder(); | 2711 ElementHolder holder = new ElementHolder(); |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3012 element.generator = true; | 3030 element.generator = true; |
| 3013 } | 3031 } |
| 3014 if (_inFunction) { | 3032 if (_inFunction) { |
| 3015 Block enclosingBlock = node.getAncestor((node) => node is Block); | 3033 Block enclosingBlock = node.getAncestor((node) => node is Block); |
| 3016 if (enclosingBlock != null) { | 3034 if (enclosingBlock != null) { |
| 3017 int functionEnd = node.offset + node.length; | 3035 int functionEnd = node.offset + node.length; |
| 3018 int blockEnd = enclosingBlock.offset + enclosingBlock.length; | 3036 int blockEnd = enclosingBlock.offset + enclosingBlock.length; |
| 3019 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); | 3037 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); |
| 3020 } | 3038 } |
| 3021 } | 3039 } |
| 3022 element.type = new FunctionTypeImpl(element); | 3040 if (_functionTypesToFix != null) { |
| 3041 _functionTypesToFix.add(element); | |
| 3042 } else { | |
| 3043 // TODO(jmesserly): for local functions inside of top-level generic | |
| 3044 // functions, this is probably not right. The function type should be set | |
| 3045 // after the enclosingElement is set, otherwise we won't be able to | |
| 3046 // substitute those type parameters later. | |
|
Brian Wilkerson
2015/11/16 20:53:04
I assume the longer term fix is to either (a) crea
Jennifer Messerly
2015/11/16 21:45:44
nice, yeah, I think either of those would work gre
Brian Wilkerson
2015/11/16 21:55:30
I fairly sure that's the case, but I'd have to dou
| |
| 3047 element.type = new FunctionTypeImpl(element); | |
| 3048 } | |
| 3023 element.hasImplicitReturnType = true; | 3049 element.hasImplicitReturnType = true; |
| 3024 _currentHolder.addFunction(element); | 3050 _currentHolder.addFunction(element); |
| 3025 node.element = element; | 3051 node.element = element; |
| 3026 holder.validate(); | 3052 holder.validate(); |
| 3027 return null; | 3053 return null; |
| 3028 } | 3054 } |
| 3029 | 3055 |
| 3030 @override | 3056 @override |
| 3031 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 3057 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 3032 ElementHolder holder = new ElementHolder(); | 3058 ElementHolder holder = new ElementHolder(); |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3415 } | 3441 } |
| 3416 } | 3442 } |
| 3417 | 3443 |
| 3418 /** | 3444 /** |
| 3419 * Creates the [ConstructorElement]s array with the single default constructor element. | 3445 * Creates the [ConstructorElement]s array with the single default constructor element. |
| 3420 * | 3446 * |
| 3421 * @param interfaceType the interface type for which to create a default const ructor | 3447 * @param interfaceType the interface type for which to create a default const ructor |
| 3422 * @return the [ConstructorElement]s array with the single default constructor element | 3448 * @return the [ConstructorElement]s array with the single default constructor element |
| 3423 */ | 3449 */ |
| 3424 List<ConstructorElement> _createDefaultConstructors( | 3450 List<ConstructorElement> _createDefaultConstructors( |
| 3425 InterfaceTypeImpl interfaceType) { | 3451 ClassElementImpl definingClass) { |
| 3426 ConstructorElementImpl constructor = | 3452 ConstructorElementImpl constructor = |
| 3427 new ConstructorElementImpl.forNode(null); | 3453 new ConstructorElementImpl.forNode(null); |
| 3428 constructor.synthetic = true; | 3454 constructor.synthetic = true; |
| 3429 constructor.returnType = interfaceType; | 3455 constructor.returnType = definingClass.type; |
| 3456 constructor.enclosingElement = definingClass; | |
| 3430 constructor.type = new FunctionTypeImpl(constructor); | 3457 constructor.type = new FunctionTypeImpl(constructor); |
| 3431 return <ConstructorElement>[constructor]; | 3458 return <ConstructorElement>[constructor]; |
| 3432 } | 3459 } |
| 3433 | 3460 |
| 3434 /** | 3461 /** |
| 3435 * Create the types associated with the given type parameters, setting the typ e of each type | 3462 * Create the types associated with the given type parameters, setting the typ e of each type |
| 3436 * parameter, and return an array of types corresponding to the given paramete rs. | 3463 * parameter, and return an array of types corresponding to the given paramete rs. |
| 3437 * | 3464 * |
| 3438 * @param typeParameters the type parameters for which types are to be created | 3465 * @param typeParameters the type parameters for which types are to be created |
| 3439 * @return an array of types corresponding to the given parameters | 3466 * @return an array of types corresponding to the given parameters |
| (...skipping 12109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15549 nonFields.add(node); | 15576 nonFields.add(node); |
| 15550 return null; | 15577 return null; |
| 15551 } | 15578 } |
| 15552 | 15579 |
| 15553 @override | 15580 @override |
| 15554 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 15581 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
| 15555 | 15582 |
| 15556 @override | 15583 @override |
| 15557 Object visitWithClause(WithClause node) => null; | 15584 Object visitWithClause(WithClause node) => null; |
| 15558 } | 15585 } |
| OLD | NEW |