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

Side by Side Diff: lib/ast.dart

Issue 2502343002: Store named parameters in sorted lists instead of using maps. (Closed)
Patch Set: Remove duplicates from named parameter lists to recover from erroneous inputs Created 4 years, 1 month 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
« no previous file with comments | « lib/analyzer/ast_from_analyzer.dart ('k') | lib/binary/ast_from_binary.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « lib/analyzer/ast_from_analyzer.dart ('k') | lib/binary/ast_from_binary.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698