| 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 analyzer.src.generated.resolver; | 5 library analyzer.src.generated.resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/visitor.dart'; | 10 import 'package:analyzer/dart/ast/visitor.dart'; |
| (...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 for (PropertyAccessorElement accessor in typeElement.accessors) { | 1015 for (PropertyAccessorElement accessor in typeElement.accessors) { |
| 1016 define(accessor); | 1016 define(accessor); |
| 1017 } | 1017 } |
| 1018 for (MethodElement method in typeElement.methods) { | 1018 for (MethodElement method in typeElement.methods) { |
| 1019 define(method); | 1019 define(method); |
| 1020 } | 1020 } |
| 1021 } | 1021 } |
| 1022 } | 1022 } |
| 1023 | 1023 |
| 1024 /** | 1024 /** |
| 1025 * A `CompilationUnitBuilder` builds an element model for a single compilation | |
| 1026 * unit. | |
| 1027 */ | |
| 1028 class CompilationUnitBuilder { | |
| 1029 /** | |
| 1030 * Build the compilation unit element for the given [source] based on the | |
| 1031 * compilation [unit] associated with the source. Throw an AnalysisException | |
| 1032 * if the element could not be built. [librarySource] is the source for the | |
| 1033 * containing library. | |
| 1034 */ | |
| 1035 CompilationUnitElementImpl buildCompilationUnit( | |
| 1036 Source source, CompilationUnit unit, Source librarySource) { | |
| 1037 return PerformanceStatistics.resolve.makeCurrentWhile(() { | |
| 1038 if (unit == null) { | |
| 1039 return null; | |
| 1040 } | |
| 1041 ElementHolder holder = new ElementHolder(); | |
| 1042 ElementBuilder builder = new ElementBuilder(holder); | |
| 1043 unit.accept(builder); | |
| 1044 CompilationUnitElementImpl element = | |
| 1045 new CompilationUnitElementImpl(source.shortName); | |
| 1046 element.accessors = holder.accessors; | |
| 1047 element.enums = holder.enums; | |
| 1048 element.functions = holder.functions; | |
| 1049 element.source = source; | |
| 1050 element.librarySource = librarySource; | |
| 1051 element.typeAliases = holder.typeAliases; | |
| 1052 element.types = holder.types; | |
| 1053 element.topLevelVariables = holder.topLevelVariables; | |
| 1054 unit.element = element; | |
| 1055 holder.validate(); | |
| 1056 return element; | |
| 1057 }); | |
| 1058 } | |
| 1059 } | |
| 1060 | |
| 1061 /** | |
| 1062 * Instances of the class `ConstantVerifier` traverse an AST structure looking f
or additional | 1025 * Instances of the class `ConstantVerifier` traverse an AST structure looking f
or additional |
| 1063 * errors and warnings not covered by the parser and resolver. In particular, it
looks for errors | 1026 * errors and warnings not covered by the parser and resolver. In particular, it
looks for errors |
| 1064 * and warnings related to constant expressions. | 1027 * and warnings related to constant expressions. |
| 1065 */ | 1028 */ |
| 1066 class ConstantVerifier extends RecursiveAstVisitor<Object> { | 1029 class ConstantVerifier extends RecursiveAstVisitor<Object> { |
| 1067 /** | 1030 /** |
| 1068 * The error reporter by which errors will be reported. | 1031 * The error reporter by which errors will be reported. |
| 1069 */ | 1032 */ |
| 1070 final ErrorReporter _errorReporter; | 1033 final ErrorReporter _errorReporter; |
| 1071 | 1034 |
| (...skipping 1572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2644 */ | 2607 */ |
| 2645 String _getStringValue(StringLiteral literal) { | 2608 String _getStringValue(StringLiteral literal) { |
| 2646 if (literal is StringInterpolation) { | 2609 if (literal is StringInterpolation) { |
| 2647 return null; | 2610 return null; |
| 2648 } | 2611 } |
| 2649 return literal.stringValue; | 2612 return literal.stringValue; |
| 2650 } | 2613 } |
| 2651 } | 2614 } |
| 2652 | 2615 |
| 2653 /** | 2616 /** |
| 2654 * Instances of the class `ElementBuilder` traverse an AST structure and build t
he element | |
| 2655 * model representing the AST structure. | |
| 2656 */ | |
| 2657 class ElementBuilder extends RecursiveAstVisitor<Object> { | |
| 2658 /** | |
| 2659 * The element holder associated with the element that is currently being buil
t. | |
| 2660 */ | |
| 2661 ElementHolder _currentHolder; | |
| 2662 | |
| 2663 /** | |
| 2664 * A flag indicating whether a variable declaration is in the context of a fie
ld declaration. | |
| 2665 */ | |
| 2666 bool _inFieldContext = false; | |
| 2667 | |
| 2668 /** | |
| 2669 * A flag indicating whether a variable declaration is within the body of a me
thod or function. | |
| 2670 */ | |
| 2671 bool _inFunction = false; | |
| 2672 | |
| 2673 /** | |
| 2674 * A collection holding the elements defined in a class that need to have | |
| 2675 * their function type fixed to take into account type parameters of the | |
| 2676 * enclosing class, or `null` if we are not currently processing nodes within | |
| 2677 * a class. | |
| 2678 */ | |
| 2679 List<ExecutableElementImpl> _functionTypesToFix = null; | |
| 2680 | |
| 2681 /** | |
| 2682 * A table mapping field names to field elements for the fields defined in the
current class, or | |
| 2683 * `null` if we are not in the scope of a class. | |
| 2684 */ | |
| 2685 HashMap<String, FieldElement> _fieldMap; | |
| 2686 | |
| 2687 /** | |
| 2688 * Initialize a newly created element builder to build the elements for a comp
ilation unit. | |
| 2689 * | |
| 2690 * @param initialHolder the element holder associated with the compilation uni
t being built | |
| 2691 */ | |
| 2692 ElementBuilder(ElementHolder initialHolder) { | |
| 2693 _currentHolder = initialHolder; | |
| 2694 } | |
| 2695 | |
| 2696 @override | |
| 2697 Object visitBlock(Block node) { | |
| 2698 bool wasInField = _inFieldContext; | |
| 2699 _inFieldContext = false; | |
| 2700 try { | |
| 2701 node.visitChildren(this); | |
| 2702 } finally { | |
| 2703 _inFieldContext = wasInField; | |
| 2704 } | |
| 2705 return null; | |
| 2706 } | |
| 2707 | |
| 2708 @override | |
| 2709 Object visitCatchClause(CatchClause node) { | |
| 2710 SimpleIdentifier exceptionParameter = node.exceptionParameter; | |
| 2711 if (exceptionParameter != null) { | |
| 2712 // exception | |
| 2713 LocalVariableElementImpl exception = | |
| 2714 new LocalVariableElementImpl.forNode(exceptionParameter); | |
| 2715 if (node.exceptionType == null) { | |
| 2716 exception.hasImplicitType = true; | |
| 2717 } | |
| 2718 _currentHolder.addLocalVariable(exception); | |
| 2719 exceptionParameter.staticElement = exception; | |
| 2720 // stack trace | |
| 2721 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; | |
| 2722 if (stackTraceParameter != null) { | |
| 2723 LocalVariableElementImpl stackTrace = | |
| 2724 new LocalVariableElementImpl.forNode(stackTraceParameter); | |
| 2725 _currentHolder.addLocalVariable(stackTrace); | |
| 2726 stackTraceParameter.staticElement = stackTrace; | |
| 2727 } | |
| 2728 } | |
| 2729 return super.visitCatchClause(node); | |
| 2730 } | |
| 2731 | |
| 2732 @override | |
| 2733 Object visitClassDeclaration(ClassDeclaration node) { | |
| 2734 ElementHolder holder = new ElementHolder(); | |
| 2735 _functionTypesToFix = new List<ExecutableElementImpl>(); | |
| 2736 // | |
| 2737 // Process field declarations before constructors and methods so that field | |
| 2738 // formal parameters can be correctly resolved to their fields. | |
| 2739 // | |
| 2740 ElementHolder previousHolder = _currentHolder; | |
| 2741 _currentHolder = holder; | |
| 2742 try { | |
| 2743 List<ClassMember> nonFields = new List<ClassMember>(); | |
| 2744 node.visitChildren( | |
| 2745 new _ElementBuilder_visitClassDeclaration(this, nonFields)); | |
| 2746 _buildFieldMap(holder.fieldsWithoutFlushing); | |
| 2747 int count = nonFields.length; | |
| 2748 for (int i = 0; i < count; i++) { | |
| 2749 nonFields[i].accept(this); | |
| 2750 } | |
| 2751 } finally { | |
| 2752 _currentHolder = previousHolder; | |
| 2753 } | |
| 2754 SimpleIdentifier className = node.name; | |
| 2755 ClassElementImpl element = new ClassElementImpl.forNode(className); | |
| 2756 List<TypeParameterElement> typeParameters = holder.typeParameters; | |
| 2757 List<DartType> typeArguments = _createTypeParameterTypes(typeParameters); | |
| 2758 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element); | |
| 2759 interfaceType.typeArguments = typeArguments; | |
| 2760 element.type = interfaceType; | |
| 2761 element.typeParameters = typeParameters; | |
| 2762 _setDoc(element, node); | |
| 2763 element.abstract = node.isAbstract; | |
| 2764 element.accessors = holder.accessors; | |
| 2765 List<ConstructorElement> constructors = holder.constructors; | |
| 2766 if (constructors.isEmpty) { | |
| 2767 constructors = _createDefaultConstructors(element); | |
| 2768 } | |
| 2769 element.constructors = constructors; | |
| 2770 element.fields = holder.fields; | |
| 2771 element.methods = holder.methods; | |
| 2772 // Function types must be initialized after the enclosing element has been | |
| 2773 // set, for them to pick up the type parameters. | |
| 2774 for (ExecutableElementImpl e in _functionTypesToFix) { | |
| 2775 e.type = new FunctionTypeImpl(e); | |
| 2776 } | |
| 2777 _functionTypesToFix = null; | |
| 2778 _currentHolder.addType(element); | |
| 2779 className.staticElement = element; | |
| 2780 _fieldMap = null; | |
| 2781 holder.validate(); | |
| 2782 return null; | |
| 2783 } | |
| 2784 | |
| 2785 /** | |
| 2786 * Implementation of this method should be synchronized with | |
| 2787 * [visitClassDeclaration]. | |
| 2788 */ | |
| 2789 void visitClassDeclarationIncrementally(ClassDeclaration node) { | |
| 2790 // | |
| 2791 // Process field declarations before constructors and methods so that field | |
| 2792 // formal parameters can be correctly resolved to their fields. | |
| 2793 // | |
| 2794 ClassElement classElement = node.element; | |
| 2795 _buildFieldMap(classElement.fields); | |
| 2796 } | |
| 2797 | |
| 2798 @override | |
| 2799 Object visitClassTypeAlias(ClassTypeAlias node) { | |
| 2800 ElementHolder holder = new ElementHolder(); | |
| 2801 _visitChildren(holder, node); | |
| 2802 SimpleIdentifier className = node.name; | |
| 2803 ClassElementImpl element = new ClassElementImpl.forNode(className); | |
| 2804 element.abstract = node.abstractKeyword != null; | |
| 2805 element.mixinApplication = true; | |
| 2806 List<TypeParameterElement> typeParameters = holder.typeParameters; | |
| 2807 element.typeParameters = typeParameters; | |
| 2808 List<DartType> typeArguments = _createTypeParameterTypes(typeParameters); | |
| 2809 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element); | |
| 2810 interfaceType.typeArguments = typeArguments; | |
| 2811 element.type = interfaceType; | |
| 2812 _setDoc(element, node); | |
| 2813 _currentHolder.addType(element); | |
| 2814 className.staticElement = element; | |
| 2815 holder.validate(); | |
| 2816 return null; | |
| 2817 } | |
| 2818 | |
| 2819 @override | |
| 2820 Object visitConstructorDeclaration(ConstructorDeclaration node) { | |
| 2821 ElementHolder holder = new ElementHolder(); | |
| 2822 bool wasInFunction = _inFunction; | |
| 2823 _inFunction = true; | |
| 2824 try { | |
| 2825 _visitChildren(holder, node); | |
| 2826 } finally { | |
| 2827 _inFunction = wasInFunction; | |
| 2828 } | |
| 2829 FunctionBody body = node.body; | |
| 2830 SimpleIdentifier constructorName = node.name; | |
| 2831 ConstructorElementImpl element = | |
| 2832 new ConstructorElementImpl.forNode(constructorName); | |
| 2833 _setDoc(element, node); | |
| 2834 if (node.externalKeyword != null) { | |
| 2835 element.external = true; | |
| 2836 } | |
| 2837 if (node.factoryKeyword != null) { | |
| 2838 element.factory = true; | |
| 2839 } | |
| 2840 element.functions = holder.functions; | |
| 2841 element.labels = holder.labels; | |
| 2842 element.localVariables = holder.localVariables; | |
| 2843 element.parameters = holder.parameters; | |
| 2844 element.const2 = node.constKeyword != null; | |
| 2845 if (body.isAsynchronous) { | |
| 2846 element.asynchronous = true; | |
| 2847 } | |
| 2848 if (body.isGenerator) { | |
| 2849 element.generator = true; | |
| 2850 } | |
| 2851 _currentHolder.addConstructor(element); | |
| 2852 node.element = element; | |
| 2853 if (constructorName == null) { | |
| 2854 Identifier returnType = node.returnType; | |
| 2855 if (returnType != null) { | |
| 2856 element.nameOffset = returnType.offset; | |
| 2857 element.nameEnd = returnType.end; | |
| 2858 } | |
| 2859 } else { | |
| 2860 constructorName.staticElement = element; | |
| 2861 element.periodOffset = node.period.offset; | |
| 2862 element.nameEnd = constructorName.end; | |
| 2863 } | |
| 2864 holder.validate(); | |
| 2865 return null; | |
| 2866 } | |
| 2867 | |
| 2868 @override | |
| 2869 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | |
| 2870 SimpleIdentifier variableName = node.identifier; | |
| 2871 LocalVariableElementImpl element = | |
| 2872 new LocalVariableElementImpl.forNode(variableName); | |
| 2873 ForEachStatement statement = node.parent as ForEachStatement; | |
| 2874 int declarationEnd = node.offset + node.length; | |
| 2875 int statementEnd = statement.offset + statement.length; | |
| 2876 element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1); | |
| 2877 element.const3 = node.isConst; | |
| 2878 element.final2 = node.isFinal; | |
| 2879 if (node.type == null) { | |
| 2880 element.hasImplicitType = true; | |
| 2881 } | |
| 2882 _currentHolder.addLocalVariable(element); | |
| 2883 variableName.staticElement = element; | |
| 2884 return super.visitDeclaredIdentifier(node); | |
| 2885 } | |
| 2886 | |
| 2887 @override | |
| 2888 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | |
| 2889 ElementHolder holder = new ElementHolder(); | |
| 2890 NormalFormalParameter normalParameter = node.parameter; | |
| 2891 SimpleIdentifier parameterName = normalParameter.identifier; | |
| 2892 ParameterElementImpl parameter; | |
| 2893 if (normalParameter is FieldFormalParameter) { | |
| 2894 parameter = new DefaultFieldFormalParameterElementImpl(parameterName); | |
| 2895 FieldElement field = | |
| 2896 _fieldMap == null ? null : _fieldMap[parameterName.name]; | |
| 2897 if (field != null) { | |
| 2898 (parameter as DefaultFieldFormalParameterElementImpl).field = field; | |
| 2899 } | |
| 2900 } else { | |
| 2901 parameter = new DefaultParameterElementImpl(parameterName); | |
| 2902 } | |
| 2903 parameter.const3 = node.isConst; | |
| 2904 parameter.final2 = node.isFinal; | |
| 2905 parameter.parameterKind = node.kind; | |
| 2906 // set initializer, default value range | |
| 2907 Expression defaultValue = node.defaultValue; | |
| 2908 if (defaultValue != null) { | |
| 2909 _visit(holder, defaultValue); | |
| 2910 FunctionElementImpl initializer = | |
| 2911 new FunctionElementImpl.forOffset(defaultValue.beginToken.offset); | |
| 2912 initializer.functions = holder.functions; | |
| 2913 initializer.labels = holder.labels; | |
| 2914 initializer.localVariables = holder.localVariables; | |
| 2915 initializer.parameters = holder.parameters; | |
| 2916 initializer.synthetic = true; | |
| 2917 parameter.initializer = initializer; | |
| 2918 parameter.defaultValueCode = defaultValue.toSource(); | |
| 2919 } | |
| 2920 // visible range | |
| 2921 _setParameterVisibleRange(node, parameter); | |
| 2922 if (normalParameter is SimpleFormalParameter && | |
| 2923 normalParameter.type == null) { | |
| 2924 parameter.hasImplicitType = true; | |
| 2925 } | |
| 2926 _currentHolder.addParameter(parameter); | |
| 2927 parameterName.staticElement = parameter; | |
| 2928 normalParameter.accept(this); | |
| 2929 holder.validate(); | |
| 2930 return null; | |
| 2931 } | |
| 2932 | |
| 2933 @override | |
| 2934 Object visitEnumDeclaration(EnumDeclaration node) { | |
| 2935 SimpleIdentifier enumName = node.name; | |
| 2936 ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName); | |
| 2937 enumElement.enum2 = true; | |
| 2938 _setDoc(enumElement, node); | |
| 2939 InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement); | |
| 2940 enumElement.type = enumType; | |
| 2941 // The equivalent code for enums in the spec shows a single constructor, | |
| 2942 // but that constructor is not callable (since it is a compile-time error | |
| 2943 // to subclass, mix-in, implement, or explicitly instantiate an enum). So | |
| 2944 // we represent this as having no constructors. | |
| 2945 enumElement.constructors = ConstructorElement.EMPTY_LIST; | |
| 2946 _currentHolder.addEnum(enumElement); | |
| 2947 enumName.staticElement = enumElement; | |
| 2948 return super.visitEnumDeclaration(node); | |
| 2949 } | |
| 2950 | |
| 2951 @override | |
| 2952 Object visitFieldDeclaration(FieldDeclaration node) { | |
| 2953 bool wasInField = _inFieldContext; | |
| 2954 _inFieldContext = true; | |
| 2955 try { | |
| 2956 node.visitChildren(this); | |
| 2957 } finally { | |
| 2958 _inFieldContext = wasInField; | |
| 2959 } | |
| 2960 return null; | |
| 2961 } | |
| 2962 | |
| 2963 @override | |
| 2964 Object visitFieldFormalParameter(FieldFormalParameter node) { | |
| 2965 if (node.parent is! DefaultFormalParameter) { | |
| 2966 SimpleIdentifier parameterName = node.identifier; | |
| 2967 FieldElement field = | |
| 2968 _fieldMap == null ? null : _fieldMap[parameterName.name]; | |
| 2969 FieldFormalParameterElementImpl parameter = | |
| 2970 new FieldFormalParameterElementImpl(parameterName); | |
| 2971 parameter.const3 = node.isConst; | |
| 2972 parameter.final2 = node.isFinal; | |
| 2973 parameter.parameterKind = node.kind; | |
| 2974 if (field != null) { | |
| 2975 parameter.field = field; | |
| 2976 } | |
| 2977 _currentHolder.addParameter(parameter); | |
| 2978 parameterName.staticElement = parameter; | |
| 2979 } | |
| 2980 // | |
| 2981 // The children of this parameter include any parameters defined on the type | |
| 2982 // of this parameter. | |
| 2983 // | |
| 2984 ElementHolder holder = new ElementHolder(); | |
| 2985 _visitChildren(holder, node); | |
| 2986 ParameterElementImpl element = node.element; | |
| 2987 element.parameters = holder.parameters; | |
| 2988 element.typeParameters = holder.typeParameters; | |
| 2989 holder.validate(); | |
| 2990 return null; | |
| 2991 } | |
| 2992 | |
| 2993 @override | |
| 2994 Object visitFunctionDeclaration(FunctionDeclaration node) { | |
| 2995 FunctionExpression expression = node.functionExpression; | |
| 2996 if (expression != null) { | |
| 2997 ElementHolder holder = new ElementHolder(); | |
| 2998 bool wasInFunction = _inFunction; | |
| 2999 _inFunction = true; | |
| 3000 try { | |
| 3001 _visitChildren(holder, node); | |
| 3002 } finally { | |
| 3003 _inFunction = wasInFunction; | |
| 3004 } | |
| 3005 FunctionBody body = expression.body; | |
| 3006 Token property = node.propertyKeyword; | |
| 3007 if (property == null || _inFunction) { | |
| 3008 SimpleIdentifier functionName = node.name; | |
| 3009 FunctionElementImpl element = | |
| 3010 new FunctionElementImpl.forNode(functionName); | |
| 3011 _setDoc(element, node); | |
| 3012 if (node.externalKeyword != null) { | |
| 3013 element.external = true; | |
| 3014 } | |
| 3015 element.functions = holder.functions; | |
| 3016 element.labels = holder.labels; | |
| 3017 element.localVariables = holder.localVariables; | |
| 3018 element.parameters = holder.parameters; | |
| 3019 element.typeParameters = holder.typeParameters; | |
| 3020 if (body.isAsynchronous) { | |
| 3021 element.asynchronous = true; | |
| 3022 } | |
| 3023 if (body.isGenerator) { | |
| 3024 element.generator = true; | |
| 3025 } | |
| 3026 if (_inFunction) { | |
| 3027 Block enclosingBlock = node.getAncestor((node) => node is Block); | |
| 3028 if (enclosingBlock != null) { | |
| 3029 int functionEnd = node.offset + node.length; | |
| 3030 int blockEnd = enclosingBlock.offset + enclosingBlock.length; | |
| 3031 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); | |
| 3032 } | |
| 3033 } | |
| 3034 if (node.returnType == null) { | |
| 3035 element.hasImplicitReturnType = true; | |
| 3036 } | |
| 3037 _currentHolder.addFunction(element); | |
| 3038 expression.element = element; | |
| 3039 functionName.staticElement = element; | |
| 3040 } else { | |
| 3041 SimpleIdentifier propertyNameNode = node.name; | |
| 3042 if (propertyNameNode == null) { | |
| 3043 // TODO(brianwilkerson) Report this internal error. | |
| 3044 return null; | |
| 3045 } | |
| 3046 String propertyName = propertyNameNode.name; | |
| 3047 TopLevelVariableElementImpl variable = _currentHolder | |
| 3048 .getTopLevelVariable(propertyName) as TopLevelVariableElementImpl; | |
| 3049 if (variable == null) { | |
| 3050 variable = new TopLevelVariableElementImpl(node.name.name, -1); | |
| 3051 variable.final2 = true; | |
| 3052 variable.synthetic = true; | |
| 3053 _currentHolder.addTopLevelVariable(variable); | |
| 3054 } | |
| 3055 if (node.isGetter) { | |
| 3056 PropertyAccessorElementImpl getter = | |
| 3057 new PropertyAccessorElementImpl.forNode(propertyNameNode); | |
| 3058 _setDoc(getter, node); | |
| 3059 if (node.externalKeyword != null) { | |
| 3060 getter.external = true; | |
| 3061 } | |
| 3062 getter.functions = holder.functions; | |
| 3063 getter.labels = holder.labels; | |
| 3064 getter.localVariables = holder.localVariables; | |
| 3065 if (body.isAsynchronous) { | |
| 3066 getter.asynchronous = true; | |
| 3067 } | |
| 3068 if (body.isGenerator) { | |
| 3069 getter.generator = true; | |
| 3070 } | |
| 3071 getter.variable = variable; | |
| 3072 getter.getter = true; | |
| 3073 getter.static = true; | |
| 3074 variable.getter = getter; | |
| 3075 if (node.returnType == null) { | |
| 3076 getter.hasImplicitReturnType = true; | |
| 3077 } | |
| 3078 _currentHolder.addAccessor(getter); | |
| 3079 expression.element = getter; | |
| 3080 propertyNameNode.staticElement = getter; | |
| 3081 } else { | |
| 3082 PropertyAccessorElementImpl setter = | |
| 3083 new PropertyAccessorElementImpl.forNode(propertyNameNode); | |
| 3084 _setDoc(setter, node); | |
| 3085 if (node.externalKeyword != null) { | |
| 3086 setter.external = true; | |
| 3087 } | |
| 3088 setter.functions = holder.functions; | |
| 3089 setter.labels = holder.labels; | |
| 3090 setter.localVariables = holder.localVariables; | |
| 3091 setter.parameters = holder.parameters; | |
| 3092 if (body.isAsynchronous) { | |
| 3093 setter.asynchronous = true; | |
| 3094 } | |
| 3095 if (body.isGenerator) { | |
| 3096 setter.generator = true; | |
| 3097 } | |
| 3098 setter.variable = variable; | |
| 3099 setter.setter = true; | |
| 3100 setter.static = true; | |
| 3101 if (node.returnType == null) { | |
| 3102 setter.hasImplicitReturnType = true; | |
| 3103 } | |
| 3104 variable.setter = setter; | |
| 3105 variable.final2 = false; | |
| 3106 _currentHolder.addAccessor(setter); | |
| 3107 expression.element = setter; | |
| 3108 propertyNameNode.staticElement = setter; | |
| 3109 } | |
| 3110 } | |
| 3111 holder.validate(); | |
| 3112 } | |
| 3113 return null; | |
| 3114 } | |
| 3115 | |
| 3116 @override | |
| 3117 Object visitFunctionExpression(FunctionExpression node) { | |
| 3118 if (node.parent is FunctionDeclaration) { | |
| 3119 // visitFunctionDeclaration has already created the element for the | |
| 3120 // declaration. We just need to visit children. | |
| 3121 return super.visitFunctionExpression(node); | |
| 3122 } | |
| 3123 ElementHolder holder = new ElementHolder(); | |
| 3124 bool wasInFunction = _inFunction; | |
| 3125 _inFunction = true; | |
| 3126 try { | |
| 3127 _visitChildren(holder, node); | |
| 3128 } finally { | |
| 3129 _inFunction = wasInFunction; | |
| 3130 } | |
| 3131 FunctionBody body = node.body; | |
| 3132 FunctionElementImpl element = | |
| 3133 new FunctionElementImpl.forOffset(node.beginToken.offset); | |
| 3134 element.functions = holder.functions; | |
| 3135 element.labels = holder.labels; | |
| 3136 element.localVariables = holder.localVariables; | |
| 3137 element.parameters = holder.parameters; | |
| 3138 element.typeParameters = holder.typeParameters; | |
| 3139 if (body.isAsynchronous) { | |
| 3140 element.asynchronous = true; | |
| 3141 } | |
| 3142 if (body.isGenerator) { | |
| 3143 element.generator = true; | |
| 3144 } | |
| 3145 if (_inFunction) { | |
| 3146 Block enclosingBlock = node.getAncestor((node) => node is Block); | |
| 3147 if (enclosingBlock != null) { | |
| 3148 int functionEnd = node.offset + node.length; | |
| 3149 int blockEnd = enclosingBlock.offset + enclosingBlock.length; | |
| 3150 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); | |
| 3151 } | |
| 3152 } | |
| 3153 if (_functionTypesToFix != null) { | |
| 3154 _functionTypesToFix.add(element); | |
| 3155 } else { | |
| 3156 element.type = new FunctionTypeImpl(element); | |
| 3157 } | |
| 3158 element.hasImplicitReturnType = true; | |
| 3159 _currentHolder.addFunction(element); | |
| 3160 node.element = element; | |
| 3161 holder.validate(); | |
| 3162 return null; | |
| 3163 } | |
| 3164 | |
| 3165 @override | |
| 3166 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | |
| 3167 ElementHolder holder = new ElementHolder(); | |
| 3168 _visitChildren(holder, node); | |
| 3169 SimpleIdentifier aliasName = node.name; | |
| 3170 List<ParameterElement> parameters = holder.parameters; | |
| 3171 List<TypeParameterElement> typeParameters = holder.typeParameters; | |
| 3172 FunctionTypeAliasElementImpl element = | |
| 3173 new FunctionTypeAliasElementImpl.forNode(aliasName); | |
| 3174 _setDoc(element, node); | |
| 3175 element.parameters = parameters; | |
| 3176 element.typeParameters = typeParameters; | |
| 3177 _createTypeParameterTypes(typeParameters); | |
| 3178 element.type = new FunctionTypeImpl.forTypedef(element); | |
| 3179 _currentHolder.addTypeAlias(element); | |
| 3180 aliasName.staticElement = element; | |
| 3181 holder.validate(); | |
| 3182 return null; | |
| 3183 } | |
| 3184 | |
| 3185 @override | |
| 3186 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | |
| 3187 if (node.parent is! DefaultFormalParameter) { | |
| 3188 SimpleIdentifier parameterName = node.identifier; | |
| 3189 ParameterElementImpl parameter = | |
| 3190 new ParameterElementImpl.forNode(parameterName); | |
| 3191 parameter.parameterKind = node.kind; | |
| 3192 _setParameterVisibleRange(node, parameter); | |
| 3193 _currentHolder.addParameter(parameter); | |
| 3194 parameterName.staticElement = parameter; | |
| 3195 } | |
| 3196 // | |
| 3197 // The children of this parameter include any parameters defined on the type | |
| 3198 //of this parameter. | |
| 3199 // | |
| 3200 ElementHolder holder = new ElementHolder(); | |
| 3201 _visitChildren(holder, node); | |
| 3202 ParameterElementImpl element = node.element; | |
| 3203 element.parameters = holder.parameters; | |
| 3204 element.typeParameters = holder.typeParameters; | |
| 3205 holder.validate(); | |
| 3206 return null; | |
| 3207 } | |
| 3208 | |
| 3209 @override | |
| 3210 Object visitLabeledStatement(LabeledStatement node) { | |
| 3211 bool onSwitchStatement = node.statement is SwitchStatement; | |
| 3212 for (Label label in node.labels) { | |
| 3213 SimpleIdentifier labelName = label.label; | |
| 3214 LabelElementImpl element = | |
| 3215 new LabelElementImpl(labelName, onSwitchStatement, false); | |
| 3216 _currentHolder.addLabel(element); | |
| 3217 labelName.staticElement = element; | |
| 3218 } | |
| 3219 return super.visitLabeledStatement(node); | |
| 3220 } | |
| 3221 | |
| 3222 @override | |
| 3223 Object visitMethodDeclaration(MethodDeclaration node) { | |
| 3224 try { | |
| 3225 ElementHolder holder = new ElementHolder(); | |
| 3226 bool wasInFunction = _inFunction; | |
| 3227 _inFunction = true; | |
| 3228 try { | |
| 3229 _visitChildren(holder, node); | |
| 3230 } finally { | |
| 3231 _inFunction = wasInFunction; | |
| 3232 } | |
| 3233 bool isStatic = node.isStatic; | |
| 3234 Token property = node.propertyKeyword; | |
| 3235 FunctionBody body = node.body; | |
| 3236 if (property == null) { | |
| 3237 SimpleIdentifier methodName = node.name; | |
| 3238 String nameOfMethod = methodName.name; | |
| 3239 if (nameOfMethod == TokenType.MINUS.lexeme && | |
| 3240 node.parameters.parameters.length == 0) { | |
| 3241 nameOfMethod = "unary-"; | |
| 3242 } | |
| 3243 MethodElementImpl element = | |
| 3244 new MethodElementImpl(nameOfMethod, methodName.offset); | |
| 3245 _setDoc(element, node); | |
| 3246 element.abstract = node.isAbstract; | |
| 3247 if (node.externalKeyword != null) { | |
| 3248 element.external = true; | |
| 3249 } | |
| 3250 element.functions = holder.functions; | |
| 3251 element.labels = holder.labels; | |
| 3252 element.localVariables = holder.localVariables; | |
| 3253 element.parameters = holder.parameters; | |
| 3254 element.static = isStatic; | |
| 3255 element.typeParameters = holder.typeParameters; | |
| 3256 if (body.isAsynchronous) { | |
| 3257 element.asynchronous = true; | |
| 3258 } | |
| 3259 if (body.isGenerator) { | |
| 3260 element.generator = true; | |
| 3261 } | |
| 3262 if (node.returnType == null) { | |
| 3263 element.hasImplicitReturnType = true; | |
| 3264 } | |
| 3265 _currentHolder.addMethod(element); | |
| 3266 methodName.staticElement = element; | |
| 3267 } else { | |
| 3268 SimpleIdentifier propertyNameNode = node.name; | |
| 3269 String propertyName = propertyNameNode.name; | |
| 3270 FieldElementImpl field = | |
| 3271 _currentHolder.getField(propertyName) as FieldElementImpl; | |
| 3272 if (field == null) { | |
| 3273 field = new FieldElementImpl(node.name.name, -1); | |
| 3274 field.final2 = true; | |
| 3275 field.static = isStatic; | |
| 3276 field.synthetic = true; | |
| 3277 _currentHolder.addField(field); | |
| 3278 } | |
| 3279 if (node.isGetter) { | |
| 3280 PropertyAccessorElementImpl getter = | |
| 3281 new PropertyAccessorElementImpl.forNode(propertyNameNode); | |
| 3282 _setDoc(getter, node); | |
| 3283 if (node.externalKeyword != null) { | |
| 3284 getter.external = true; | |
| 3285 } | |
| 3286 getter.functions = holder.functions; | |
| 3287 getter.labels = holder.labels; | |
| 3288 getter.localVariables = holder.localVariables; | |
| 3289 if (body.isAsynchronous) { | |
| 3290 getter.asynchronous = true; | |
| 3291 } | |
| 3292 if (body.isGenerator) { | |
| 3293 getter.generator = true; | |
| 3294 } | |
| 3295 getter.variable = field; | |
| 3296 getter.abstract = node.isAbstract; | |
| 3297 getter.getter = true; | |
| 3298 getter.static = isStatic; | |
| 3299 field.getter = getter; | |
| 3300 if (node.returnType == null) { | |
| 3301 getter.hasImplicitReturnType = true; | |
| 3302 } | |
| 3303 _currentHolder.addAccessor(getter); | |
| 3304 propertyNameNode.staticElement = getter; | |
| 3305 } else { | |
| 3306 PropertyAccessorElementImpl setter = | |
| 3307 new PropertyAccessorElementImpl.forNode(propertyNameNode); | |
| 3308 _setDoc(setter, node); | |
| 3309 if (node.externalKeyword != null) { | |
| 3310 setter.external = true; | |
| 3311 } | |
| 3312 setter.functions = holder.functions; | |
| 3313 setter.labels = holder.labels; | |
| 3314 setter.localVariables = holder.localVariables; | |
| 3315 setter.parameters = holder.parameters; | |
| 3316 if (body.isAsynchronous) { | |
| 3317 setter.asynchronous = true; | |
| 3318 } | |
| 3319 if (body.isGenerator) { | |
| 3320 setter.generator = true; | |
| 3321 } | |
| 3322 setter.variable = field; | |
| 3323 setter.abstract = node.isAbstract; | |
| 3324 setter.setter = true; | |
| 3325 setter.static = isStatic; | |
| 3326 if (node.returnType == null) { | |
| 3327 setter.hasImplicitReturnType = true; | |
| 3328 } | |
| 3329 field.setter = setter; | |
| 3330 field.final2 = false; | |
| 3331 _currentHolder.addAccessor(setter); | |
| 3332 propertyNameNode.staticElement = setter; | |
| 3333 } | |
| 3334 } | |
| 3335 holder.validate(); | |
| 3336 } catch (exception, stackTrace) { | |
| 3337 if (node.name.staticElement == null) { | |
| 3338 ClassDeclaration classNode = | |
| 3339 node.getAncestor((node) => node is ClassDeclaration); | |
| 3340 StringBuffer buffer = new StringBuffer(); | |
| 3341 buffer.write("The element for the method "); | |
| 3342 buffer.write(node.name); | |
| 3343 buffer.write(" in "); | |
| 3344 buffer.write(classNode.name); | |
| 3345 buffer.write(" was not set while trying to build the element model."); | |
| 3346 AnalysisEngine.instance.logger.logError( | |
| 3347 buffer.toString(), new CaughtException(exception, stackTrace)); | |
| 3348 } else { | |
| 3349 String message = | |
| 3350 "Exception caught in ElementBuilder.visitMethodDeclaration()"; | |
| 3351 AnalysisEngine.instance.logger | |
| 3352 .logError(message, new CaughtException(exception, stackTrace)); | |
| 3353 } | |
| 3354 } finally { | |
| 3355 if (node.name.staticElement == null) { | |
| 3356 ClassDeclaration classNode = | |
| 3357 node.getAncestor((node) => node is ClassDeclaration); | |
| 3358 StringBuffer buffer = new StringBuffer(); | |
| 3359 buffer.write("The element for the method "); | |
| 3360 buffer.write(node.name); | |
| 3361 buffer.write(" in "); | |
| 3362 buffer.write(classNode.name); | |
| 3363 buffer.write(" was not set while trying to resolve types."); | |
| 3364 AnalysisEngine.instance.logger.logError( | |
| 3365 buffer.toString(), | |
| 3366 new CaughtException( | |
| 3367 new AnalysisException(buffer.toString()), null)); | |
| 3368 } | |
| 3369 } | |
| 3370 return null; | |
| 3371 } | |
| 3372 | |
| 3373 @override | |
| 3374 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | |
| 3375 if (node.parent is! DefaultFormalParameter) { | |
| 3376 SimpleIdentifier parameterName = node.identifier; | |
| 3377 ParameterElementImpl parameter = | |
| 3378 new ParameterElementImpl.forNode(parameterName); | |
| 3379 parameter.const3 = node.isConst; | |
| 3380 parameter.final2 = node.isFinal; | |
| 3381 parameter.parameterKind = node.kind; | |
| 3382 _setParameterVisibleRange(node, parameter); | |
| 3383 if (node.type == null) { | |
| 3384 parameter.hasImplicitType = true; | |
| 3385 } | |
| 3386 _currentHolder.addParameter(parameter); | |
| 3387 parameterName.staticElement = parameter; | |
| 3388 } | |
| 3389 return super.visitSimpleFormalParameter(node); | |
| 3390 } | |
| 3391 | |
| 3392 @override | |
| 3393 Object visitSwitchCase(SwitchCase node) { | |
| 3394 for (Label label in node.labels) { | |
| 3395 SimpleIdentifier labelName = label.label; | |
| 3396 LabelElementImpl element = new LabelElementImpl(labelName, false, true); | |
| 3397 _currentHolder.addLabel(element); | |
| 3398 labelName.staticElement = element; | |
| 3399 } | |
| 3400 return super.visitSwitchCase(node); | |
| 3401 } | |
| 3402 | |
| 3403 @override | |
| 3404 Object visitSwitchDefault(SwitchDefault node) { | |
| 3405 for (Label label in node.labels) { | |
| 3406 SimpleIdentifier labelName = label.label; | |
| 3407 LabelElementImpl element = new LabelElementImpl(labelName, false, true); | |
| 3408 _currentHolder.addLabel(element); | |
| 3409 labelName.staticElement = element; | |
| 3410 } | |
| 3411 return super.visitSwitchDefault(node); | |
| 3412 } | |
| 3413 | |
| 3414 @override | |
| 3415 Object visitTypeParameter(TypeParameter node) { | |
| 3416 SimpleIdentifier parameterName = node.name; | |
| 3417 TypeParameterElementImpl typeParameter = | |
| 3418 new TypeParameterElementImpl.forNode(parameterName); | |
| 3419 TypeParameterTypeImpl typeParameterType = | |
| 3420 new TypeParameterTypeImpl(typeParameter); | |
| 3421 typeParameter.type = typeParameterType; | |
| 3422 _currentHolder.addTypeParameter(typeParameter); | |
| 3423 parameterName.staticElement = typeParameter; | |
| 3424 return super.visitTypeParameter(node); | |
| 3425 } | |
| 3426 | |
| 3427 @override | |
| 3428 Object visitVariableDeclaration(VariableDeclaration node) { | |
| 3429 bool isConst = node.isConst; | |
| 3430 bool isFinal = node.isFinal; | |
| 3431 bool hasInitializer = node.initializer != null; | |
| 3432 VariableElementImpl element; | |
| 3433 if (_inFieldContext) { | |
| 3434 SimpleIdentifier fieldName = node.name; | |
| 3435 FieldElementImpl field; | |
| 3436 if ((isConst || isFinal) && hasInitializer) { | |
| 3437 field = new ConstFieldElementImpl.forNode(fieldName); | |
| 3438 } else { | |
| 3439 field = new FieldElementImpl.forNode(fieldName); | |
| 3440 } | |
| 3441 element = field; | |
| 3442 if (node.parent.parent is FieldDeclaration) { | |
| 3443 _setDoc(element, node.parent.parent); | |
| 3444 } | |
| 3445 if ((node.parent as VariableDeclarationList).type == null) { | |
| 3446 field.hasImplicitType = true; | |
| 3447 } | |
| 3448 _currentHolder.addField(field); | |
| 3449 fieldName.staticElement = field; | |
| 3450 } else if (_inFunction) { | |
| 3451 SimpleIdentifier variableName = node.name; | |
| 3452 LocalVariableElementImpl variable; | |
| 3453 if (isConst && hasInitializer) { | |
| 3454 variable = new ConstLocalVariableElementImpl.forNode(variableName); | |
| 3455 } else { | |
| 3456 variable = new LocalVariableElementImpl.forNode(variableName); | |
| 3457 } | |
| 3458 element = variable; | |
| 3459 Block enclosingBlock = node.getAncestor((node) => node is Block); | |
| 3460 // TODO(brianwilkerson) This isn't right for variables declared in a for | |
| 3461 // loop. | |
| 3462 variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length); | |
| 3463 if ((node.parent as VariableDeclarationList).type == null) { | |
| 3464 variable.hasImplicitType = true; | |
| 3465 } | |
| 3466 _currentHolder.addLocalVariable(variable); | |
| 3467 variableName.staticElement = element; | |
| 3468 } else { | |
| 3469 SimpleIdentifier variableName = node.name; | |
| 3470 TopLevelVariableElementImpl variable; | |
| 3471 if (isConst && hasInitializer) { | |
| 3472 variable = new ConstTopLevelVariableElementImpl.forNode(variableName); | |
| 3473 } else { | |
| 3474 variable = new TopLevelVariableElementImpl.forNode(variableName); | |
| 3475 } | |
| 3476 element = variable; | |
| 3477 if (node.parent.parent is TopLevelVariableDeclaration) { | |
| 3478 _setDoc(element, node.parent.parent); | |
| 3479 } | |
| 3480 if ((node.parent as VariableDeclarationList).type == null) { | |
| 3481 variable.hasImplicitType = true; | |
| 3482 } | |
| 3483 _currentHolder.addTopLevelVariable(variable); | |
| 3484 variableName.staticElement = element; | |
| 3485 } | |
| 3486 element.const3 = isConst; | |
| 3487 element.final2 = isFinal; | |
| 3488 if (hasInitializer) { | |
| 3489 ElementHolder holder = new ElementHolder(); | |
| 3490 bool wasInFieldContext = _inFieldContext; | |
| 3491 _inFieldContext = false; | |
| 3492 try { | |
| 3493 _visit(holder, node.initializer); | |
| 3494 } finally { | |
| 3495 _inFieldContext = wasInFieldContext; | |
| 3496 } | |
| 3497 FunctionElementImpl initializer = | |
| 3498 new FunctionElementImpl.forOffset(node.initializer.beginToken.offset); | |
| 3499 initializer.functions = holder.functions; | |
| 3500 initializer.labels = holder.labels; | |
| 3501 initializer.localVariables = holder.localVariables; | |
| 3502 initializer.synthetic = true; | |
| 3503 element.initializer = initializer; | |
| 3504 holder.validate(); | |
| 3505 } | |
| 3506 if (element is PropertyInducingElementImpl) { | |
| 3507 if (_inFieldContext) { | |
| 3508 (element as FieldElementImpl).static = | |
| 3509 (node.parent.parent as FieldDeclaration).isStatic; | |
| 3510 } | |
| 3511 PropertyAccessorElementImpl getter = | |
| 3512 new PropertyAccessorElementImpl.forVariable(element); | |
| 3513 getter.getter = true; | |
| 3514 if (element.hasImplicitType) { | |
| 3515 getter.hasImplicitReturnType = true; | |
| 3516 } | |
| 3517 _currentHolder.addAccessor(getter); | |
| 3518 element.getter = getter; | |
| 3519 if (!isConst && !isFinal) { | |
| 3520 PropertyAccessorElementImpl setter = | |
| 3521 new PropertyAccessorElementImpl.forVariable(element); | |
| 3522 setter.setter = true; | |
| 3523 ParameterElementImpl parameter = | |
| 3524 new ParameterElementImpl("_${element.name}", element.nameOffset); | |
| 3525 parameter.synthetic = true; | |
| 3526 parameter.parameterKind = ParameterKind.REQUIRED; | |
| 3527 setter.parameters = <ParameterElement>[parameter]; | |
| 3528 _currentHolder.addAccessor(setter); | |
| 3529 element.setter = setter; | |
| 3530 } | |
| 3531 } | |
| 3532 return null; | |
| 3533 } | |
| 3534 | |
| 3535 /** | |
| 3536 * Build the table mapping field names to field elements for the fields define
d in the current | |
| 3537 * class. | |
| 3538 * | |
| 3539 * @param fields the field elements defined in the current class | |
| 3540 */ | |
| 3541 void _buildFieldMap(List<FieldElement> fields) { | |
| 3542 _fieldMap = new HashMap<String, FieldElement>(); | |
| 3543 int count = fields.length; | |
| 3544 for (int i = 0; i < count; i++) { | |
| 3545 FieldElement field = fields[i]; | |
| 3546 _fieldMap[field.name] = field; | |
| 3547 } | |
| 3548 } | |
| 3549 | |
| 3550 /** | |
| 3551 * Creates the [ConstructorElement]s array with the single default constructor
element. | |
| 3552 * | |
| 3553 * @param interfaceType the interface type for which to create a default const
ructor | |
| 3554 * @return the [ConstructorElement]s array with the single default constructor
element | |
| 3555 */ | |
| 3556 List<ConstructorElement> _createDefaultConstructors( | |
| 3557 ClassElementImpl definingClass) { | |
| 3558 ConstructorElementImpl constructor = | |
| 3559 new ConstructorElementImpl.forNode(null); | |
| 3560 constructor.synthetic = true; | |
| 3561 constructor.returnType = definingClass.type; | |
| 3562 constructor.enclosingElement = definingClass; | |
| 3563 constructor.type = new FunctionTypeImpl(constructor); | |
| 3564 return <ConstructorElement>[constructor]; | |
| 3565 } | |
| 3566 | |
| 3567 /** | |
| 3568 * Create the types associated with the given type parameters, setting the typ
e of each type | |
| 3569 * parameter, and return an array of types corresponding to the given paramete
rs. | |
| 3570 * | |
| 3571 * @param typeParameters the type parameters for which types are to be created | |
| 3572 * @return an array of types corresponding to the given parameters | |
| 3573 */ | |
| 3574 List<DartType> _createTypeParameterTypes( | |
| 3575 List<TypeParameterElement> typeParameters) { | |
| 3576 int typeParameterCount = typeParameters.length; | |
| 3577 List<DartType> typeArguments = new List<DartType>(typeParameterCount); | |
| 3578 for (int i = 0; i < typeParameterCount; i++) { | |
| 3579 TypeParameterElementImpl typeParameter = | |
| 3580 typeParameters[i] as TypeParameterElementImpl; | |
| 3581 TypeParameterTypeImpl typeParameterType = | |
| 3582 new TypeParameterTypeImpl(typeParameter); | |
| 3583 typeParameter.type = typeParameterType; | |
| 3584 typeArguments[i] = typeParameterType; | |
| 3585 } | |
| 3586 return typeArguments; | |
| 3587 } | |
| 3588 | |
| 3589 /** | |
| 3590 * Return the body of the function that contains the given parameter, or `null
` if no | |
| 3591 * function body could be found. | |
| 3592 * | |
| 3593 * @param node the parameter contained in the function whose body is to be ret
urned | |
| 3594 * @return the body of the function that contains the given parameter | |
| 3595 */ | |
| 3596 FunctionBody _getFunctionBody(FormalParameter node) { | |
| 3597 AstNode parent = node.parent; | |
| 3598 while (parent != null) { | |
| 3599 if (parent is ConstructorDeclaration) { | |
| 3600 return parent.body; | |
| 3601 } else if (parent is FunctionExpression) { | |
| 3602 return parent.body; | |
| 3603 } else if (parent is MethodDeclaration) { | |
| 3604 return parent.body; | |
| 3605 } | |
| 3606 parent = parent.parent; | |
| 3607 } | |
| 3608 return null; | |
| 3609 } | |
| 3610 | |
| 3611 /** | |
| 3612 * If the given [node] has a documentation comment, remember its content | |
| 3613 * and range into the given [element]. | |
| 3614 */ | |
| 3615 void _setDoc(ElementImpl element, AnnotatedNode node) { | |
| 3616 Comment comment = node.documentationComment; | |
| 3617 if (comment != null && comment.isDocumentation) { | |
| 3618 element.documentationComment = | |
| 3619 comment.tokens.map((Token t) => t.lexeme).join('\n'); | |
| 3620 element.setDocRange(comment.offset, comment.length); | |
| 3621 } | |
| 3622 } | |
| 3623 | |
| 3624 /** | |
| 3625 * Sets the visible source range for formal parameter. | |
| 3626 */ | |
| 3627 void _setParameterVisibleRange( | |
| 3628 FormalParameter node, ParameterElementImpl element) { | |
| 3629 FunctionBody body = _getFunctionBody(node); | |
| 3630 if (body != null) { | |
| 3631 element.setVisibleRange(body.offset, body.length); | |
| 3632 } | |
| 3633 } | |
| 3634 | |
| 3635 /** | |
| 3636 * Make the given holder be the current holder while visiting the given node. | |
| 3637 * | |
| 3638 * @param holder the holder that will gather elements that are built while vis
iting the children | |
| 3639 * @param node the node to be visited | |
| 3640 */ | |
| 3641 void _visit(ElementHolder holder, AstNode node) { | |
| 3642 if (node != null) { | |
| 3643 ElementHolder previousHolder = _currentHolder; | |
| 3644 _currentHolder = holder; | |
| 3645 try { | |
| 3646 node.accept(this); | |
| 3647 } finally { | |
| 3648 _currentHolder = previousHolder; | |
| 3649 } | |
| 3650 } | |
| 3651 } | |
| 3652 | |
| 3653 /** | |
| 3654 * Make the given holder be the current holder while visiting the children of
the given node. | |
| 3655 * | |
| 3656 * @param holder the holder that will gather elements that are built while vis
iting the children | |
| 3657 * @param node the node whose children are to be visited | |
| 3658 */ | |
| 3659 void _visitChildren(ElementHolder holder, AstNode node) { | |
| 3660 if (node != null) { | |
| 3661 ElementHolder previousHolder = _currentHolder; | |
| 3662 _currentHolder = holder; | |
| 3663 try { | |
| 3664 node.visitChildren(this); | |
| 3665 } finally { | |
| 3666 _currentHolder = previousHolder; | |
| 3667 } | |
| 3668 } | |
| 3669 } | |
| 3670 } | |
| 3671 | |
| 3672 /** | |
| 3673 * Instances of the class `ElementHolder` hold on to elements created while trav
ersing an AST | 2617 * Instances of the class `ElementHolder` hold on to elements created while trav
ersing an AST |
| 3674 * structure so that they can be accessed when creating their enclosing element. | 2618 * structure so that they can be accessed when creating their enclosing element. |
| 3675 */ | 2619 */ |
| 3676 class ElementHolder { | 2620 class ElementHolder { |
| 3677 List<PropertyAccessorElement> _accessors; | 2621 List<PropertyAccessorElement> _accessors; |
| 3678 | 2622 |
| 3679 List<ConstructorElement> _constructors; | 2623 List<ConstructorElement> _constructors; |
| 3680 | 2624 |
| 3681 List<ClassElement> _enums; | 2625 List<ClassElement> _enums; |
| 3682 | 2626 |
| (...skipping 9790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13473 } | 12417 } |
| 13474 return new DartObjectImpl( | 12418 return new DartObjectImpl( |
| 13475 type is InterfaceType ? type : verifier._typeProvider.objectType, | 12419 type is InterfaceType ? type : verifier._typeProvider.objectType, |
| 13476 GenericState.UNKNOWN_VALUE); | 12420 GenericState.UNKNOWN_VALUE); |
| 13477 } | 12421 } |
| 13478 } | 12422 } |
| 13479 return super.visitSimpleIdentifier(node); | 12423 return super.visitSimpleIdentifier(node); |
| 13480 } | 12424 } |
| 13481 } | 12425 } |
| 13482 | 12426 |
| 13483 class _ElementBuilder_visitClassDeclaration extends UnifyingAstVisitor<Object> { | |
| 13484 final ElementBuilder builder; | |
| 13485 | |
| 13486 List<ClassMember> nonFields; | |
| 13487 | |
| 13488 _ElementBuilder_visitClassDeclaration(this.builder, this.nonFields) : super(); | |
| 13489 | |
| 13490 @override | |
| 13491 Object visitConstructorDeclaration(ConstructorDeclaration node) { | |
| 13492 nonFields.add(node); | |
| 13493 return null; | |
| 13494 } | |
| 13495 | |
| 13496 @override | |
| 13497 Object visitMethodDeclaration(MethodDeclaration node) { | |
| 13498 nonFields.add(node); | |
| 13499 return null; | |
| 13500 } | |
| 13501 | |
| 13502 @override | |
| 13503 Object visitNode(AstNode node) => node.accept(builder); | |
| 13504 } | |
| 13505 | |
| 13506 class _ResolverVisitor_isVariableAccessedInClosure | 12427 class _ResolverVisitor_isVariableAccessedInClosure |
| 13507 extends RecursiveAstVisitor<Object> { | 12428 extends RecursiveAstVisitor<Object> { |
| 13508 final Element variable; | 12429 final Element variable; |
| 13509 | 12430 |
| 13510 bool result = false; | 12431 bool result = false; |
| 13511 | 12432 |
| 13512 bool _inClosure = false; | 12433 bool _inClosure = false; |
| 13513 | 12434 |
| 13514 _ResolverVisitor_isVariableAccessedInClosure(this.variable); | 12435 _ResolverVisitor_isVariableAccessedInClosure(this.variable); |
| 13515 | 12436 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13585 nonFields.add(node); | 12506 nonFields.add(node); |
| 13586 return null; | 12507 return null; |
| 13587 } | 12508 } |
| 13588 | 12509 |
| 13589 @override | 12510 @override |
| 13590 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 12511 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
| 13591 | 12512 |
| 13592 @override | 12513 @override |
| 13593 Object visitWithClause(WithClause node) => null; | 12514 Object visitWithClause(WithClause node) => null; |
| 13594 } | 12515 } |
| OLD | NEW |