| 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 summary_resynthesizer; | 5 library summary_resynthesizer; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; | 10 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; |
| (...skipping 1271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 DartType _buildType(bool instantiateToBoundsAllowed, int numTypeArguments, | 1282 DartType _buildType(bool instantiateToBoundsAllowed, int numTypeArguments, |
| 1283 DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) { | 1283 DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) { |
| 1284 ElementHandle element = this.element; // To allow type promotion | 1284 ElementHandle element = this.element; // To allow type promotion |
| 1285 if (element is ClassElementHandle) { | 1285 if (element is ClassElementHandle) { |
| 1286 List<DartType> typeArguments = null; | 1286 List<DartType> typeArguments = null; |
| 1287 // If type arguments are specified, use them. | 1287 // If type arguments are specified, use them. |
| 1288 // Otherwise, delay until they are requested. | 1288 // Otherwise, delay until they are requested. |
| 1289 if (numTypeParameters == 0) { | 1289 if (numTypeParameters == 0) { |
| 1290 return element.type; | 1290 return element.type; |
| 1291 } else if (numTypeArguments == numTypeParameters) { | 1291 } else if (numTypeArguments == numTypeParameters) { |
| 1292 typeArguments = new List<DartType>(numTypeParameters); | 1292 typeArguments = _buildTypeArguments(numTypeArguments, getTypeArgument); |
| 1293 for (int i = 0; i < numTypeParameters; i++) { | |
| 1294 typeArguments[i] = getTypeArgument(i); | |
| 1295 } | |
| 1296 } | 1293 } |
| 1297 InterfaceTypeImpl type = | 1294 InterfaceTypeImpl type = |
| 1298 new InterfaceTypeImpl.elementWithNameAndArgs(element, name, () { | 1295 new InterfaceTypeImpl.elementWithNameAndArgs(element, name, () { |
| 1299 if (typeArguments == null) { | 1296 if (typeArguments == null) { |
| 1300 typeArguments = new List<DartType>.filled( | |
| 1301 element.typeParameters.length, DynamicTypeImpl.instance); | |
| 1302 if (libraryResynthesizer.summaryResynthesizer.strongMode && | 1297 if (libraryResynthesizer.summaryResynthesizer.strongMode && |
| 1303 instantiateToBoundsAllowed) { | 1298 instantiateToBoundsAllowed) { |
| 1304 InterfaceType instantiatedToBounds = libraryResynthesizer | 1299 InterfaceType instantiatedToBounds = libraryResynthesizer |
| 1305 .summaryResynthesizer.context.typeSystem | 1300 .summaryResynthesizer.context.typeSystem |
| 1306 .instantiateToBounds(element.type) as InterfaceType; | 1301 .instantiateToBounds(element.type) as InterfaceType; |
| 1307 return instantiatedToBounds.typeArguments; | 1302 return instantiatedToBounds.typeArguments; |
| 1303 } else { |
| 1304 return new List<DartType>.filled( |
| 1305 numTypeParameters, DynamicTypeImpl.instance); |
| 1308 } | 1306 } |
| 1309 } | 1307 } |
| 1310 return typeArguments; | 1308 return typeArguments; |
| 1311 }); | 1309 }); |
| 1312 // Mark the type as having implicit type arguments, so that we don't | 1310 // Mark the type as having implicit type arguments, so that we don't |
| 1313 // attempt to request them during constant expression resynthesizing. | 1311 // attempt to request them during constant expression resynthesizing. |
| 1314 if (typeArguments == null) { | 1312 if (typeArguments == null) { |
| 1315 libraryResynthesizer.typesWithImplicitTypeArguments.add(type); | 1313 libraryResynthesizer.typesWithImplicitTypeArguments.add(type); |
| 1316 } | 1314 } |
| 1317 // Done. | 1315 // Done. |
| 1318 return type; | 1316 return type; |
| 1319 } else if (element is FunctionTypedElement) { | 1317 } else if (element is FunctionTypedElement) { |
| 1320 int numTypeArguments; | 1318 if (element is FunctionTypeAliasElementHandle) { |
| 1321 FunctionTypedElementComputer computer; | 1319 List<DartType> typeArguments; |
| 1322 if (implicitFunctionTypeIndices.isNotEmpty) { | 1320 if (numTypeArguments == numTypeParameters) { |
| 1323 numTypeArguments = numTypeParameters; | 1321 typeArguments = |
| 1324 computer = () { | 1322 _buildTypeArguments(numTypeArguments, getTypeArgument); |
| 1325 FunctionTypedElement element = this.element; | 1323 } else if (libraryResynthesizer.summaryResynthesizer.strongMode && |
| 1326 for (int index in implicitFunctionTypeIndices) { | 1324 instantiateToBoundsAllowed) { |
| 1327 element = element.parameters[index].type.element; | 1325 FunctionType instantiatedToBounds = libraryResynthesizer |
| 1328 } | 1326 .summaryResynthesizer.context.typeSystem |
| 1329 return element; | 1327 .instantiateToBounds(element.type) as FunctionType; |
| 1330 }; | 1328 typeArguments = instantiatedToBounds.typeArguments; |
| 1331 } else if (element is FunctionTypeAliasElementHandle) { | 1329 } else { |
| 1330 typeArguments = new List<DartType>.filled( |
| 1331 numTypeParameters, DynamicTypeImpl.instance); |
| 1332 } |
| 1332 return new FunctionTypeImpl.elementWithNameAndArgs( | 1333 return new FunctionTypeImpl.elementWithNameAndArgs( |
| 1333 element, | 1334 element, name, typeArguments, numTypeParameters != 0); |
| 1334 name, | |
| 1335 _buildTypeArguments(numTypeParameters, getTypeArgument), | |
| 1336 numTypeParameters != 0); | |
| 1337 } else { | 1335 } else { |
| 1338 // For a type that refers to a generic executable, the type arguments ar
e | 1336 FunctionTypedElementComputer computer; |
| 1339 // not supposed to include the arguments to the executable itself. | 1337 if (implicitFunctionTypeIndices.isNotEmpty) { |
| 1340 numTypeArguments = enclosing == null ? 0 : enclosing.numTypeParameters; | 1338 numTypeArguments = numTypeParameters; |
| 1341 computer = () => this.element as FunctionTypedElement; | 1339 computer = () { |
| 1340 FunctionTypedElement element = this.element; |
| 1341 for (int index in implicitFunctionTypeIndices) { |
| 1342 element = element.parameters[index].type.element; |
| 1343 } |
| 1344 return element; |
| 1345 }; |
| 1346 } else { |
| 1347 // For a type that refers to a generic executable, the type arguments
are |
| 1348 // not supposed to include the arguments to the executable itself. |
| 1349 numTypeArguments = enclosing?.numTypeParameters ?? 0; |
| 1350 computer = () => this.element as FunctionTypedElement; |
| 1351 } |
| 1352 // TODO(paulberry): Is it a bug that we have to pass `false` for |
| 1353 // isInstantiated? |
| 1354 return new DeferredFunctionTypeImpl(computer, null, |
| 1355 _buildTypeArguments(numTypeArguments, getTypeArgument), false); |
| 1342 } | 1356 } |
| 1343 // TODO(paulberry): Is it a bug that we have to pass `false` for | |
| 1344 // isInstantiated? | |
| 1345 return new DeferredFunctionTypeImpl(computer, null, | |
| 1346 _buildTypeArguments(numTypeArguments, getTypeArgument), false); | |
| 1347 } else { | 1357 } else { |
| 1348 return null; | 1358 return null; |
| 1349 } | 1359 } |
| 1350 } | 1360 } |
| 1351 | 1361 |
| 1352 /** | 1362 /** |
| 1353 * Build a list of type arguments having length [numTypeArguments] where each | 1363 * Build a list of type arguments having length [numTypeArguments] where each |
| 1354 * type argument is obtained by calling [getTypeArgument]. | 1364 * type argument is obtained by calling [getTypeArgument]. |
| 1355 */ | 1365 */ |
| 1356 List<DartType> _buildTypeArguments( | 1366 List<DartType> _buildTypeArguments( |
| 1357 int numTypeArguments, DartType getTypeArgument(int i)) { | 1367 int numTypeArguments, DartType getTypeArgument(int i)) { |
| 1358 List<DartType> typeArguments = const <DartType>[]; | 1368 List<DartType> typeArguments = const <DartType>[]; |
| 1359 if (numTypeArguments != 0) { | 1369 if (numTypeArguments != 0) { |
| 1360 typeArguments = <DartType>[]; | 1370 typeArguments = new List<DartType>(numTypeArguments); |
| 1361 for (int i = 0; i < numTypeArguments; i++) { | 1371 for (int i = 0; i < numTypeArguments; i++) { |
| 1362 typeArguments.add(getTypeArgument(i)); | 1372 typeArguments[i] = getTypeArgument(i); |
| 1363 } | 1373 } |
| 1364 } | 1374 } |
| 1365 return typeArguments; | 1375 return typeArguments; |
| 1366 } | 1376 } |
| 1367 } | 1377 } |
| 1368 | 1378 |
| 1369 class _ResynthesizerContext implements ResynthesizerContext { | 1379 class _ResynthesizerContext implements ResynthesizerContext { |
| 1370 final _UnitResynthesizer _unitResynthesizer; | 1380 final _UnitResynthesizer _unitResynthesizer; |
| 1371 | 1381 |
| 1372 _ResynthesizerContext(this._unitResynthesizer); | 1382 _ResynthesizerContext(this._unitResynthesizer); |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1917 static String _getElementIdentifier(String name, ReferenceKind kind) { | 1927 static String _getElementIdentifier(String name, ReferenceKind kind) { |
| 1918 if (kind == ReferenceKind.topLevelPropertyAccessor || | 1928 if (kind == ReferenceKind.topLevelPropertyAccessor || |
| 1919 kind == ReferenceKind.propertyAccessor) { | 1929 kind == ReferenceKind.propertyAccessor) { |
| 1920 if (!name.endsWith('=')) { | 1930 if (!name.endsWith('=')) { |
| 1921 return name + '?'; | 1931 return name + '?'; |
| 1922 } | 1932 } |
| 1923 } | 1933 } |
| 1924 return name; | 1934 return name; |
| 1925 } | 1935 } |
| 1926 } | 1936 } |
| OLD | NEW |