| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
| 9 * from the given element. | 9 * from the given element. |
| 10 */ | 10 */ |
| (...skipping 1202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1213 element.getLibrary(), | 1213 element.getLibrary(), |
| 1214 signature.requiredParameterCount + i, | 1214 signature.requiredParameterCount + i, |
| 1215 <SourceString>[])); | 1215 <SourceString>[])); |
| 1216 } | 1216 } |
| 1217 return selectors; | 1217 return selectors; |
| 1218 } | 1218 } |
| 1219 | 1219 |
| 1220 bool fieldNeedsGetter(VariableElement field) { | 1220 bool fieldNeedsGetter(VariableElement field) { |
| 1221 assert(field.isField()); | 1221 assert(field.isField()); |
| 1222 if (fieldAccessNeverThrows(field)) return false; | 1222 if (fieldAccessNeverThrows(field)) return false; |
| 1223 return backend.retainGetter(field) | 1223 return backend.shouldRetainGetter(field) |
| 1224 || compiler.codegenWorld.hasInvokedGetter(field, compiler); | 1224 || compiler.codegenWorld.hasInvokedGetter(field, compiler); |
| 1225 } | 1225 } |
| 1226 | 1226 |
| 1227 bool fieldNeedsSetter(VariableElement field) { | 1227 bool fieldNeedsSetter(VariableElement field) { |
| 1228 assert(field.isField()); | 1228 assert(field.isField()); |
| 1229 if (fieldAccessNeverThrows(field)) return false; | 1229 if (fieldAccessNeverThrows(field)) return false; |
| 1230 return (!field.modifiers.isFinalOrConst()) | 1230 return (!field.modifiers.isFinalOrConst()) |
| 1231 && (backend.retainSetter(field) | 1231 && (backend.shouldRetainSetter(field) |
| 1232 || compiler.codegenWorld.hasInvokedSetter(field, compiler)); | 1232 || compiler.codegenWorld.hasInvokedSetter(field, compiler)); |
| 1233 } | 1233 } |
| 1234 | 1234 |
| 1235 // We never access a field in a closure (a captured variable) without knowing | 1235 // We never access a field in a closure (a captured variable) without knowing |
| 1236 // that it is there. Therefore we don't need to use a getter (that will throw | 1236 // that it is there. Therefore we don't need to use a getter (that will throw |
| 1237 // if the getter method is missing), but can always access the field directly. | 1237 // if the getter method is missing), but can always access the field directly. |
| 1238 static bool fieldAccessNeverThrows(VariableElement field) { | 1238 static bool fieldAccessNeverThrows(VariableElement field) { |
| 1239 return field is ClosureFieldElement; | 1239 return field is ClosureFieldElement; |
| 1240 } | 1240 } |
| 1241 | 1241 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1281 if (!parameters.optionalParameters.isEmpty) { | 1281 if (!parameters.optionalParameters.isEmpty) { |
| 1282 addParameterStubs(member, builder.addProperty); | 1282 addParameterStubs(member, builder.addProperty); |
| 1283 } | 1283 } |
| 1284 } else if (!member.isField()) { | 1284 } else if (!member.isField()) { |
| 1285 compiler.internalError('unexpected kind: "${member.kind}"', | 1285 compiler.internalError('unexpected kind: "${member.kind}"', |
| 1286 element: member); | 1286 element: member); |
| 1287 } | 1287 } |
| 1288 emitExtraAccessors(member, builder); | 1288 emitExtraAccessors(member, builder); |
| 1289 } | 1289 } |
| 1290 | 1290 |
| 1291 /// Returns the "reflection name" of an [Element] or [Selector]. |
| 1292 /// The reflection name of a getter 'foo' is 'foo'. |
| 1293 /// The reflection name of a setter 'foo' is 'foo='. |
| 1294 /// The reflection name of a method 'foo' is 'foo:N:M:O', where N is the |
| 1295 /// number of required arguments, M is the number of optional arguments, and |
| 1296 /// O is the named arguments. |
| 1297 /// The reflection name of a constructor is similar to a regular method but |
| 1298 /// starts with 'new '. |
| 1299 /// This is used by js_mirrors.dart. |
| 1291 String getReflectionName(elementOrSelector, String mangledName) { | 1300 String getReflectionName(elementOrSelector, String mangledName) { |
| 1292 if (!backend.retainName(elementOrSelector.name)) return null; | 1301 SourceString name = elementOrSelector.name; |
| 1302 if (!backend.shouldRetainName(name)) { |
| 1303 if (name == const SourceString('') && elementOrSelector is Element) { |
| 1304 // Make sure to retain names of unnamed constructors. |
| 1305 if (!backend.isNeededForReflection(elementOrSelector)) return null; |
| 1306 } else { |
| 1307 return null; |
| 1308 } |
| 1309 } |
| 1293 // TODO(ahe): Enable the next line when I can tell the difference between | 1310 // TODO(ahe): Enable the next line when I can tell the difference between |
| 1294 // an instance method and a global. They may have the same mangled name. | 1311 // an instance method and a global. They may have the same mangled name. |
| 1295 // if (recordedMangledNames.contains(mangledName)) return null; | 1312 // if (recordedMangledNames.contains(mangledName)) return null; |
| 1296 recordedMangledNames.add(mangledName); | 1313 recordedMangledNames.add(mangledName); |
| 1297 return getReflectionNameInternal(elementOrSelector, mangledName); | 1314 return getReflectionNameInternal(elementOrSelector, mangledName); |
| 1298 } | 1315 } |
| 1299 | 1316 |
| 1300 String getReflectionNameInternal(elementOrSelector, String mangledName) { | 1317 String getReflectionNameInternal(elementOrSelector, String mangledName) { |
| 1301 String name = elementOrSelector.name.slowToString(); | 1318 String name = elementOrSelector.name.slowToString(); |
| 1302 if (elementOrSelector.isGetter()) return name; | 1319 if (elementOrSelector.isGetter()) return name; |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1694 /* Do nothing. */ | 1711 /* Do nothing. */ |
| 1695 } | 1712 } |
| 1696 | 1713 |
| 1697 void emitRuntimeName(String runtimeName, ClassBuilder builder) { | 1714 void emitRuntimeName(String runtimeName, ClassBuilder builder) { |
| 1698 /* Do nothing. */ | 1715 /* Do nothing. */ |
| 1699 } | 1716 } |
| 1700 | 1717 |
| 1701 void recordMangledField(Element member, | 1718 void recordMangledField(Element member, |
| 1702 String accessorName, | 1719 String accessorName, |
| 1703 String memberName) { | 1720 String memberName) { |
| 1704 if (!backend.retainGetter(member)) return; | 1721 if (!backend.shouldRetainGetter(member)) return; |
| 1705 String previousName; | 1722 String previousName; |
| 1706 if (member.isInstanceMember()) { | 1723 if (member.isInstanceMember()) { |
| 1707 previousName = mangledFieldNames.putIfAbsent( | 1724 previousName = mangledFieldNames.putIfAbsent( |
| 1708 '${namer.getterPrefix}$accessorName', | 1725 '${namer.getterPrefix}$accessorName', |
| 1709 () => memberName); | 1726 () => memberName); |
| 1710 } else { | 1727 } else { |
| 1711 previousName = mangledGlobalFieldNames.putIfAbsent( | 1728 previousName = mangledGlobalFieldNames.putIfAbsent( |
| 1712 accessorName, | 1729 accessorName, |
| 1713 () => memberName); | 1730 () => memberName); |
| 1714 } | 1731 } |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1952 if (hasStatics) { | 1969 if (hasStatics) { |
| 1953 builder.addProperty('static', new jsAst.Blob(statics)); | 1970 builder.addProperty('static', new jsAst.Blob(statics)); |
| 1954 } | 1971 } |
| 1955 | 1972 |
| 1956 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. | 1973 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. |
| 1957 if (!buffer.isEmpty) { | 1974 if (!buffer.isEmpty) { |
| 1958 buffer.write(',$n$n'); | 1975 buffer.write(',$n$n'); |
| 1959 } | 1976 } |
| 1960 buffer.write('$className:$_'); | 1977 buffer.write('$className:$_'); |
| 1961 buffer.write(jsAst.prettyPrint(builder.toObjectInitializer(), compiler)); | 1978 buffer.write(jsAst.prettyPrint(builder.toObjectInitializer(), compiler)); |
| 1962 if (backend.retainName(classElement.name)) { | 1979 if (backend.shouldRetainName(classElement.name)) { |
| 1963 buffer.write(',$n$n"+${classElement.name.slowToString()}": 0'); | 1980 buffer.write(',$n$n"+${classElement.name.slowToString()}": 0'); |
| 1981 recordedMangledNames.add(className); |
| 1964 } | 1982 } |
| 1965 } | 1983 } |
| 1966 | 1984 |
| 1967 bool get getterAndSetterCanBeImplementedByFieldSpec => true; | 1985 bool get getterAndSetterCanBeImplementedByFieldSpec => true; |
| 1968 | 1986 |
| 1969 /// If this is true then we can generate the noSuchMethod handlers at startup | 1987 /// If this is true then we can generate the noSuchMethod handlers at startup |
| 1970 /// time, instead of them being emitted as part of the Object class. | 1988 /// time, instead of them being emitted as part of the Object class. |
| 1971 bool get generateTrivialNsmHandlers => true; | 1989 bool get generateTrivialNsmHandlers => true; |
| 1972 | 1990 |
| 1973 int _selectorRank(Selector selector) { | 1991 int _selectorRank(Selector selector) { |
| (...skipping 2069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4043 | 4061 |
| 4044 const String HOOKS_API_USAGE = """ | 4062 const String HOOKS_API_USAGE = """ |
| 4045 // The code supports the following hooks: | 4063 // The code supports the following hooks: |
| 4046 // dartPrint(message) - if this function is defined it is called | 4064 // dartPrint(message) - if this function is defined it is called |
| 4047 // instead of the Dart [print] method. | 4065 // instead of the Dart [print] method. |
| 4048 // dartMainRunner(main) - if this function is defined, the Dart [main] | 4066 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 4049 // method will not be invoked directly. | 4067 // method will not be invoked directly. |
| 4050 // Instead, a closure that will invoke [main] is | 4068 // Instead, a closure that will invoke [main] is |
| 4051 // passed to [dartMainRunner]. | 4069 // passed to [dartMainRunner]. |
| 4052 """; | 4070 """; |
| OLD | NEW |