| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 /// ----------------------------------------------------------------------- | 5 /// ----------------------------------------------------------------------- |
| 6 /// ERROR HANDLING | 6 /// ERROR HANDLING |
| 7 /// ----------------------------------------------------------------------- | 7 /// ----------------------------------------------------------------------- |
| 8 /// | 8 /// |
| 9 /// As a rule of thumb, errors that can be detected statically are handled by | 9 /// As a rule of thumb, errors that can be detected statically are handled by |
| 10 /// the frontend, typically by translating the erroneous code into a 'throw' or | 10 /// the frontend, typically by translating the erroneous code into a 'throw' or |
| (...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 937 DartType get setterType { | 937 DartType get setterType { |
| 938 return isSetter | 938 return isSetter |
| 939 ? function.positionalParameters[0].type | 939 ? function.positionalParameters[0].type |
| 940 : const BottomType(); | 940 : const BottomType(); |
| 941 } | 941 } |
| 942 | 942 |
| 943 _MemberAccessor get _getterInterface => _reference; | 943 _MemberAccessor get _getterInterface => _reference; |
| 944 _MemberAccessor get _setterInterface => _reference; | 944 _MemberAccessor get _setterInterface => _reference; |
| 945 } | 945 } |
| 946 | 946 |
| 947 enum ProcedureKind { Method, Getter, Setter, Operator, Factory, } | 947 enum ProcedureKind { |
| 948 Method, |
| 949 Getter, |
| 950 Setter, |
| 951 Operator, |
| 952 Factory, |
| 953 } |
| 948 | 954 |
| 949 // ------------------------------------------------------------------------ | 955 // ------------------------------------------------------------------------ |
| 950 // CONSTRUCTOR INITIALIZERS | 956 // CONSTRUCTOR INITIALIZERS |
| 951 // ------------------------------------------------------------------------ | 957 // ------------------------------------------------------------------------ |
| 952 | 958 |
| 953 /// Part of an initializer list in a constructor. | 959 /// Part of an initializer list in a constructor. |
| 954 abstract class Initializer extends TreeNode { | 960 abstract class Initializer extends TreeNode { |
| 955 accept(InitializerVisitor v); | 961 accept(InitializerVisitor v); |
| 956 } | 962 } |
| 957 | 963 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 | 1099 |
| 1094 /// A function declares parameters and has a body. | 1100 /// A function declares parameters and has a body. |
| 1095 /// | 1101 /// |
| 1096 /// This may occur in a procedure, constructor, function expression, or local | 1102 /// This may occur in a procedure, constructor, function expression, or local |
| 1097 /// function declaration. | 1103 /// function declaration. |
| 1098 class FunctionNode extends TreeNode { | 1104 class FunctionNode extends TreeNode { |
| 1099 AsyncMarker asyncMarker; | 1105 AsyncMarker asyncMarker; |
| 1100 List<TypeParameter> typeParameters; | 1106 List<TypeParameter> typeParameters; |
| 1101 int requiredParameterCount; | 1107 int requiredParameterCount; |
| 1102 List<VariableDeclaration> positionalParameters; | 1108 List<VariableDeclaration> positionalParameters; |
| 1103 List<VariableDeclaration> namedParameters; | 1109 List<VariableDeclaration> namedParameters; // Must be sorted. |
| 1104 InferredValue inferredReturnValue; // May be null. | 1110 InferredValue inferredReturnValue; // May be null. |
| 1105 DartType returnType; // Not null. | 1111 DartType returnType; // Not null. |
| 1106 Statement body; | 1112 Statement body; |
| 1107 | 1113 |
| 1108 FunctionNode(this.body, | 1114 FunctionNode(this.body, |
| 1109 {List<TypeParameter> typeParameters, | 1115 {List<TypeParameter> typeParameters, |
| 1110 List<VariableDeclaration> positionalParameters, | 1116 List<VariableDeclaration> positionalParameters, |
| 1111 List<VariableDeclaration> namedParameters, | 1117 List<VariableDeclaration> namedParameters, |
| 1112 int requiredParameterCount, | 1118 int requiredParameterCount, |
| 1113 this.returnType: const DynamicType(), | 1119 this.returnType: const DynamicType(), |
| 1114 this.inferredReturnValue, | 1120 this.inferredReturnValue, |
| 1115 this.asyncMarker: AsyncMarker.Sync}) | 1121 this.asyncMarker: AsyncMarker.Sync}) |
| 1116 : this.positionalParameters = | 1122 : this.positionalParameters = |
| 1117 positionalParameters ?? <VariableDeclaration>[], | 1123 positionalParameters ?? <VariableDeclaration>[], |
| 1118 this.requiredParameterCount = | 1124 this.requiredParameterCount = |
| 1119 requiredParameterCount ?? positionalParameters?.length ?? 0, | 1125 requiredParameterCount ?? positionalParameters?.length ?? 0, |
| 1120 this.namedParameters = namedParameters ?? <VariableDeclaration>[], | 1126 this.namedParameters = namedParameters ?? <VariableDeclaration>[], |
| 1121 this.typeParameters = typeParameters ?? <TypeParameter>[] { | 1127 this.typeParameters = typeParameters ?? <TypeParameter>[] { |
| 1122 assert(returnType != null); | 1128 assert(returnType != null); |
| 1123 setParents(this.typeParameters, this); | 1129 setParents(this.typeParameters, this); |
| 1124 setParents(this.positionalParameters, this); | 1130 setParents(this.positionalParameters, this); |
| 1125 setParents(this.namedParameters, this); | 1131 setParents(this.namedParameters, this); |
| 1126 body?.parent = this; | 1132 body?.parent = this; |
| 1127 } | 1133 } |
| 1128 | 1134 |
| 1129 static DartType _getTypeOfVariable(VariableDeclaration node) => node.type; | 1135 static DartType _getTypeOfVariable(VariableDeclaration node) => node.type; |
| 1130 | 1136 |
| 1137 static NamedType _getNamedTypeOfVariable(VariableDeclaration node) { |
| 1138 return new NamedType(node.name, node.type); |
| 1139 } |
| 1140 |
| 1131 FunctionType get functionType { | 1141 FunctionType get functionType { |
| 1132 Map<String, DartType> named = const <String, DartType>{}; | 1142 Map<String, DartType> named = const <String, DartType>{}; |
| 1133 if (namedParameters.isNotEmpty) { | 1143 if (namedParameters.isNotEmpty) { |
| 1134 named = <String, DartType>{}; | 1144 named = <String, DartType>{}; |
| 1135 for (var node in namedParameters) { | 1145 for (var node in namedParameters) { |
| 1136 named[node.name] = node.type; | 1146 named[node.name] = node.type; |
| 1137 } | 1147 } |
| 1138 } | 1148 } |
| 1139 TreeNode parent = this.parent; | 1149 TreeNode parent = this.parent; |
| 1140 return new FunctionType( | 1150 return new FunctionType( |
| 1141 positionalParameters.map(_getTypeOfVariable).toList(), returnType, | 1151 positionalParameters.map(_getTypeOfVariable).toList(), returnType, |
| 1142 namedParameters: named, | 1152 namedParameters: namedParameters.map(_getNamedTypeOfVariable).toList(), |
| 1143 typeParameters: parent is Constructor | 1153 typeParameters: parent is Constructor |
| 1144 ? parent.enclosingClass.typeParameters | 1154 ? parent.enclosingClass.typeParameters |
| 1145 : typeParameters, | 1155 : typeParameters, |
| 1146 requiredParameterCount: requiredParameterCount); | 1156 requiredParameterCount: requiredParameterCount); |
| 1147 } | 1157 } |
| 1148 | 1158 |
| 1149 accept(TreeVisitor v) => v.visitFunctionNode(this); | 1159 accept(TreeVisitor v) => v.visitFunctionNode(this); |
| 1150 | 1160 |
| 1151 visitChildren(Visitor v) { | 1161 visitChildren(Visitor v) { |
| 1152 visitList(typeParameters, v); | 1162 visitList(typeParameters, v); |
| (...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1974 | 1984 |
| 1975 /// Expression of form `x ? y : z`. | 1985 /// Expression of form `x ? y : z`. |
| 1976 class ConditionalExpression extends Expression { | 1986 class ConditionalExpression extends Expression { |
| 1977 Expression condition; | 1987 Expression condition; |
| 1978 Expression then; | 1988 Expression then; |
| 1979 Expression otherwise; | 1989 Expression otherwise; |
| 1980 | 1990 |
| 1981 /// The static type of the expression. Should not be `null`. | 1991 /// The static type of the expression. Should not be `null`. |
| 1982 DartType staticType; | 1992 DartType staticType; |
| 1983 | 1993 |
| 1984 ConditionalExpression(this.condition, this.then, this.otherwise, | 1994 ConditionalExpression( |
| 1985 this.staticType) { | 1995 this.condition, this.then, this.otherwise, this.staticType) { |
| 1986 condition?.parent = this; | 1996 condition?.parent = this; |
| 1987 then?.parent = this; | 1997 then?.parent = this; |
| 1988 otherwise?.parent = this; | 1998 otherwise?.parent = this; |
| 1989 } | 1999 } |
| 1990 | 2000 |
| 1991 DartType getStaticType(TypeEnvironment types) => staticType; | 2001 DartType getStaticType(TypeEnvironment types) => staticType; |
| 1992 | 2002 |
| 1993 accept(ExpressionVisitor v) => v.visitConditionalExpression(this); | 2003 accept(ExpressionVisitor v) => v.visitConditionalExpression(this); |
| 1994 | 2004 |
| 1995 visitChildren(Visitor v) { | 2005 visitChildren(Visitor v) { |
| (...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2956 } | 2966 } |
| 2957 | 2967 |
| 2958 /// Declaration of a local variable. | 2968 /// Declaration of a local variable. |
| 2959 /// | 2969 /// |
| 2960 /// This may occur as a statement, but is also used in several non-statement | 2970 /// This may occur as a statement, but is also used in several non-statement |
| 2961 /// contexts, such as in [ForStatement], [Catch], and [FunctionNode]. | 2971 /// contexts, such as in [ForStatement], [Catch], and [FunctionNode]. |
| 2962 /// | 2972 /// |
| 2963 /// When this occurs as a statement, it must be a direct child of a [Block]. | 2973 /// When this occurs as a statement, it must be a direct child of a [Block]. |
| 2964 // | 2974 // |
| 2965 // DESIGN TODO: Should we remove the 'final' modifier from variables? | 2975 // DESIGN TODO: Should we remove the 'final' modifier from variables? |
| 2966 class VariableDeclaration extends Statement { | 2976 class VariableDeclaration extends Statement |
| 2977 implements Comparable<VariableDeclaration> { |
| 2967 /// For named parameters, this is the name of the parameter. No two named | 2978 /// For named parameters, this is the name of the parameter. No two named |
| 2968 /// parameters (in the same parameter list) can have the same name. | 2979 /// parameters (in the same parameter list) can have the same name. |
| 2969 /// | 2980 /// |
| 2970 /// In all other cases, the name is cosmetic, may be empty or null, | 2981 /// In all other cases, the name is cosmetic, may be empty or null, |
| 2971 /// and is not necessarily unique. | 2982 /// and is not necessarily unique. |
| 2972 String name; | 2983 String name; |
| 2973 int flags = 0; | 2984 int flags = 0; |
| 2974 DartType type; // Not null, defaults to dynamic. | 2985 DartType type; // Not null, defaults to dynamic. |
| 2975 InferredValue inferredValue; // May be null. | 2986 InferredValue inferredValue; // May be null. |
| 2976 | 2987 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3029 type = v.visitDartType(type); | 3040 type = v.visitDartType(type); |
| 3030 if (initializer != null) { | 3041 if (initializer != null) { |
| 3031 initializer = initializer.accept(v); | 3042 initializer = initializer.accept(v); |
| 3032 initializer?.parent = this; | 3043 initializer?.parent = this; |
| 3033 } | 3044 } |
| 3034 } | 3045 } |
| 3035 | 3046 |
| 3036 /// Returns a possibly synthesized name for this variable, consistent with | 3047 /// Returns a possibly synthesized name for this variable, consistent with |
| 3037 /// the names used across all [toString] calls. | 3048 /// the names used across all [toString] calls. |
| 3038 String toString() => debugVariableDeclarationName(this); | 3049 String toString() => debugVariableDeclarationName(this); |
| 3050 |
| 3051 int compareTo(VariableDeclaration other) { |
| 3052 return name.compareTo(other.name); |
| 3053 } |
| 3039 } | 3054 } |
| 3040 | 3055 |
| 3041 /// Declaration a local function. | 3056 /// Declaration a local function. |
| 3042 /// | 3057 /// |
| 3043 /// The body of the function may use [variable] as its self-reference. | 3058 /// The body of the function may use [variable] as its self-reference. |
| 3044 class FunctionDeclaration extends Statement { | 3059 class FunctionDeclaration extends Statement { |
| 3045 VariableDeclaration variable; // Is final and has no initializer. | 3060 VariableDeclaration variable; // Is final and has no initializer. |
| 3046 FunctionNode function; | 3061 FunctionNode function; |
| 3047 | 3062 |
| 3048 FunctionDeclaration(this.variable, this.function) { | 3063 FunctionDeclaration(this.variable, this.function) { |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3255 } | 3270 } |
| 3256 return hash; | 3271 return hash; |
| 3257 } | 3272 } |
| 3258 } | 3273 } |
| 3259 | 3274 |
| 3260 /// A possibly generic function type. | 3275 /// A possibly generic function type. |
| 3261 class FunctionType extends DartType { | 3276 class FunctionType extends DartType { |
| 3262 final List<TypeParameter> typeParameters; | 3277 final List<TypeParameter> typeParameters; |
| 3263 final int requiredParameterCount; | 3278 final int requiredParameterCount; |
| 3264 final List<DartType> positionalParameters; | 3279 final List<DartType> positionalParameters; |
| 3265 final Map<String, DartType> namedParameters; | 3280 final List<NamedType> namedParameters; // Must be sorted. |
| 3266 final DartType returnType; | 3281 final DartType returnType; |
| 3267 int _hashCode; | 3282 int _hashCode; |
| 3268 | 3283 |
| 3269 FunctionType(List<DartType> positionalParameters, this.returnType, | 3284 FunctionType(List<DartType> positionalParameters, this.returnType, |
| 3270 {this.namedParameters: const <String, DartType>{}, | 3285 {this.namedParameters: const <NamedType>[], |
| 3271 this.typeParameters: const <TypeParameter>[], | 3286 this.typeParameters: const <TypeParameter>[], |
| 3272 int requiredParameterCount}) | 3287 int requiredParameterCount}) |
| 3273 : this.positionalParameters = positionalParameters, | 3288 : this.positionalParameters = positionalParameters, |
| 3274 this.requiredParameterCount = | 3289 this.requiredParameterCount = |
| 3275 requiredParameterCount ?? positionalParameters.length; | 3290 requiredParameterCount ?? positionalParameters.length; |
| 3276 | 3291 |
| 3277 accept(DartTypeVisitor v) => v.visitFunctionType(this); | 3292 accept(DartTypeVisitor v) => v.visitFunctionType(this); |
| 3278 | 3293 |
| 3279 visitChildren(Visitor v) { | 3294 visitChildren(Visitor v) { |
| 3280 visitList(typeParameters, v); | 3295 visitList(typeParameters, v); |
| 3281 visitList(positionalParameters, v); | 3296 visitList(positionalParameters, v); |
| 3282 visitIterable(namedParameters.values, v); | 3297 visitList(namedParameters, v); |
| 3283 returnType.accept(v); | 3298 returnType.accept(v); |
| 3284 } | 3299 } |
| 3285 | 3300 |
| 3286 bool operator ==(Object other) { | 3301 bool operator ==(Object other) { |
| 3287 if (identical(this, other)) return true; | 3302 if (identical(this, other)) return true; |
| 3288 if (other is FunctionType) { | 3303 if (other is FunctionType) { |
| 3289 if (typeParameters.length != other.typeParameters.length || | 3304 if (typeParameters.length != other.typeParameters.length || |
| 3290 requiredParameterCount != other.requiredParameterCount || | 3305 requiredParameterCount != other.requiredParameterCount || |
| 3291 positionalParameters.length != other.positionalParameters.length || | 3306 positionalParameters.length != other.positionalParameters.length || |
| 3292 namedParameters.length != other.namedParameters.length) { | 3307 namedParameters.length != other.namedParameters.length) { |
| 3293 return false; | 3308 return false; |
| 3294 } | 3309 } |
| 3295 if (typeParameters.isEmpty) { | 3310 if (typeParameters.isEmpty) { |
| 3296 for (int i = 0; i < positionalParameters.length; ++i) { | 3311 for (int i = 0; i < positionalParameters.length; ++i) { |
| 3297 if (positionalParameters[i] != other.positionalParameters[i]) { | 3312 if (positionalParameters[i] != other.positionalParameters[i]) { |
| 3298 return false; | 3313 return false; |
| 3299 } | 3314 } |
| 3300 } | 3315 } |
| 3301 for (var name in namedParameters.keys) { | 3316 for (int i = 0; i < namedParameters.length; ++i) { |
| 3302 // If the other function type declared differently named parameters, | 3317 if (namedParameters[i] != other.namedParameters[i]) { |
| 3303 // one side of this equality will be null and we're good. | |
| 3304 if (namedParameters[name] != other.namedParameters[name]) { | |
| 3305 return false; | 3318 return false; |
| 3306 } | 3319 } |
| 3307 } | 3320 } |
| 3308 return returnType == other.returnType; | 3321 return returnType == other.returnType; |
| 3309 } else { | 3322 } else { |
| 3310 // Structural equality does not tell us if two generic function types | 3323 // Structural equality does not tell us if two generic function types |
| 3311 // are the same type. If they are unifiable without substituting any | 3324 // are the same type. If they are unifiable without substituting any |
| 3312 // type variables, they are equal. | 3325 // type variables, they are equal. |
| 3313 return unifyTypes(this, other, new Set<TypeParameter>()) != null; | 3326 return unifyTypes(this, other, new Set<TypeParameter>()) != null; |
| 3314 } | 3327 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3335 int hash = 1237; | 3348 int hash = 1237; |
| 3336 hash = 0x3fffffff & (hash * 31 + requiredParameterCount); | 3349 hash = 0x3fffffff & (hash * 31 + requiredParameterCount); |
| 3337 for (int i = 0; i < typeParameters.length; ++i) { | 3350 for (int i = 0; i < typeParameters.length; ++i) { |
| 3338 TypeParameter parameter = typeParameters[i]; | 3351 TypeParameter parameter = typeParameters[i]; |
| 3339 _temporaryHashCodeTable[parameter] = _temporaryHashCodeTable.length; | 3352 _temporaryHashCodeTable[parameter] = _temporaryHashCodeTable.length; |
| 3340 hash = 0x3fffffff & (hash * 31 + parameter.bound.hashCode); | 3353 hash = 0x3fffffff & (hash * 31 + parameter.bound.hashCode); |
| 3341 } | 3354 } |
| 3342 for (int i = 0; i < positionalParameters.length; ++i) { | 3355 for (int i = 0; i < positionalParameters.length; ++i) { |
| 3343 hash = 0x3fffffff & (hash * 31 + positionalParameters[i].hashCode); | 3356 hash = 0x3fffffff & (hash * 31 + positionalParameters[i].hashCode); |
| 3344 } | 3357 } |
| 3345 // TODO: Using a sorted list of names would be better than a map here. | 3358 for (int i = 0; i < namedParameters.length; ++i) { |
| 3346 namedParameters.forEach((String name, DartType type) { | 3359 hash = 0x3fffffff & (hash * 31 + namedParameters[i].hashCode); |
| 3347 // Note that we use only addition and truncation here, so that we do not | 3360 } |
| 3348 // rely on the iteration of the of the map. | |
| 3349 hash = 0x3fffffff & (hash + name.hashCode); | |
| 3350 hash = 0x3fffffff & (hash + type.hashCode); | |
| 3351 }); | |
| 3352 hash = 0x3fffffff & (hash * 31 + returnType.hashCode); | 3361 hash = 0x3fffffff & (hash * 31 + returnType.hashCode); |
| 3353 for (int i = 0; i < typeParameters.length; ++i) { | 3362 for (int i = 0; i < typeParameters.length; ++i) { |
| 3354 // Remove the type parameters from the scope again. | 3363 // Remove the type parameters from the scope again. |
| 3355 _temporaryHashCodeTable.remove(typeParameters[i]); | 3364 _temporaryHashCodeTable.remove(typeParameters[i]); |
| 3356 } | 3365 } |
| 3357 return hash; | 3366 return hash; |
| 3358 } | 3367 } |
| 3359 } | 3368 } |
| 3360 | 3369 |
| 3370 /// A named parameter in [FunctionType]. |
| 3371 class NamedType extends Node implements Comparable<NamedType> { |
| 3372 final String name; |
| 3373 final DartType type; |
| 3374 |
| 3375 NamedType(this.name, this.type); |
| 3376 |
| 3377 bool operator ==(Object other) { |
| 3378 return other is NamedType && name == other.name && type == other.type; |
| 3379 } |
| 3380 |
| 3381 int get hashCode { |
| 3382 return name.hashCode * 31 + type.hashCode * 37; |
| 3383 } |
| 3384 |
| 3385 int compareTo(NamedType other) => name.compareTo(other.name); |
| 3386 |
| 3387 accept(Visitor v) => v.visitNamedType(this); |
| 3388 |
| 3389 void visitChildren(Visitor v) { |
| 3390 type.accept(v); |
| 3391 } |
| 3392 } |
| 3393 |
| 3361 /// Stores the hash code of function type parameters while computing the hash | 3394 /// Stores the hash code of function type parameters while computing the hash |
| 3362 /// code of a [FunctionType] object. | 3395 /// code of a [FunctionType] object. |
| 3363 /// | 3396 /// |
| 3364 /// This ensures that distinct [FunctionType] objects get the same hash code | 3397 /// This ensures that distinct [FunctionType] objects get the same hash code |
| 3365 /// if they represent the same type, even though their type parameters are | 3398 /// if they represent the same type, even though their type parameters are |
| 3366 /// represented by different objects. | 3399 /// represented by different objects. |
| 3367 final Map<TypeParameter, int> _temporaryHashCodeTable = <TypeParameter, int>{}; | 3400 final Map<TypeParameter, int> _temporaryHashCodeTable = <TypeParameter, int>{}; |
| 3368 | 3401 |
| 3369 /// Reference to a type variable. | 3402 /// Reference to a type variable. |
| 3370 class TypeParameterType extends DartType { | 3403 class TypeParameterType extends DartType { |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3606 | 3639 |
| 3607 @override | 3640 @override |
| 3608 defaultTreeNode(TreeNode node) { | 3641 defaultTreeNode(TreeNode node) { |
| 3609 if (node == child) { | 3642 if (node == child) { |
| 3610 return replacement; | 3643 return replacement; |
| 3611 } else { | 3644 } else { |
| 3612 return node; | 3645 return node; |
| 3613 } | 3646 } |
| 3614 } | 3647 } |
| 3615 } | 3648 } |
| OLD | NEW |