Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 1659973002: Move ElementBuilder and CompilationUnitBuilder into builder.dart. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/incremental_resolver.dart ('k') | pkg/analyzer/lib/src/task/incremental_element_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698