OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 part of js_backend; | 5 part of js_backend; |
6 | 6 |
7 /** | 7 /** |
8 * Assigns JavaScript identifiers to Dart variables, class-names and members. | 8 * Assigns JavaScript identifiers to Dart variables, class-names and members. |
9 */ | 9 */ |
10 class Namer implements ClosureNamer { | 10 class Namer implements ClosureNamer { |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
249 final Set<String> usedGlobalNames; | 249 final Set<String> usedGlobalNames; |
250 final Set<String> usedInstanceNames; | 250 final Set<String> usedInstanceNames; |
251 final Map<String, String> globalNameMap; | 251 final Map<String, String> globalNameMap; |
252 final Map<String, String> suggestedGlobalNames; | 252 final Map<String, String> suggestedGlobalNames; |
253 final Map<String, String> instanceNameMap; | 253 final Map<String, String> instanceNameMap; |
254 final Map<String, String> suggestedInstanceNames; | 254 final Map<String, String> suggestedInstanceNames; |
255 | 255 |
256 final Map<String, String> operatorNameMap; | 256 final Map<String, String> operatorNameMap; |
257 final Map<String, int> popularNameCounters; | 257 final Map<String, int> popularNameCounters; |
258 | 258 |
259 final Map<Constant, String> constantNames; | 259 final Map<ConstantValue, String> constantNames; |
260 final Map<Constant, String> constantLongNames; | 260 final Map<ConstantValue, String> constantLongNames; |
261 ConstantCanonicalHasher constantHasher; | 261 ConstantCanonicalHasher constantHasher; |
262 | 262 |
263 // All alphanumeric characters. | 263 // All alphanumeric characters. |
264 static const String _alphaNumeric = | 264 static const String _alphaNumeric = |
265 'abcdefghijklmnopqrstuvwxyzABZDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; | 265 'abcdefghijklmnopqrstuvwxyzABZDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; |
266 | 266 |
267 Namer(Compiler compiler) | 267 Namer(Compiler compiler) |
268 : compiler = compiler, | 268 : compiler = compiler, |
269 globals = new Map<Element, String>(), | 269 globals = new Map<Element, String>(), |
270 shortPrivateNameOwners = new Map<String, LibraryElement>(), | 270 shortPrivateNameOwners = new Map<String, LibraryElement>(), |
271 usedGlobalNames = new Set<String>(), | 271 usedGlobalNames = new Set<String>(), |
272 usedInstanceNames = new Set<String>(), | 272 usedInstanceNames = new Set<String>(), |
273 instanceNameMap = new Map<String, String>(), | 273 instanceNameMap = new Map<String, String>(), |
274 operatorNameMap = new Map<String, String>(), | 274 operatorNameMap = new Map<String, String>(), |
275 globalNameMap = new Map<String, String>(), | 275 globalNameMap = new Map<String, String>(), |
276 suggestedGlobalNames = new Map<String, String>(), | 276 suggestedGlobalNames = new Map<String, String>(), |
277 suggestedInstanceNames = new Map<String, String>(), | 277 suggestedInstanceNames = new Map<String, String>(), |
278 popularNameCounters = new Map<String, int>(), | 278 popularNameCounters = new Map<String, int>(), |
279 constantNames = new Map<Constant, String>(), | 279 constantNames = new Map<ConstantValue, String>(), |
280 constantLongNames = new Map<Constant, String>(), | 280 constantLongNames = new Map<ConstantValue, String>(), |
281 constantHasher = new ConstantCanonicalHasher(compiler), | 281 constantHasher = new ConstantCanonicalHasher(compiler), |
282 functionTypeNamer = new FunctionTypeNamer(compiler); | 282 functionTypeNamer = new FunctionTypeNamer(compiler); |
283 | 283 |
284 JavaScriptBackend get backend => compiler.backend; | 284 JavaScriptBackend get backend => compiler.backend; |
285 | 285 |
286 String get isolateName => 'Isolate'; | 286 String get isolateName => 'Isolate'; |
287 String get isolatePropertiesName => r'$isolateProperties'; | 287 String get isolatePropertiesName => r'$isolateProperties'; |
288 /** | 288 /** |
289 * Some closures must contain their name. The name is stored in | 289 * Some closures must contain their name. The name is stored in |
290 * [STATIC_CLOSURE_NAME_NAME]. | 290 * [STATIC_CLOSURE_NAME_NAME]. |
(...skipping 11 matching lines...) Expand all Loading... | |
302 case 'REFLECTABLE': return reflectableField; | 302 case 'REFLECTABLE': return reflectableField; |
303 case 'CLASS_DESCRIPTOR_PROPERTY': return classDescriptorProperty; | 303 case 'CLASS_DESCRIPTOR_PROPERTY': return classDescriptorProperty; |
304 default: | 304 default: |
305 compiler.reportError( | 305 compiler.reportError( |
306 node, MessageKind.GENERIC, | 306 node, MessageKind.GENERIC, |
307 {'text': 'Error: Namer has no name for "$name".'}); | 307 {'text': 'Error: Namer has no name for "$name".'}); |
308 return 'BROKEN'; | 308 return 'BROKEN'; |
309 } | 309 } |
310 } | 310 } |
311 | 311 |
312 String constantName(Constant constant) { | 312 String constantName(ConstantValue constant) { |
313 // In the current implementation it doesn't make sense to give names to | 313 // In the current implementation it doesn't make sense to give names to |
314 // function constants since the function-implementation itself serves as | 314 // function constants since the function-implementation itself serves as |
315 // constant and can be accessed directly. | 315 // constant and can be accessed directly. |
316 assert(!constant.isFunction); | 316 assert(!constant.isFunction); |
317 String result = constantNames[constant]; | 317 String result = constantNames[constant]; |
318 if (result == null) { | 318 if (result == null) { |
319 String longName = constantLongName(constant); | 319 String longName = constantLongName(constant); |
320 result = getFreshName(longName, usedGlobalNames, suggestedGlobalNames, | 320 result = getFreshName(longName, usedGlobalNames, suggestedGlobalNames, |
321 ensureSafe: true); | 321 ensureSafe: true); |
322 constantNames[constant] = result; | 322 constantNames[constant] = result; |
323 } | 323 } |
324 return result; | 324 return result; |
325 } | 325 } |
326 | 326 |
327 // The long name is unminified and may have collisions. | 327 // The long name is unminified and may have collisions. |
328 String constantLongName(Constant constant) { | 328 String constantLongName(ConstantValue constant) { |
329 String longName = constantLongNames[constant]; | 329 String longName = constantLongNames[constant]; |
330 if (longName == null) { | 330 if (longName == null) { |
331 longName = new ConstantNamingVisitor(compiler, constantHasher) | 331 longName = new ConstantNamingVisitor(compiler, constantHasher) |
332 .getName(constant); | 332 .getName(constant); |
333 constantLongNames[constant] = longName; | 333 constantLongNames[constant] = longName; |
334 } | 334 } |
335 return longName; | 335 return longName; |
336 } | 336 } |
337 | 337 |
338 String breakLabelName(LabelDefinition label) { | 338 String breakLabelName(LabelDefinition label) { |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
873 [globalObjectFor(element), getStaticClosureName(element)]); | 873 [globalObjectFor(element), getStaticClosureName(element)]); |
874 } | 874 } |
875 | 875 |
876 // This name is used as part of the name of a TypeConstant | 876 // This name is used as part of the name of a TypeConstant |
877 String uniqueNameForTypeConstantElement(Element element) { | 877 String uniqueNameForTypeConstantElement(Element element) { |
878 // TODO(sra): If we replace the period with an identifier character, | 878 // TODO(sra): If we replace the period with an identifier character, |
879 // TypeConstants will have better names in unminified code. | 879 // TypeConstants will have better names in unminified code. |
880 return "${globalObjectFor(element)}.${getNameX(element)}"; | 880 return "${globalObjectFor(element)}.${getNameX(element)}"; |
881 } | 881 } |
882 | 882 |
883 String globalObjectForConstant(Constant constant) => 'C'; | 883 String globalObjectForConstant(ConstantValue constant) => 'C'; |
884 | 884 |
885 String operatorIsPrefix() => r'$is'; | 885 String operatorIsPrefix() => r'$is'; |
886 | 886 |
887 String operatorAsPrefix() => r'$as'; | 887 String operatorAsPrefix() => r'$as'; |
888 | 888 |
889 String operatorSignature() => r'$signature'; | 889 String operatorSignature() => r'$signature'; |
890 | 890 |
891 String typedefTag() => r'typedef'; | 891 String typedefTag() => r'typedef'; |
892 | 892 |
893 String functionTypeTag() => r'func'; | 893 String functionTypeTag() => r'func'; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
999 | 999 |
1000 void forgetElement(Element element) { | 1000 void forgetElement(Element element) { |
1001 String globalName = globals[element]; | 1001 String globalName = globals[element]; |
1002 invariant(element, globalName != null, message: 'No global name.'); | 1002 invariant(element, globalName != null, message: 'No global name.'); |
1003 usedGlobalNames.remove(globalName); | 1003 usedGlobalNames.remove(globalName); |
1004 globals.remove(element); | 1004 globals.remove(element); |
1005 } | 1005 } |
1006 } | 1006 } |
1007 | 1007 |
1008 /** | 1008 /** |
1009 * Generator of names for [Constant] values. | 1009 * Generator of names for [ConstantValue] values. |
1010 * | 1010 * |
1011 * The names are stable under perturbations of the source. The name is either a | 1011 * The names are stable under perturbations of the source. The name is either a |
1012 * short sequence of words, if this can be found from the constant, or a type | 1012 * short sequence of words, if this can be found from the constant, or a type |
1013 * followed by a hash tag. | 1013 * followed by a hash tag. |
1014 * | 1014 * |
1015 * List_imX // A List, with hash tag. | 1015 * List_imX // A List, with hash tag. |
1016 * C_Sentinel // const Sentinel(), "C_" added to avoid clash | 1016 * C_Sentinel // const Sentinel(), "C_" added to avoid clash |
1017 * // with class name. | 1017 * // with class name. |
1018 * JSInt_methods // an interceptor. | 1018 * JSInt_methods // an interceptor. |
1019 * Duration_16000 // const Duration(milliseconds: 16) | 1019 * Duration_16000 // const Duration(milliseconds: 16) |
1020 * EventKeyProvider_keyup // const EventKeyProvider('keyup') | 1020 * EventKeyProvider_keyup // const EventKeyProvider('keyup') |
1021 * | 1021 * |
1022 */ | 1022 */ |
1023 class ConstantNamingVisitor implements ConstantVisitor { | 1023 class ConstantNamingVisitor implements ConstantValueVisitor { |
1024 | 1024 |
1025 static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$'); | 1025 static final RegExp IDENTIFIER = new RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$'); |
1026 static const MAX_FRAGMENTS = 5; | 1026 static const MAX_FRAGMENTS = 5; |
1027 static const MAX_EXTRA_LENGTH = 30; | 1027 static const MAX_EXTRA_LENGTH = 30; |
1028 static const DEFAULT_TAG_LENGTH = 3; | 1028 static const DEFAULT_TAG_LENGTH = 3; |
1029 | 1029 |
1030 final Compiler compiler; | 1030 final Compiler compiler; |
1031 final ConstantCanonicalHasher hasher; | 1031 final ConstantCanonicalHasher hasher; |
1032 | 1032 |
1033 String root = null; // First word, usually a type name. | 1033 String root = null; // First word, usually a type name. |
1034 bool failed = false; // Failed to generate something pretty. | 1034 bool failed = false; // Failed to generate something pretty. |
1035 List<String> fragments = <String>[]; | 1035 List<String> fragments = <String>[]; |
1036 int length = 0; | 1036 int length = 0; |
1037 | 1037 |
1038 ConstantNamingVisitor(this.compiler, this.hasher); | 1038 ConstantNamingVisitor(this.compiler, this.hasher); |
1039 | 1039 |
1040 String getName(Constant constant) { | 1040 String getName(ConstantValue constant) { |
1041 _visit(constant); | 1041 _visit(constant); |
1042 if (root == null) return 'CONSTANT'; | 1042 if (root == null) return 'CONSTANT'; |
1043 if (failed) return '${root}_${getHashTag(constant, DEFAULT_TAG_LENGTH)}'; | 1043 if (failed) return '${root}_${getHashTag(constant, DEFAULT_TAG_LENGTH)}'; |
1044 if (fragments.length == 1) return 'C_${root}'; | 1044 if (fragments.length == 1) return 'C_${root}'; |
1045 return fragments.join('_'); | 1045 return fragments.join('_'); |
1046 } | 1046 } |
1047 | 1047 |
1048 String getHashTag(Constant constant, int width) => | 1048 String getHashTag(ConstantValue constant, int width) => |
1049 hashWord(hasher.getHash(constant), width); | 1049 hashWord(hasher.getHash(constant), width); |
1050 | 1050 |
1051 String hashWord(int hash, int length) { | 1051 String hashWord(int hash, int length) { |
1052 hash &= 0x1fffffff; | 1052 hash &= 0x1fffffff; |
1053 StringBuffer sb = new StringBuffer(); | 1053 StringBuffer sb = new StringBuffer(); |
1054 for (int i = 0; i < length; i++) { | 1054 for (int i = 0; i < length; i++) { |
1055 int digit = hash % 62; | 1055 int digit = hash % 62; |
1056 sb.write('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' | 1056 sb.write('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' |
1057 [digit]); | 1057 [digit]); |
1058 hash ~/= 62; | 1058 hash ~/= 62; |
(...skipping 20 matching lines...) Expand all Loading... | |
1079 } | 1079 } |
1080 | 1080 |
1081 void addIdentifier(String fragment) { | 1081 void addIdentifier(String fragment) { |
1082 if (fragment.length <= MAX_EXTRA_LENGTH && IDENTIFIER.hasMatch(fragment)) { | 1082 if (fragment.length <= MAX_EXTRA_LENGTH && IDENTIFIER.hasMatch(fragment)) { |
1083 add(fragment); | 1083 add(fragment); |
1084 } else { | 1084 } else { |
1085 failed = true; | 1085 failed = true; |
1086 } | 1086 } |
1087 } | 1087 } |
1088 | 1088 |
1089 _visit(Constant constant) { | 1089 _visit(ConstantValue constant) { |
1090 return constant.accept(this); | 1090 return constant.accept(this); |
1091 } | 1091 } |
1092 | 1092 |
1093 visitFunction(FunctionConstant constant) { | 1093 visitFunction(FunctionConstantValue constant) { |
1094 add(constant.element.name); | 1094 add(constant.element.name); |
1095 } | 1095 } |
1096 | 1096 |
1097 visitNull(NullConstant constant) { | 1097 visitNull(NullConstantValue constant) { |
1098 add('null'); | 1098 add('null'); |
1099 } | 1099 } |
1100 | 1100 |
1101 visitInt(IntConstant constant) { | 1101 visitInt(IntConstantValue constant) { |
1102 // No `addRoot` since IntConstants are always inlined. | 1102 // No `addRoot` since IntConstants are always inlined. |
1103 if (constant.value < 0) { | 1103 if (constant.primitiveValue < 0) { |
1104 add('m${-constant.value}'); | 1104 add('m${-constant.primitiveValue}'); |
1105 } else { | 1105 } else { |
1106 add('${constant.value}'); | 1106 add('${constant.primitiveValue}'); |
1107 } | 1107 } |
1108 } | 1108 } |
1109 | 1109 |
1110 visitDouble(DoubleConstant constant) { | 1110 visitDouble(DoubleConstantValue constant) { |
1111 failed = true; | 1111 failed = true; |
1112 } | 1112 } |
1113 | 1113 |
1114 visitTrue(TrueConstant constant) { | 1114 visitTrue(TrueConstantValue constant) { |
1115 add('true'); | 1115 add('true'); |
1116 } | 1116 } |
1117 | 1117 |
1118 visitFalse(FalseConstant constant) { | 1118 visitFalse(FalseConstantValue constant) { |
1119 add('false'); | 1119 add('false'); |
1120 } | 1120 } |
1121 | 1121 |
1122 visitString(StringConstant constant) { | 1122 visitString(StringConstantValue constant) { |
1123 // No `addRoot` since string constants are always inlined. | 1123 // No `addRoot` since string constants are always inlined. |
1124 addIdentifier(constant.value.slowToString()); | 1124 addIdentifier(constant.primitiveValue.slowToString()); |
1125 } | 1125 } |
1126 | 1126 |
1127 visitList(ListConstant constant) { | 1127 visitList(ListConstantValue constant) { |
1128 // TODO(9476): Incorporate type parameters into name. | 1128 // TODO(9476): Incorporate type parameters into name. |
1129 addRoot('List'); | 1129 addRoot('List'); |
1130 int length = constant.length; | 1130 int length = constant.length; |
1131 if (constant.length == 0) { | 1131 if (constant.length == 0) { |
1132 add('empty'); | 1132 add('empty'); |
1133 } else if (length >= MAX_FRAGMENTS) { | 1133 } else if (length >= MAX_FRAGMENTS) { |
1134 failed = true; | 1134 failed = true; |
1135 } else { | 1135 } else { |
1136 for (int i = 0; i < length; i++) { | 1136 for (int i = 0; i < length; i++) { |
1137 _visit(constant.entries[i]); | 1137 _visit(constant.entries[i]); |
1138 if (failed) break; | 1138 if (failed) break; |
1139 } | 1139 } |
1140 } | 1140 } |
1141 } | 1141 } |
1142 | 1142 |
1143 visitMap(JavaScriptMapConstant constant) { | 1143 visitMap(JavaScriptMapConstant constant) { |
1144 // TODO(9476): Incorporate type parameters into name. | 1144 // TODO(9476): Incorporate type parameters into name. |
1145 addRoot('Map'); | 1145 addRoot('Map'); |
1146 if (constant.length == 0) { | 1146 if (constant.length == 0) { |
1147 add('empty'); | 1147 add('empty'); |
1148 } else { | 1148 } else { |
1149 // Using some bits from the keys hash tag groups the names Maps with the | 1149 // Using some bits from the keys hash tag groups the names Maps with the |
1150 // same structure. | 1150 // same structure. |
1151 add(getHashTag(constant.keyList, 2) + getHashTag(constant, 3)); | 1151 add(getHashTag(constant.keyList, 2) + getHashTag(constant, 3)); |
1152 } | 1152 } |
1153 } | 1153 } |
1154 | 1154 |
1155 visitConstructed(ConstructedConstant constant) { | 1155 visitConstructed(ConstructedConstantValue constant) { |
1156 addRoot(constant.type.element.name); | 1156 addRoot(constant.type.element.name); |
1157 for (int i = 0; i < constant.fields.length; i++) { | 1157 for (int i = 0; i < constant.fields.length; i++) { |
1158 _visit(constant.fields[i]); | 1158 _visit(constant.fields[i]); |
1159 if (failed) return; | 1159 if (failed) return; |
1160 } | 1160 } |
1161 } | 1161 } |
1162 | 1162 |
1163 visitType(TypeConstant constant) { | 1163 visitType(TypeConstantValue constant) { |
1164 addRoot('Type'); | 1164 addRoot('Type'); |
1165 DartType type = constant.representedType; | 1165 DartType type = constant.representedType; |
1166 JavaScriptBackend backend = compiler.backend; | 1166 JavaScriptBackend backend = compiler.backend; |
1167 String name = backend.rti.getTypeRepresentationForTypeConstant(type); | 1167 String name = backend.rti.getTypeRepresentationForTypeConstant(type); |
1168 addIdentifier(name); | 1168 addIdentifier(name); |
1169 } | 1169 } |
1170 | 1170 |
1171 visitInterceptor(InterceptorConstant constant) { | 1171 visitInterceptor(InterceptorConstantValue constant) { |
1172 addRoot(constant.dispatchedType.element.name); | 1172 addRoot(constant.dispatchedType.element.name); |
1173 add('methods'); | 1173 add('methods'); |
1174 } | 1174 } |
1175 | 1175 |
1176 visitDummy(DummyConstant constant) { | 1176 visitDummy(DummyConstantValue constant) { |
1177 add('dummy_receiver'); | 1177 add('dummy_receiver'); |
1178 } | 1178 } |
1179 | 1179 |
1180 visitDeferred(DeferredConstant constant) { | 1180 visitDeferred(DeferredConstantValue constant) { |
1181 addRoot('Deferred'); | 1181 addRoot('Deferred'); |
1182 } | 1182 } |
1183 } | 1183 } |
1184 | 1184 |
1185 /** | 1185 /** |
1186 * Generates canonical hash values for [Constant]s. | 1186 * Generates canonical hash values for [ConstantValue]s. |
1187 * | 1187 * |
1188 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations, | 1188 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations, |
1189 * so it can't be used for generating names. This hasher keeps consistency | 1189 * so it can't be used for generating names. This hasher keeps consistency |
1190 * between runs by basing hash values of the names of elements, rather than | 1190 * between runs by basing hash values of the names of elements, rather than |
1191 * their hashCodes. | 1191 * their hashCodes. |
1192 */ | 1192 */ |
1193 class ConstantCanonicalHasher implements ConstantVisitor<int> { | 1193 class ConstantCanonicalHasher implements ConstantValueVisitor<int> { |
1194 | 1194 |
1195 static const _MASK = 0x1fffffff; | 1195 static const _MASK = 0x1fffffff; |
1196 static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024; | 1196 static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024; |
1197 | 1197 |
1198 | 1198 |
1199 final Compiler compiler; | 1199 final Compiler compiler; |
1200 final Map<Constant, int> hashes = new Map<Constant, int>(); | 1200 final Map<ConstantValue, int> hashes = new Map<ConstantValue, int>(); |
1201 | 1201 |
1202 ConstantCanonicalHasher(this.compiler); | 1202 ConstantCanonicalHasher(this.compiler); |
1203 | 1203 |
1204 int getHash(Constant constant) => _visit(constant); | 1204 int getHash(ConstantValue constant) => _visit(constant); |
1205 | 1205 |
1206 int _visit(Constant constant) { | 1206 int _visit(ConstantValue constant) { |
1207 int hash = hashes[constant]; | 1207 int hash = hashes[constant]; |
1208 if (hash == null) { | 1208 if (hash == null) { |
1209 hash = _finish(constant.accept(this)); | 1209 hash = _finish(constant.accept(this)); |
1210 hashes[constant] = hash; | 1210 hashes[constant] = hash; |
1211 } | 1211 } |
1212 return hash; | 1212 return hash; |
1213 } | 1213 } |
1214 | 1214 |
1215 int visitNull(NullConstant constant) => 1; | 1215 int visitNull(NullConstantValue constant) => 1; |
1216 int visitTrue(TrueConstant constant) => 2; | 1216 int visitTrue(TrueConstantValue constant) => 2; |
1217 int visitFalse(FalseConstant constant) => 3; | 1217 int visitFalse(FalseConstantValue constant) => 3; |
1218 | 1218 |
1219 int visitFunction(FunctionConstant constant) { | 1219 int visitFunction(FunctionConstantValue constant) { |
1220 return _hashString(1, constant.element.name); | 1220 return _hashString(1, constant.element.name); |
1221 } | 1221 } |
1222 | 1222 |
1223 int visitInt(IntConstant constant) => _hashInt(constant.value); | 1223 int visitInt(IntConstantValue constant) => _hashInt(constant.primitiveValue); |
1224 | 1224 |
1225 int visitDouble(DoubleConstant constant) => _hashDouble(constant.value); | 1225 int visitDouble(DoubleConstantValue constant) => _hashDouble(constant.primitiv eValue); |
sigurdm
2014/10/01 07:46:47
Long line
Johnni Winther
2014/10/01 08:21:23
Done.
| |
1226 | 1226 |
1227 int visitString(StringConstant constant) { | 1227 int visitString(StringConstantValue constant) { |
1228 return _hashString(2, constant.value.slowToString()); | 1228 return _hashString(2, constant.primitiveValue.slowToString()); |
1229 } | 1229 } |
1230 | 1230 |
1231 int visitList(ListConstant constant) { | 1231 int visitList(ListConstantValue constant) { |
1232 return _hashList(constant.length, constant.entries); | 1232 return _hashList(constant.length, constant.entries); |
1233 } | 1233 } |
1234 | 1234 |
1235 int visitMap(MapConstant constant) { | 1235 int visitMap(MapConstantValue constant) { |
1236 int hash = _hashList(constant.length, constant.keys); | 1236 int hash = _hashList(constant.length, constant.keys); |
1237 return _hashList(hash, constant.values); | 1237 return _hashList(hash, constant.values); |
1238 } | 1238 } |
1239 | 1239 |
1240 int visitConstructed(ConstructedConstant constant) { | 1240 int visitConstructed(ConstructedConstantValue constant) { |
1241 int hash = _hashString(3, constant.type.element.name); | 1241 int hash = _hashString(3, constant.type.element.name); |
1242 for (int i = 0; i < constant.fields.length; i++) { | 1242 for (int i = 0; i < constant.fields.length; i++) { |
1243 hash = _combine(hash, _visit(constant.fields[i])); | 1243 hash = _combine(hash, _visit(constant.fields[i])); |
1244 } | 1244 } |
1245 return hash; | 1245 return hash; |
1246 } | 1246 } |
1247 | 1247 |
1248 int visitType(TypeConstant constant) { | 1248 int visitType(TypeConstantValue constant) { |
1249 DartType type = constant.representedType; | 1249 DartType type = constant.representedType; |
1250 JavaScriptBackend backend = compiler.backend; | 1250 JavaScriptBackend backend = compiler.backend; |
1251 String name = backend.rti.getTypeRepresentationForTypeConstant(type); | 1251 String name = backend.rti.getTypeRepresentationForTypeConstant(type); |
1252 return _hashString(4, name); | 1252 return _hashString(4, name); |
1253 } | 1253 } |
1254 | 1254 |
1255 visitInterceptor(InterceptorConstant constant) { | 1255 visitInterceptor(InterceptorConstantValue constant) { |
1256 String typeName = constant.dispatchedType.element.name; | 1256 String typeName = constant.dispatchedType.element.name; |
1257 return _hashString(5, typeName); | 1257 return _hashString(5, typeName); |
1258 } | 1258 } |
1259 | 1259 |
1260 visitDummy(DummyConstant constant) { | 1260 visitDummy(DummyConstantValue constant) { |
1261 compiler.internalError(NO_LOCATION_SPANNABLE, | 1261 compiler.internalError(NO_LOCATION_SPANNABLE, |
1262 'DummyReceiverConstant should never be named and never be subconstant'); | 1262 'DummyReceiverConstant should never be named and never be subconstant'); |
1263 } | 1263 } |
1264 | 1264 |
1265 visitDeferred(DeferredConstant constant) { | 1265 visitDeferred(DeferredConstantValue constant) { |
1266 int hash = constant.prefix.hashCode; | 1266 int hash = constant.prefix.hashCode; |
1267 return _combine(hash, constant.referenced.accept(this)); | 1267 return _combine(hash, constant.referenced.accept(this)); |
1268 } | 1268 } |
1269 | 1269 |
1270 int _hashString(int hash, String s) { | 1270 int _hashString(int hash, String s) { |
1271 int length = s.length; | 1271 int length = s.length; |
1272 hash = _combine(hash, length); | 1272 hash = _combine(hash, length); |
1273 // Increasing stride is O(log N) on large strings which are unlikely to have | 1273 // Increasing stride is O(log N) on large strings which are unlikely to have |
1274 // many collisions. | 1274 // many collisions. |
1275 for (int i = 0; i < length; i += 1 + (i >> 2)) { | 1275 for (int i = 0; i < length; i += 1 + (i >> 2)) { |
1276 hash = _combine(hash, s.codeUnitAt(i)); | 1276 hash = _combine(hash, s.codeUnitAt(i)); |
1277 } | 1277 } |
1278 return hash; | 1278 return hash; |
1279 } | 1279 } |
1280 | 1280 |
1281 int _hashList(int hash, List<Constant> constants) { | 1281 int _hashList(int hash, List<ConstantValue> constants) { |
1282 for (Constant constant in constants) { | 1282 for (ConstantValue constant in constants) { |
1283 hash = _combine(hash, _visit(constant)); | 1283 hash = _combine(hash, _visit(constant)); |
1284 } | 1284 } |
1285 return hash; | 1285 return hash; |
1286 } | 1286 } |
1287 | 1287 |
1288 static int _hashInt(int value) { | 1288 static int _hashInt(int value) { |
1289 if (value.abs() < _UINT32_LIMIT) return _MASK & value; | 1289 if (value.abs() < _UINT32_LIMIT) return _MASK & value; |
1290 return _hashDouble(value.toDouble()); | 1290 return _hashDouble(value.toDouble()); |
1291 } | 1291 } |
1292 | 1292 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1385 if (!first) { | 1385 if (!first) { |
1386 sb.write('_'); | 1386 sb.write('_'); |
1387 } | 1387 } |
1388 sb.write('_'); | 1388 sb.write('_'); |
1389 visit(parameter); | 1389 visit(parameter); |
1390 first = true; | 1390 first = true; |
1391 } | 1391 } |
1392 } | 1392 } |
1393 } | 1393 } |
1394 } | 1394 } |
OLD | NEW |