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 |