| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 dart2js.constants.constructors; | 5 library dart2js.constants.constructors; |
| 6 | 6 |
| 7 import '../dart_types.dart'; | 7 import '../dart_types.dart'; |
| 8 import '../elements/elements.dart' show | 8 import '../elements/elements.dart' show ConstructorElement, FieldElement; |
| 9 ConstructorElement, | 9 import '../universe/call_structure.dart' show CallStructure; |
| 10 FieldElement; | |
| 11 import '../universe/call_structure.dart' show | |
| 12 CallStructure; | |
| 13 import '../util/util.dart'; | 10 import '../util/util.dart'; |
| 14 import 'evaluation.dart'; | 11 import 'evaluation.dart'; |
| 15 import 'expressions.dart'; | 12 import 'expressions.dart'; |
| 16 | 13 |
| 17 enum ConstantConstructorKind { | 14 enum ConstantConstructorKind { |
| 18 GENERATIVE, | 15 GENERATIVE, |
| 19 REDIRECTING_GENERATIVE, | 16 REDIRECTING_GENERATIVE, |
| 20 REDIRECTING_FACTORY, | 17 REDIRECTING_FACTORY, |
| 21 } | 18 } |
| 22 | 19 |
| 23 /// Definition of a constant constructor. | 20 /// Definition of a constant constructor. |
| 24 abstract class ConstantConstructor { | 21 abstract class ConstantConstructor { |
| 25 ConstantConstructorKind get kind; | 22 ConstantConstructorKind get kind; |
| 26 | 23 |
| 27 /// Computes the type of the instance created in a const constructor | 24 /// Computes the type of the instance created in a const constructor |
| 28 /// invocation with type [newType]. | 25 /// invocation with type [newType]. |
| 29 InterfaceType computeInstanceType(InterfaceType newType); | 26 InterfaceType computeInstanceType(InterfaceType newType); |
| 30 | 27 |
| 31 /// Computes the constant expressions of the fields of the created instance | 28 /// Computes the constant expressions of the fields of the created instance |
| 32 /// in a const constructor invocation with [arguments]. | 29 /// in a const constructor invocation with [arguments]. |
| 33 Map<FieldElement, ConstantExpression> computeInstanceFields( | 30 Map<FieldElement, ConstantExpression> computeInstanceFields( |
| 34 List<ConstantExpression> arguments, | 31 List<ConstantExpression> arguments, CallStructure callStructure); |
| 35 CallStructure callStructure); | |
| 36 | 32 |
| 37 accept(ConstantConstructorVisitor visitor, arg); | 33 accept(ConstantConstructorVisitor visitor, arg); |
| 38 } | 34 } |
| 39 | 35 |
| 40 abstract class ConstantConstructorVisitor<R, A> { | 36 abstract class ConstantConstructorVisitor<R, A> { |
| 41 const ConstantConstructorVisitor(); | 37 const ConstantConstructorVisitor(); |
| 42 | 38 |
| 43 R visit(ConstantConstructor constantConstructor, A context) { | 39 R visit(ConstantConstructor constantConstructor, A context) { |
| 44 return constantConstructor.accept(this, context); | 40 return constantConstructor.accept(this, context); |
| 45 } | 41 } |
| 46 | 42 |
| 47 R visitGenerative(GenerativeConstantConstructor constructor, A arg); | 43 R visitGenerative(GenerativeConstantConstructor constructor, A arg); |
| 48 R visitRedirectingGenerative( | 44 R visitRedirectingGenerative( |
| 49 RedirectingGenerativeConstantConstructor constructor, A arg); | 45 RedirectingGenerativeConstantConstructor constructor, A arg); |
| 50 R visitRedirectingFactory( | 46 R visitRedirectingFactory( |
| 51 RedirectingFactoryConstantConstructor constructor, A arg); | 47 RedirectingFactoryConstantConstructor constructor, A arg); |
| 52 } | 48 } |
| 53 | 49 |
| 54 /// A generative constant constructor. | 50 /// A generative constant constructor. |
| 55 class GenerativeConstantConstructor implements ConstantConstructor{ | 51 class GenerativeConstantConstructor implements ConstantConstructor { |
| 56 final InterfaceType type; | 52 final InterfaceType type; |
| 57 final Map<dynamic/*int|String*/, ConstantExpression> defaultValues; | 53 final Map<dynamic /*int|String*/, ConstantExpression> defaultValues; |
| 58 final Map<FieldElement, ConstantExpression> fieldMap; | 54 final Map<FieldElement, ConstantExpression> fieldMap; |
| 59 final ConstructedConstantExpression superConstructorInvocation; | 55 final ConstructedConstantExpression superConstructorInvocation; |
| 60 | 56 |
| 61 GenerativeConstantConstructor( | 57 GenerativeConstantConstructor(this.type, this.defaultValues, this.fieldMap, |
| 62 this.type, | |
| 63 this.defaultValues, | |
| 64 this.fieldMap, | |
| 65 this.superConstructorInvocation); | 58 this.superConstructorInvocation); |
| 66 | 59 |
| 67 ConstantConstructorKind get kind => ConstantConstructorKind.GENERATIVE; | 60 ConstantConstructorKind get kind => ConstantConstructorKind.GENERATIVE; |
| 68 | 61 |
| 69 InterfaceType computeInstanceType(InterfaceType newType) { | 62 InterfaceType computeInstanceType(InterfaceType newType) { |
| 70 return type.substByContext(newType); | 63 return type.substByContext(newType); |
| 71 } | 64 } |
| 72 | 65 |
| 73 Map<FieldElement, ConstantExpression> computeInstanceFields( | 66 Map<FieldElement, ConstantExpression> computeInstanceFields( |
| 74 List<ConstantExpression> arguments, | 67 List<ConstantExpression> arguments, CallStructure callStructure) { |
| 75 CallStructure callStructure) { | 68 NormalizedArguments args = |
| 76 NormalizedArguments args = new NormalizedArguments( | 69 new NormalizedArguments(defaultValues, callStructure, arguments); |
| 77 defaultValues, callStructure, arguments); | |
| 78 Map<FieldElement, ConstantExpression> appliedFieldMap = | 70 Map<FieldElement, ConstantExpression> appliedFieldMap = |
| 79 applyFields(args, superConstructorInvocation); | 71 applyFields(args, superConstructorInvocation); |
| 80 fieldMap.forEach((FieldElement field, ConstantExpression constant) { | 72 fieldMap.forEach((FieldElement field, ConstantExpression constant) { |
| 81 appliedFieldMap[field] = constant.apply(args); | 73 appliedFieldMap[field] = constant.apply(args); |
| 82 }); | 74 }); |
| 83 return appliedFieldMap; | 75 return appliedFieldMap; |
| 84 } | 76 } |
| 85 | 77 |
| 86 accept(ConstantConstructorVisitor visitor, arg) { | 78 accept(ConstantConstructorVisitor visitor, arg) { |
| 87 return visitor.visitGenerative(this, arg); | 79 return visitor.visitGenerative(this, arg); |
| 88 } | 80 } |
| 89 | 81 |
| 90 int get hashCode { | 82 int get hashCode { |
| 91 int hash = Hashing.objectHash(type); | 83 int hash = Hashing.objectHash(type); |
| 92 hash = Hashing.mapHash(defaultValues, hash); | 84 hash = Hashing.mapHash(defaultValues, hash); |
| 93 hash = Hashing.mapHash(fieldMap, hash); | 85 hash = Hashing.mapHash(fieldMap, hash); |
| 94 return Hashing.objectHash(superConstructorInvocation, hash); | 86 return Hashing.objectHash(superConstructorInvocation, hash); |
| 95 } | 87 } |
| 96 | 88 |
| 97 bool operator ==(other) { | 89 bool operator ==(other) { |
| 98 if (identical(this, other)) return true; | 90 if (identical(this, other)) return true; |
| 99 if (other is! GenerativeConstantConstructor) return false; | 91 if (other is! GenerativeConstantConstructor) return false; |
| 100 return | 92 return type == other.type && |
| 101 type == other.type && | |
| 102 superConstructorInvocation == other.superConstructorInvocation && | 93 superConstructorInvocation == other.superConstructorInvocation && |
| 103 mapEquals(defaultValues, other.defaultValues) && | 94 mapEquals(defaultValues, other.defaultValues) && |
| 104 mapEquals(fieldMap, other.fieldMap); | 95 mapEquals(fieldMap, other.fieldMap); |
| 105 } | 96 } |
| 106 | 97 |
| 107 String toString() { | 98 String toString() { |
| 108 StringBuffer sb = new StringBuffer(); | 99 StringBuffer sb = new StringBuffer(); |
| 109 sb.write("{'type': $type"); | 100 sb.write("{'type': $type"); |
| 110 defaultValues.forEach((key, ConstantExpression expression) { | 101 defaultValues.forEach((key, ConstantExpression expression) { |
| 111 sb.write(",\n 'default:${key}': ${expression.getText()}"); | 102 sb.write(",\n 'default:${key}': ${expression.getText()}"); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 fieldMap.forEach((FieldElement field, ConstantExpression constant) { | 135 fieldMap.forEach((FieldElement field, ConstantExpression constant) { |
| 145 appliedFieldMap[field] = constant.apply(args); | 136 appliedFieldMap[field] = constant.apply(args); |
| 146 }); | 137 }); |
| 147 } | 138 } |
| 148 return appliedFieldMap; | 139 return appliedFieldMap; |
| 149 } | 140 } |
| 150 } | 141 } |
| 151 | 142 |
| 152 /// A redirecting generative constant constructor. | 143 /// A redirecting generative constant constructor. |
| 153 class RedirectingGenerativeConstantConstructor implements ConstantConstructor { | 144 class RedirectingGenerativeConstantConstructor implements ConstantConstructor { |
| 154 final Map<dynamic/*int|String*/, ConstantExpression> defaultValues; | 145 final Map<dynamic /*int|String*/, ConstantExpression> defaultValues; |
| 155 final ConstructedConstantExpression thisConstructorInvocation; | 146 final ConstructedConstantExpression thisConstructorInvocation; |
| 156 | 147 |
| 157 RedirectingGenerativeConstantConstructor( | 148 RedirectingGenerativeConstantConstructor( |
| 158 this.defaultValues, | 149 this.defaultValues, this.thisConstructorInvocation); |
| 159 this.thisConstructorInvocation); | |
| 160 | 150 |
| 161 ConstantConstructorKind get kind { | 151 ConstantConstructorKind get kind { |
| 162 return ConstantConstructorKind.REDIRECTING_GENERATIVE; | 152 return ConstantConstructorKind.REDIRECTING_GENERATIVE; |
| 163 } | 153 } |
| 164 | 154 |
| 165 InterfaceType computeInstanceType(InterfaceType newType) { | 155 InterfaceType computeInstanceType(InterfaceType newType) { |
| 166 return thisConstructorInvocation.computeInstanceType() | 156 return thisConstructorInvocation |
| 157 .computeInstanceType() |
| 167 .substByContext(newType); | 158 .substByContext(newType); |
| 168 } | 159 } |
| 169 | 160 |
| 170 Map<FieldElement, ConstantExpression> computeInstanceFields( | 161 Map<FieldElement, ConstantExpression> computeInstanceFields( |
| 171 List<ConstantExpression> arguments, | 162 List<ConstantExpression> arguments, CallStructure callStructure) { |
| 172 CallStructure callStructure) { | |
| 173 NormalizedArguments args = | 163 NormalizedArguments args = |
| 174 new NormalizedArguments(defaultValues, callStructure, arguments); | 164 new NormalizedArguments(defaultValues, callStructure, arguments); |
| 175 Map<FieldElement, ConstantExpression> appliedFieldMap = | 165 Map<FieldElement, ConstantExpression> appliedFieldMap = |
| 176 GenerativeConstantConstructor.applyFields( | 166 GenerativeConstantConstructor.applyFields( |
| 177 args, thisConstructorInvocation); | 167 args, thisConstructorInvocation); |
| 178 return appliedFieldMap; | 168 return appliedFieldMap; |
| 179 } | 169 } |
| 180 | 170 |
| 181 accept(ConstantConstructorVisitor visitor, arg) { | 171 accept(ConstantConstructorVisitor visitor, arg) { |
| 182 return visitor.visitRedirectingGenerative(this, arg); | 172 return visitor.visitRedirectingGenerative(this, arg); |
| 183 } | 173 } |
| 184 | 174 |
| 185 int get hashCode { | 175 int get hashCode { |
| 186 int hash = Hashing.objectHash(thisConstructorInvocation); | 176 int hash = Hashing.objectHash(thisConstructorInvocation); |
| 187 return Hashing.mapHash(defaultValues, hash); | 177 return Hashing.mapHash(defaultValues, hash); |
| 188 } | 178 } |
| 189 | 179 |
| 190 bool operator ==(other) { | 180 bool operator ==(other) { |
| 191 if (identical(this, other)) return true; | 181 if (identical(this, other)) return true; |
| 192 if (other is! RedirectingGenerativeConstantConstructor) return false; | 182 if (other is! RedirectingGenerativeConstantConstructor) return false; |
| 193 return | 183 return thisConstructorInvocation == other.thisConstructorInvocation && |
| 194 thisConstructorInvocation == other.thisConstructorInvocation && | |
| 195 GenerativeConstantConstructor.mapEquals( | 184 GenerativeConstantConstructor.mapEquals( |
| 196 defaultValues, other.defaultValues); | 185 defaultValues, other.defaultValues); |
| 197 } | 186 } |
| 198 | 187 |
| 199 String toString() { | 188 String toString() { |
| 200 StringBuffer sb = new StringBuffer(); | 189 StringBuffer sb = new StringBuffer(); |
| 201 sb.write("{'type': ${thisConstructorInvocation.type}"); | 190 sb.write("{'type': ${thisConstructorInvocation.type}"); |
| 202 defaultValues.forEach((key, ConstantExpression expression) { | 191 defaultValues.forEach((key, ConstantExpression expression) { |
| 203 sb.write(",\n 'default:${key}': ${expression.getText()}"); | 192 sb.write(",\n 'default:${key}': ${expression.getText()}"); |
| 204 }); | 193 }); |
| 205 sb.write(",\n 'constructor': ${thisConstructorInvocation.getText()}"); | 194 sb.write(",\n 'constructor': ${thisConstructorInvocation.getText()}"); |
| 206 sb.write("}"); | 195 sb.write("}"); |
| 207 return sb.toString(); | 196 return sb.toString(); |
| 208 } | 197 } |
| 209 } | 198 } |
| 210 | 199 |
| 211 /// A redirecting factory constant constructor. | 200 /// A redirecting factory constant constructor. |
| 212 class RedirectingFactoryConstantConstructor implements ConstantConstructor { | 201 class RedirectingFactoryConstantConstructor implements ConstantConstructor { |
| 213 final ConstructedConstantExpression targetConstructorInvocation; | 202 final ConstructedConstantExpression targetConstructorInvocation; |
| 214 | 203 |
| 215 RedirectingFactoryConstantConstructor(this.targetConstructorInvocation); | 204 RedirectingFactoryConstantConstructor(this.targetConstructorInvocation); |
| 216 | 205 |
| 217 ConstantConstructorKind get kind { | 206 ConstantConstructorKind get kind { |
| 218 return ConstantConstructorKind.REDIRECTING_FACTORY; | 207 return ConstantConstructorKind.REDIRECTING_FACTORY; |
| 219 } | 208 } |
| 220 | 209 |
| 221 InterfaceType computeInstanceType(InterfaceType newType) { | 210 InterfaceType computeInstanceType(InterfaceType newType) { |
| 222 return targetConstructorInvocation.computeInstanceType() | 211 return targetConstructorInvocation |
| 212 .computeInstanceType() |
| 223 .substByContext(newType); | 213 .substByContext(newType); |
| 224 } | 214 } |
| 225 | 215 |
| 226 Map<FieldElement, ConstantExpression> computeInstanceFields( | 216 Map<FieldElement, ConstantExpression> computeInstanceFields( |
| 227 List<ConstantExpression> arguments, | 217 List<ConstantExpression> arguments, CallStructure callStructure) { |
| 228 CallStructure callStructure) { | |
| 229 ConstantConstructor constantConstructor = | 218 ConstantConstructor constantConstructor = |
| 230 targetConstructorInvocation.target.constantConstructor; | 219 targetConstructorInvocation.target.constantConstructor; |
| 231 return constantConstructor.computeInstanceFields(arguments, callStructure); | 220 return constantConstructor.computeInstanceFields(arguments, callStructure); |
| 232 } | 221 } |
| 233 | 222 |
| 234 accept(ConstantConstructorVisitor visitor, arg) { | 223 accept(ConstantConstructorVisitor visitor, arg) { |
| 235 return visitor.visitRedirectingFactory(this, arg); | 224 return visitor.visitRedirectingFactory(this, arg); |
| 236 } | 225 } |
| 237 | 226 |
| 238 int get hashCode { | 227 int get hashCode { |
| 239 return Hashing.objectHash(targetConstructorInvocation); | 228 return Hashing.objectHash(targetConstructorInvocation); |
| 240 } | 229 } |
| 241 | 230 |
| 242 bool operator ==(other) { | 231 bool operator ==(other) { |
| 243 if (identical(this, other)) return true; | 232 if (identical(this, other)) return true; |
| 244 if (other is! RedirectingFactoryConstantConstructor) return false; | 233 if (other is! RedirectingFactoryConstantConstructor) return false; |
| 245 return targetConstructorInvocation == other.targetConstructorInvocation; | 234 return targetConstructorInvocation == other.targetConstructorInvocation; |
| 246 } | 235 } |
| 247 | 236 |
| 248 String toString() { | 237 String toString() { |
| 249 StringBuffer sb = new StringBuffer(); | 238 StringBuffer sb = new StringBuffer(); |
| 250 sb.write("{"); | 239 sb.write("{"); |
| 251 sb.write("'constructor': ${targetConstructorInvocation.getText()}"); | 240 sb.write("'constructor': ${targetConstructorInvocation.getText()}"); |
| 252 sb.write("}"); | 241 sb.write("}"); |
| 253 return sb.toString(); | 242 return sb.toString(); |
| 254 } | 243 } |
| 255 } | 244 } |
| OLD | NEW |