OLD | NEW |
1 // (c) 2015, the Dart Team. All rights reserved. Use of this | 1 // (c) 2015, the Dart Team. All rights reserved. Use of this |
2 // source code is governed by a BSD-style license that can be found in | 2 // source code is governed by a BSD-style license that can be found in |
3 // the LICENSE file. | 3 // the LICENSE file. |
4 | 4 |
5 library reflectable.src.transformer_implementation; | 5 library reflectable.src.transformer_implementation; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:convert'; | 8 import 'dart:convert'; |
9 import 'dart:developer' as developer; | 9 import 'dart:developer' as developer; |
10 import 'dart:io'; | 10 import 'dart:io'; |
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 Iterable<String> membersList = () sync* { | 808 Iterable<String> membersList = () sync* { |
809 yield* topLevelVariablesList; | 809 yield* topLevelVariablesList; |
810 yield* fieldsList; | 810 yield* fieldsList; |
811 yield* methodsList; | 811 yield* methodsList; |
812 }(); | 812 }(); |
813 String membersCode = _formatAsList("m.DeclarationMirror", membersList); | 813 String membersCode = _formatAsList("m.DeclarationMirror", membersList); |
814 | 814 |
815 // Generate code for listing [Type] instances. | 815 // Generate code for listing [Type] instances. |
816 String typesCode = | 816 String typesCode = |
817 _formatAsConstList("Type", classes.map((ClassElement classElement) { | 817 _formatAsConstList("Type", classes.map((ClassElement classElement) { |
818 return _typeCodeOfClass(classElement, importCollector); | 818 return _dynamicTypeCodeOfClass(classElement, importCollector); |
819 })); | 819 })); |
820 | 820 |
821 // Generate code for creation of library mirrors. | 821 // Generate code for creation of library mirrors. |
822 String librariesCode; | 822 String librariesCode; |
823 if (!_capabilities._supportsLibraries) { | 823 if (!_capabilities._supportsLibraries) { |
824 librariesCode = "null"; | 824 librariesCode = "null"; |
825 } else { | 825 } else { |
826 librariesCode = _formatAsList("m.LibraryMirror", | 826 librariesCode = _formatAsList("m.LibraryMirror", |
827 libraries.items.map((_LibraryDomain library) { | 827 libraries.items.map((_LibraryDomain library) { |
828 return _libraryMirrorCode(library, libraries.indexOf(library), members, | 828 return _libraryMirrorCode(library, libraries.indexOf(library), members, |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 if (_capabilities._impliesDeclarations) { | 1132 if (_capabilities._impliesDeclarations) { |
1133 int indexOf(TypeParameterElement typeParameter) => | 1133 int indexOf(TypeParameterElement typeParameter) => |
1134 typeParameters.indexOf(typeParameter) + typeParametersOffset; | 1134 typeParameters.indexOf(typeParameter) + typeParametersOffset; |
1135 typeParameterIndices = _formatAsConstList( | 1135 typeParameterIndices = _formatAsConstList( |
1136 'int', | 1136 'int', |
1137 classElement.typeParameters | 1137 classElement.typeParameters |
1138 .where(typeParameters.items.contains) | 1138 .where(typeParameters.items.contains) |
1139 .map(indexOf)); | 1139 .map(indexOf)); |
1140 } | 1140 } |
1141 | 1141 |
| 1142 String dynamicReflectedTypeCode = |
| 1143 "${importCollector._getPrefix(classElement.library)}" |
| 1144 "${classElement.name}"; |
| 1145 |
1142 return 'new r.GenericClassMirrorImpl(r"${classDomain._simpleName}", ' | 1146 return 'new r.GenericClassMirrorImpl(r"${classDomain._simpleName}", ' |
1143 'r"${_qualifiedName(classElement)}", $descriptor, $classIndex, ' | 1147 'r"${_qualifiedName(classElement)}", $descriptor, $classIndex, ' |
1144 '${_constConstructionCode(importCollector)}, ' | 1148 '${_constConstructionCode(importCollector)}, ' |
1145 '$declarationsCode, $instanceMembersCode, $staticMembersCode, ' | 1149 '$declarationsCode, $instanceMembersCode, $staticMembersCode, ' |
1146 '$superclassIndex, $staticGettersCode, $staticSettersCode, ' | 1150 '$superclassIndex, $staticGettersCode, $staticSettersCode, ' |
1147 '$constructorsCode, $ownerIndex, $mixinIndex, ' | 1151 '$constructorsCode, $ownerIndex, $mixinIndex, ' |
1148 '$superinterfaceIndices, $classMetadataCode, $isCheckCode, ' | 1152 '$superinterfaceIndices, $classMetadataCode, $isCheckCode, ' |
1149 '$typeParameterIndices)'; | 1153 '$typeParameterIndices, $dynamicReflectedTypeCode)'; |
1150 } | 1154 } |
1151 } | 1155 } |
1152 | 1156 |
1153 String _methodMirrorCode( | 1157 String _methodMirrorCode( |
1154 ExecutableElement element, | 1158 ExecutableElement element, |
1155 Enumerator<TopLevelVariableElement> topLevelVariables, | 1159 Enumerator<TopLevelVariableElement> topLevelVariables, |
1156 Enumerator<FieldElement> fields, | 1160 Enumerator<FieldElement> fields, |
1157 Enumerator<ExecutableElement> members, | 1161 Enumerator<ExecutableElement> members, |
1158 Enumerator<ParameterElement> parameters, | 1162 Enumerator<ParameterElement> parameters, |
1159 _ImportCollector importCollector, | 1163 _ImportCollector importCollector, |
1160 TransformLogger logger, | 1164 TransformLogger logger, |
1161 bool reflectedTypeRequested) { | 1165 bool reflectedTypeRequested) { |
1162 if (element is PropertyAccessorElement && element.isSynthetic) { | 1166 if (element is PropertyAccessorElement && element.isSynthetic) { |
1163 // There is no type propagation, so we declare an `accessorElement`. | 1167 // There is no type propagation, so we declare an `accessorElement`. |
1164 PropertyAccessorElement accessorElement = element; | 1168 PropertyAccessorElement accessorElement = element; |
1165 PropertyInducingElement variable = accessorElement.variable; | 1169 PropertyInducingElement variable = accessorElement.variable; |
1166 int variableMirrorIndex = variable is TopLevelVariableElement | 1170 int variableMirrorIndex = variable is TopLevelVariableElement |
1167 ? topLevelVariables.indexOf(variable) | 1171 ? topLevelVariables.indexOf(variable) |
1168 : fields.indexOf(variable); | 1172 : fields.indexOf(variable); |
1169 String reflectedTypeCode = reflectedTypeRequested | 1173 String reflectedTypeCode = reflectedTypeRequested |
1170 ? _typeCode(accessorElement.variable.type, importCollector) | 1174 ? _typeCode(accessorElement.variable.type, importCollector) |
1171 : "null"; | 1175 : "null"; |
| 1176 String dynamicReflectedTypeCode = reflectedTypeRequested |
| 1177 ? _dynamicTypeCodeOrNull( |
| 1178 accessorElement.variable.type, importCollector) |
| 1179 : "null"; |
1172 // The `indexOf` is non-null: `accessorElement` came from `members`. | 1180 // The `indexOf` is non-null: `accessorElement` came from `members`. |
1173 int selfIndex = members.indexOf(accessorElement) + fields.length; | 1181 int selfIndex = members.indexOf(accessorElement) + fields.length; |
1174 if (accessorElement.isGetter) { | 1182 if (accessorElement.isGetter) { |
1175 return 'new r.ImplicitGetterMirrorImpl(' | 1183 return 'new r.ImplicitGetterMirrorImpl(' |
1176 '${_constConstructionCode(importCollector)}, ' | 1184 '${_constConstructionCode(importCollector)}, ' |
1177 '$variableMirrorIndex, $reflectedTypeCode, $selfIndex)'; | 1185 '$variableMirrorIndex, $reflectedTypeCode, ' |
| 1186 '$dynamicReflectedTypeCode, $selfIndex)'; |
1178 } else { | 1187 } else { |
1179 assert(accessorElement.isSetter); | 1188 assert(accessorElement.isSetter); |
1180 return 'new r.ImplicitSetterMirrorImpl(' | 1189 return 'new r.ImplicitSetterMirrorImpl(' |
1181 '${_constConstructionCode(importCollector)}, ' | 1190 '${_constConstructionCode(importCollector)}, ' |
1182 '$variableMirrorIndex, $reflectedTypeCode, $selfIndex)'; | 1191 '$variableMirrorIndex, $reflectedTypeCode, ' |
| 1192 '$dynamicReflectedTypeCode, $selfIndex)'; |
1183 } | 1193 } |
1184 } else { | 1194 } else { |
1185 // [element] is a method, a function, or an explicitly declared | 1195 // [element] is a method, a function, or an explicitly declared |
1186 // getter or setter. | 1196 // getter or setter. |
1187 int descriptor = _declarationDescriptor(element); | 1197 int descriptor = _declarationDescriptor(element); |
1188 int returnTypeIndex = _computeReturnTypeIndex(element, descriptor); | 1198 int returnTypeIndex = _computeReturnTypeIndex(element, descriptor); |
1189 int ownerIndex = _computeOwnerIndex(element, descriptor); | 1199 int ownerIndex = _computeOwnerIndex(element, descriptor); |
1190 String parameterIndicesCode = _formatAsConstList("int", | 1200 String parameterIndicesCode = _formatAsConstList("int", |
1191 element.parameters.map((ParameterElement parameterElement) { | 1201 element.parameters.map((ParameterElement parameterElement) { |
1192 return parameters.indexOf(parameterElement); | 1202 return parameters.indexOf(parameterElement); |
1193 })); | 1203 })); |
1194 String reflectedReturnTypeCode = element.returnType.isVoid | 1204 String reflectedReturnTypeCode = element.returnType.isVoid |
1195 ? "null" | 1205 ? "null" |
1196 : _typeCode(element.returnType, importCollector); | 1206 : _typeCode(element.returnType, importCollector); |
| 1207 String dynamicReflectedReturnTypeCode = element.returnType.isVoid |
| 1208 ? "null" |
| 1209 : _dynamicTypeCodeOrNull(element.returnType, importCollector); |
1197 String metadataCode = _capabilities._supportsMetadata | 1210 String metadataCode = _capabilities._supportsMetadata |
1198 ? _extractMetadataCode( | 1211 ? _extractMetadataCode( |
1199 element, _resolver, importCollector, logger, _generatedLibraryId) | 1212 element, _resolver, importCollector, logger, _generatedLibraryId) |
1200 : null; | 1213 : null; |
1201 return 'new r.MethodMirrorImpl(r"${element.name}", $descriptor, ' | 1214 return 'new r.MethodMirrorImpl(r"${element.name}", $descriptor, ' |
1202 '$ownerIndex, $returnTypeIndex, $reflectedReturnTypeCode, ' | 1215 '$ownerIndex, $returnTypeIndex, $reflectedReturnTypeCode, ' |
1203 '$parameterIndicesCode, ${_constConstructionCode(importCollector)}, ' | 1216 '$dynamicReflectedReturnTypeCode, $parameterIndicesCode, ' |
1204 '$metadataCode)'; | 1217 '${_constConstructionCode(importCollector)}, $metadataCode)'; |
1205 } | 1218 } |
1206 } | 1219 } |
1207 | 1220 |
1208 String _topLevelVariableMirrorCode( | 1221 String _topLevelVariableMirrorCode( |
1209 TopLevelVariableElement element, | 1222 TopLevelVariableElement element, |
1210 _ImportCollector importCollector, | 1223 _ImportCollector importCollector, |
1211 TransformLogger logger, | 1224 TransformLogger logger, |
1212 bool reflectedTypeRequested) { | 1225 bool reflectedTypeRequested) { |
1213 int descriptor = _topLevelVariableDescriptor(element); | 1226 int descriptor = _topLevelVariableDescriptor(element); |
1214 int ownerIndex = | 1227 int ownerIndex = |
1215 _libraries.indexOf(element.enclosingElement.enclosingElement); | 1228 _libraries.indexOf(element.enclosingElement.enclosingElement); |
1216 int classMirrorIndex = _computeVariableTypeIndex(element, descriptor); | 1229 int classMirrorIndex = _computeVariableTypeIndex(element, descriptor); |
1217 String reflectedTypeCode = reflectedTypeRequested | 1230 String reflectedTypeCode = reflectedTypeRequested |
1218 ? _typeCode(element.type, importCollector) | 1231 ? _typeCode(element.type, importCollector) |
1219 : "null"; | 1232 : "null"; |
| 1233 String dynamicReflectedTypeCode = reflectedTypeRequested |
| 1234 ? _dynamicTypeCodeOrNull(element.type, importCollector) |
| 1235 : "null"; |
1220 String metadataCode; | 1236 String metadataCode; |
1221 if (_capabilities._supportsMetadata) { | 1237 if (_capabilities._supportsMetadata) { |
1222 metadataCode = _extractMetadataCode( | 1238 metadataCode = _extractMetadataCode( |
1223 element, _resolver, importCollector, logger, _generatedLibraryId); | 1239 element, _resolver, importCollector, logger, _generatedLibraryId); |
1224 } else { | 1240 } else { |
1225 // We encode 'without capability' as `null` for metadata, because | 1241 // We encode 'without capability' as `null` for metadata, because |
1226 // it is a `List<Object>`, which has no other natural encoding. | 1242 // it is a `List<Object>`, which has no other natural encoding. |
1227 metadataCode = null; | 1243 metadataCode = null; |
1228 } | 1244 } |
1229 return 'new r.VariableMirrorImpl(r"${element.name}", $descriptor, ' | 1245 return 'new r.VariableMirrorImpl(r"${element.name}", $descriptor, ' |
1230 '$ownerIndex, ${_constConstructionCode(importCollector)}, ' | 1246 '$ownerIndex, ${_constConstructionCode(importCollector)}, ' |
1231 '$classMirrorIndex, $reflectedTypeCode, $metadataCode)'; | 1247 '$classMirrorIndex, $reflectedTypeCode, ' |
| 1248 '$dynamicReflectedTypeCode, $metadataCode)'; |
1232 } | 1249 } |
1233 | 1250 |
1234 String _fieldMirrorCode( | 1251 String _fieldMirrorCode( |
1235 FieldElement element, | 1252 FieldElement element, |
1236 _ImportCollector importCollector, | 1253 _ImportCollector importCollector, |
1237 TransformLogger logger, | 1254 TransformLogger logger, |
1238 bool reflectedTypeRequested) { | 1255 bool reflectedTypeRequested) { |
1239 int descriptor = _fieldDescriptor(element); | 1256 int descriptor = _fieldDescriptor(element); |
1240 int ownerIndex = classes.indexOf(element.enclosingElement); | 1257 int ownerIndex = classes.indexOf(element.enclosingElement); |
1241 int classMirrorIndex = _computeVariableTypeIndex(element, descriptor); | 1258 int classMirrorIndex = _computeVariableTypeIndex(element, descriptor); |
1242 String reflectedTypeCode = reflectedTypeRequested | 1259 String reflectedTypeCode = reflectedTypeRequested |
1243 ? _typeCode(element.type, importCollector) | 1260 ? _typeCode(element.type, importCollector) |
1244 : "null"; | 1261 : "null"; |
| 1262 String dynamicReflectedTypeCode = reflectedTypeRequested |
| 1263 ? _dynamicTypeCodeOrNull(element.type, importCollector) |
| 1264 : "null"; |
1245 String metadataCode; | 1265 String metadataCode; |
1246 if (_capabilities._supportsMetadata) { | 1266 if (_capabilities._supportsMetadata) { |
1247 metadataCode = _extractMetadataCode( | 1267 metadataCode = _extractMetadataCode( |
1248 element, _resolver, importCollector, logger, _generatedLibraryId); | 1268 element, _resolver, importCollector, logger, _generatedLibraryId); |
1249 } else { | 1269 } else { |
1250 // We encode 'without capability' as `null` for metadata, because | 1270 // We encode 'without capability' as `null` for metadata, because |
1251 // it is a `List<Object>`, which has no other natural encoding. | 1271 // it is a `List<Object>`, which has no other natural encoding. |
1252 metadataCode = null; | 1272 metadataCode = null; |
1253 } | 1273 } |
1254 return 'new r.VariableMirrorImpl(r"${element.name}", $descriptor, ' | 1274 return 'new r.VariableMirrorImpl(r"${element.name}", $descriptor, ' |
1255 '$ownerIndex, ${_constConstructionCode(importCollector)}, ' | 1275 '$ownerIndex, ${_constConstructionCode(importCollector)}, ' |
1256 '$classMirrorIndex, $reflectedTypeCode, $metadataCode)'; | 1276 '$classMirrorIndex, $reflectedTypeCode, ' |
| 1277 '$dynamicReflectedTypeCode, $metadataCode)'; |
1257 } | 1278 } |
1258 | 1279 |
1259 String _typeCode(DartType dartType, _ImportCollector importCollector) { | 1280 String _typeCode(DartType dartType, _ImportCollector importCollector) { |
1260 if (dartType is TypeParameterType) { | 1281 if (dartType is TypeParameterType) { |
1261 ClassElement owningClassElement = dartType.element.enclosingElement; | 1282 ClassElement owningClassElement = dartType.element.enclosingElement; |
1262 return 'const r.FakeType(r"${_qualifiedName(owningClassElement)}.' | 1283 return 'const r.FakeType(r"${_qualifiedName(owningClassElement)}.' |
1263 '${dartType.element}")'; | 1284 '${dartType.element}")'; |
1264 } | 1285 } |
1265 return _typeCodeOfClass(dartType.element, importCollector); | 1286 return _typeCodeOfClass(dartType, importCollector); |
1266 } | 1287 } |
1267 | 1288 |
1268 String _typeCodeOfClass(TypeDefiningElement typeDefiningElement, | 1289 /// Returns a string containing code that in the generated library will |
| 1290 /// evaluate to a [Type] value like the value we would have obtained by |
| 1291 /// evaluating the [typeDefiningElement] as an expression in the library |
| 1292 /// where it occurs, but with all type arguments erased to `dynamic`. |
| 1293 /// Furthermore, return "null" for non-generic classes (that is used to |
| 1294 /// avoid duplication of identical expressions). [importCollector] is used |
| 1295 /// to find the library prefixes needed in order to obtain values from other |
| 1296 /// libraries. |
| 1297 String _dynamicTypeCodeOrNull( |
| 1298 DartType dartType, _ImportCollector importCollector) { |
| 1299 if (dartType is InterfaceType) { |
| 1300 return dartType.typeArguments.isEmpty |
| 1301 ? "null" |
| 1302 : _dynamicTypeCodeOfClass(dartType.element, importCollector); |
| 1303 } |
| 1304 // Not an interface type, let `_dynamicTypeCodeOfClass` handle it. |
| 1305 return _dynamicTypeCodeOfClass(dartType.element, importCollector); |
| 1306 } |
| 1307 |
| 1308 /// Returns true iff the given [type] is not and does not contain a type |
| 1309 /// variable. |
| 1310 bool _isTypeVariableFree(DartType type) { |
| 1311 if (type is TypeParameterType) return false; |
| 1312 if (type is InterfaceType) { |
| 1313 if (type.typeArguments.isEmpty) return true; |
| 1314 return type.typeArguments.every(_isTypeVariableFree); |
| 1315 } |
| 1316 // Possible kinds of types at this point (apart from several types |
| 1317 // indicating an error that we do not expect here): `BottomTypeImpl`, |
| 1318 // `DynamicTypeImpl`, `FunctionTypeImpl`, `VoidTypeImpl`. None of these |
| 1319 // have type variables. |
| 1320 return true; |
| 1321 } |
| 1322 |
| 1323 /// Returns a string containing a type expression that in the generated |
| 1324 /// library will serve as a type argument with the same meaning as the |
| 1325 /// [classElement] has where it occurs. The [importCollector] is used to |
| 1326 /// find the library prefixes needed in order to obtain values from other |
| 1327 /// libraries. |
| 1328 String _typeCodeOfTypeArgument( |
| 1329 DartType dartType, _ImportCollector importCollector) { |
| 1330 fail() { |
| 1331 return unimplementedError( |
| 1332 "Attempt to generate code for an unsupported kind of type $dartType"); |
| 1333 } |
| 1334 |
| 1335 if (dartType.isDynamic) return "dynamic"; |
| 1336 if (dartType is InterfaceType) { |
| 1337 ClassElement classElement = dartType.element; |
| 1338 if ((classElement is MixinApplication && |
| 1339 classElement.declaredName == null) || |
| 1340 classElement.isPrivate) { |
| 1341 throw fail(); |
| 1342 } |
| 1343 String prefix = importCollector._getPrefix(classElement.library); |
| 1344 if (classElement.typeParameters.isEmpty) { |
| 1345 return "$prefix${classElement.name}"; |
| 1346 } else { |
| 1347 if (dartType.typeArguments.every(_isTypeVariableFree)) { |
| 1348 String arguments = dartType.typeArguments |
| 1349 .map((DartType typeArgument) => |
| 1350 _typeCodeOfTypeArgument(typeArgument, importCollector)) |
| 1351 .join(', '); |
| 1352 return "$prefix${classElement.name}<$arguments>"; |
| 1353 } else { |
| 1354 throw fail(); |
| 1355 } |
| 1356 } |
| 1357 } else { |
| 1358 throw fail(); |
| 1359 } |
| 1360 } |
| 1361 |
| 1362 /// Returns a string containing code that in the generated library will |
| 1363 /// evaluate to a [Type] value like the value we would have obtained by |
| 1364 /// evaluating the [typeDefiningElement] as an expression in the library |
| 1365 /// where it occurs. [importCollector] is used to find the library prefixes |
| 1366 /// needed in order to obtain values from other libraries. |
| 1367 String _typeCodeOfClass(DartType dartType, _ImportCollector importCollector) { |
| 1368 if (dartType.isDynamic) return "dynamic"; |
| 1369 if (dartType is InterfaceType) { |
| 1370 ClassElement classElement = dartType.element; |
| 1371 if ((classElement is MixinApplication && |
| 1372 classElement.declaredName == null) || |
| 1373 classElement.isPrivate) { |
| 1374 return 'const r.FakeType(r"${_qualifiedName(classElement)}")'; |
| 1375 } |
| 1376 String prefix = importCollector._getPrefix(classElement.library); |
| 1377 if (classElement.typeParameters.isEmpty) { |
| 1378 return "$prefix${classElement.name}"; |
| 1379 } else { |
| 1380 if (dartType.typeArguments.every(_isTypeVariableFree)) { |
| 1381 return "const m.TypeValue" |
| 1382 "<${_typeCodeOfTypeArgument(dartType, importCollector)}>().type"; |
| 1383 } else { |
| 1384 String arguments = dartType.typeArguments |
| 1385 .map((DartType typeArgument) => typeArgument.toString()) |
| 1386 .join(', '); |
| 1387 return 'const r.FakeType(' |
| 1388 'r"${_qualifiedName(classElement)}<$arguments>")'; |
| 1389 } |
| 1390 } |
| 1391 } else { |
| 1392 throw unimplementedError( |
| 1393 "Attempt to generate code for an unsupported kind of type $dartType"); |
| 1394 } |
| 1395 } |
| 1396 |
| 1397 /// Returns a string containing code that in the generated library will |
| 1398 /// evaluate to a [Type] value like the value we would have obtained by |
| 1399 /// evaluating the [typeDefiningElement] as an expression in the library |
| 1400 /// where it occurs, except that all type arguments are stripped such |
| 1401 /// that we get the fully dynamic instantiation if it is a generic class. |
| 1402 /// [importCollector] is used to find the library prefixes needed in order |
| 1403 /// to obtain values from other libraries. |
| 1404 String _dynamicTypeCodeOfClass(TypeDefiningElement typeDefiningElement, |
1269 _ImportCollector importCollector) { | 1405 _ImportCollector importCollector) { |
1270 if ((typeDefiningElement is MixinApplication && | 1406 DartType type = typeDefiningElement.type; |
1271 typeDefiningElement.declaredName == null) || | 1407 if (type.isDynamic) return "dynamic"; |
1272 typeDefiningElement.isPrivate) { | 1408 if (type is InterfaceType) { |
| 1409 ClassElement classElement = type.element; |
| 1410 if ((classElement is MixinApplication && |
| 1411 classElement.declaredName == null) || |
| 1412 classElement.isPrivate) { |
| 1413 return 'const r.FakeType(r"${_qualifiedName(classElement)}")'; |
| 1414 } |
| 1415 String prefix = importCollector._getPrefix(classElement.library); |
| 1416 return "$prefix${classElement.name}"; |
| 1417 } else { |
1273 return 'const r.FakeType(r"${_qualifiedName(typeDefiningElement)}")'; | 1418 return 'const r.FakeType(r"${_qualifiedName(typeDefiningElement)}")'; |
1274 } | 1419 } |
1275 if (typeDefiningElement.type.isDynamic) return "dynamic"; | |
1276 String prefix = importCollector._getPrefix(typeDefiningElement.library); | |
1277 return "$prefix${typeDefiningElement.name}"; | |
1278 } | 1420 } |
1279 | 1421 |
1280 String _libraryMirrorCode( | 1422 String _libraryMirrorCode( |
1281 _LibraryDomain libraryDomain, | 1423 _LibraryDomain libraryDomain, |
1282 int libraryIndex, | 1424 int libraryIndex, |
1283 Enumerator<ExecutableElement> members, | 1425 Enumerator<ExecutableElement> members, |
1284 Enumerator<TopLevelVariableElement> variables, | 1426 Enumerator<TopLevelVariableElement> variables, |
1285 int methodsOffset, | 1427 int methodsOffset, |
1286 _ImportCollector importCollector, | 1428 _ImportCollector importCollector, |
1287 TransformLogger logger) { | 1429 TransformLogger logger) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1366 classMirrorIndex = classes.contains(element.type.element) | 1508 classMirrorIndex = classes.contains(element.type.element) |
1367 ? classes.indexOf(element.type.element) | 1509 ? classes.indexOf(element.type.element) |
1368 : constants.NO_CAPABILITY_INDEX; | 1510 : constants.NO_CAPABILITY_INDEX; |
1369 } | 1511 } |
1370 } else { | 1512 } else { |
1371 classMirrorIndex = constants.NO_CAPABILITY_INDEX; | 1513 classMirrorIndex = constants.NO_CAPABILITY_INDEX; |
1372 } | 1514 } |
1373 String reflectedTypeCode = reflectedTypeRequested | 1515 String reflectedTypeCode = reflectedTypeRequested |
1374 ? _typeCode(element.type, importCollector) | 1516 ? _typeCode(element.type, importCollector) |
1375 : "null"; | 1517 : "null"; |
| 1518 String dynamicReflectedTypeCode = reflectedTypeRequested |
| 1519 ? _dynamicTypeCodeOrNull(element.type, importCollector) |
| 1520 : "null"; |
1376 String metadataCode = "null"; | 1521 String metadataCode = "null"; |
1377 if (_capabilities._supportsMetadata) { | 1522 if (_capabilities._supportsMetadata) { |
1378 FormalParameter node = element.computeNode(); | 1523 FormalParameter node = element.computeNode(); |
1379 if (node == null) { | 1524 if (node == null) { |
1380 metadataCode = "const []"; | 1525 metadataCode = "const []"; |
1381 } else { | 1526 } else { |
1382 metadataCode = _extractMetadataCode( | 1527 metadataCode = _extractMetadataCode( |
1383 element, _resolver, importCollector, logger, _generatedLibraryId); | 1528 element, _resolver, importCollector, logger, _generatedLibraryId); |
1384 } | 1529 } |
1385 } | 1530 } |
1386 FormalParameter parameterNode = element.computeNode(); | 1531 FormalParameter parameterNode = element.computeNode(); |
1387 String defaultValueCode = "null"; | 1532 String defaultValueCode = "null"; |
1388 if (parameterNode is DefaultFormalParameter && | 1533 if (parameterNode is DefaultFormalParameter && |
1389 parameterNode.defaultValue != null) { | 1534 parameterNode.defaultValue != null) { |
1390 defaultValueCode = _extractConstantCode( | 1535 defaultValueCode = _extractConstantCode( |
1391 parameterNode.defaultValue, | 1536 parameterNode.defaultValue, |
1392 element.library, | 1537 element.library, |
1393 importCollector, | 1538 importCollector, |
1394 logger, | 1539 logger, |
1395 _generatedLibraryId, | 1540 _generatedLibraryId, |
1396 _resolver); | 1541 _resolver); |
1397 } | 1542 } |
1398 return 'new r.ParameterMirrorImpl(r"${element.name}", $descriptor, ' | 1543 return 'new r.ParameterMirrorImpl(r"${element.name}", $descriptor, ' |
1399 '$ownerIndex, ${_constConstructionCode(importCollector)}, ' | 1544 '$ownerIndex, ${_constConstructionCode(importCollector)}, ' |
1400 '$classMirrorIndex, $reflectedTypeCode, $metadataCode, ' | 1545 '$classMirrorIndex, $reflectedTypeCode, $dynamicReflectedTypeCode, ' |
1401 '$defaultValueCode)'; | 1546 '$metadataCode, $defaultValueCode)'; |
1402 } | 1547 } |
1403 } | 1548 } |
1404 | 1549 |
1405 /// Auxiliary class used by `classes`. Its `expand` method expands | 1550 /// Auxiliary class used by `classes`. Its `expand` method expands |
1406 /// its argument to a fixed point, based on the `successors` method. | 1551 /// its argument to a fixed point, based on the `successors` method. |
1407 class _SubtypesFixedPoint extends FixedPoint<ClassElement> { | 1552 class _SubtypesFixedPoint extends FixedPoint<ClassElement> { |
1408 final Map<ClassElement, Set<ClassElement>> subtypes; | 1553 final Map<ClassElement, Set<ClassElement>> subtypes; |
1409 | 1554 |
1410 _SubtypesFixedPoint(this.subtypes); | 1555 _SubtypesFixedPoint(this.subtypes); |
1411 | 1556 |
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2215 capability is ec.LibraryCapability); | 2360 capability is ec.LibraryCapability); |
2216 } | 2361 } |
2217 } | 2362 } |
2218 | 2363 |
2219 /// Collects the libraries that needs to be imported, and gives each library | 2364 /// Collects the libraries that needs to be imported, and gives each library |
2220 /// a unique prefix. | 2365 /// a unique prefix. |
2221 class _ImportCollector { | 2366 class _ImportCollector { |
2222 Map<LibraryElement, String> _mapping = <LibraryElement, String>{}; | 2367 Map<LibraryElement, String> _mapping = <LibraryElement, String>{}; |
2223 int _count = 0; | 2368 int _count = 0; |
2224 | 2369 |
2225 /// Returns the prefix associated with [library]. | 2370 /// Returns the prefix associated with [library]. Iff it is non-empty |
| 2371 /// it includes the period. |
2226 String _getPrefix(LibraryElement library) { | 2372 String _getPrefix(LibraryElement library) { |
2227 if (library.isDartCore) return ""; | 2373 if (library.isDartCore) return ""; |
2228 String prefix = _mapping[library]; | 2374 String prefix = _mapping[library]; |
2229 if (prefix != null) return prefix; | 2375 if (prefix != null) return prefix; |
2230 prefix = "prefix$_count."; | 2376 prefix = "prefix$_count."; |
2231 _count++; | 2377 _count++; |
2232 _mapping[library] = prefix; | 2378 _mapping[library] = prefix; |
2233 return prefix; | 2379 return prefix; |
2234 } | 2380 } |
2235 | 2381 |
(...skipping 1874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4110 return functionElement == null | 4256 return functionElement == null |
4111 ? "null" | 4257 ? "null" |
4112 : "${functionElement.library.name}.${functionElement.name}"; | 4258 : "${functionElement.library.name}.${functionElement.name}"; |
4113 } | 4259 } |
4114 | 4260 |
4115 String _qualifiedTypeParameterName(TypeParameterElement typeParameterElement) { | 4261 String _qualifiedTypeParameterName(TypeParameterElement typeParameterElement) { |
4116 if (typeParameterElement == null) return "null"; | 4262 if (typeParameterElement == null) return "null"; |
4117 return "${_qualifiedName(typeParameterElement.enclosingElement)}." | 4263 return "${_qualifiedName(typeParameterElement.enclosingElement)}." |
4118 "${typeParameterElement.name}"; | 4264 "${typeParameterElement.name}"; |
4119 } | 4265 } |
OLD | NEW |