Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(607)

Side by Side Diff: pkg/analyzer/lib/src/summary/link.dart

Issue 2028713003: Fix AST-based type inference with explicit type parameters for method calls. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 /** 5 /**
6 * This library is capable of producing linked summaries from unlinked 6 * This library is capable of producing linked summaries from unlinked
7 * ones (or prelinked ones). It functions by building a miniature 7 * ones (or prelinked ones). It functions by building a miniature
8 * element model to represent the contents of the summaries, and then 8 * element model to represent the contents of the summaries, and then
9 * scanning the element model to gather linked information and adding 9 * scanning the element model to gather linked information and adding
10 * it to the summary data structures. 10 * it to the summary data structures.
(...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 * [dependencies]. 1491 * [dependencies].
1492 */ 1492 */
1493 void collectDependencies( 1493 void collectDependencies(
1494 List<ConstNode> dependencies, 1494 List<ConstNode> dependencies,
1495 UnlinkedConst unlinkedConst, 1495 UnlinkedConst unlinkedConst,
1496 CompilationUnitElementForLink compilationUnit) { 1496 CompilationUnitElementForLink compilationUnit) {
1497 if (unlinkedConst == null) { 1497 if (unlinkedConst == null) {
1498 return; 1498 return;
1499 } 1499 }
1500 int refPtr = 0; 1500 int refPtr = 0;
1501 int intPtr = 0;
1501 for (UnlinkedConstOperation operation in unlinkedConst.operations) { 1502 for (UnlinkedConstOperation operation in unlinkedConst.operations) {
1502 switch (operation) { 1503 switch (operation) {
1504 case UnlinkedConstOperation.pushInt:
1505 intPtr++;
1506 break;
1507 case UnlinkedConstOperation.pushLongInt:
1508 int numInts = unlinkedConst.ints[intPtr++];
1509 intPtr += numInts;
1510 break;
1511 case UnlinkedConstOperation.concatenate:
1512 intPtr++;
1513 break;
1503 case UnlinkedConstOperation.pushReference: 1514 case UnlinkedConstOperation.pushReference:
1515 EntityRef ref = unlinkedConst.references[refPtr++];
1516 ConstVariableNode variable =
1517 compilationUnit.resolveRef(ref.reference).asConstVariable;
1518 if (variable != null) {
1519 dependencies.add(variable);
1520 }
1521 break;
1522 case UnlinkedConstOperation.makeUntypedList:
1523 case UnlinkedConstOperation.makeUntypedMap:
1524 intPtr++;
1525 break;
1526 case UnlinkedConstOperation.assignToRef:
1527 refPtr++;
1528 break;
1504 case UnlinkedConstOperation.invokeMethodRef: 1529 case UnlinkedConstOperation.invokeMethodRef:
1505 EntityRef ref = unlinkedConst.references[refPtr++]; 1530 EntityRef ref = unlinkedConst.references[refPtr++];
1506 ConstVariableNode variable = 1531 ConstVariableNode variable =
1507 compilationUnit.resolveRef(ref.reference).asConstVariable; 1532 compilationUnit.resolveRef(ref.reference).asConstVariable;
1508 if (variable != null) { 1533 if (variable != null) {
1509 dependencies.add(variable); 1534 dependencies.add(variable);
1510 } 1535 }
1536 intPtr += 2;
1537 int numTypeArguments = unlinkedConst.ints[intPtr++];
1538 refPtr += numTypeArguments;
1539 break;
1540 case UnlinkedConstOperation.invokeMethod:
1541 intPtr += 2;
1542 int numTypeArguments = unlinkedConst.ints[intPtr++];
1543 refPtr += numTypeArguments;
1511 break; 1544 break;
1512 case UnlinkedConstOperation.makeTypedList: 1545 case UnlinkedConstOperation.makeTypedList:
1513 refPtr++; 1546 refPtr++;
1547 intPtr++;
1514 break; 1548 break;
1515 case UnlinkedConstOperation.makeTypedMap: 1549 case UnlinkedConstOperation.makeTypedMap:
1516 refPtr += 2; 1550 refPtr += 2;
1551 intPtr++;
1517 break; 1552 break;
1518 case UnlinkedConstOperation.invokeConstructor: 1553 case UnlinkedConstOperation.invokeConstructor:
1519 EntityRef ref = unlinkedConst.references[refPtr++]; 1554 EntityRef ref = unlinkedConst.references[refPtr++];
1520 ConstructorElementForLink element = 1555 ConstructorElementForLink element =
1521 compilationUnit.resolveRef(ref.reference).asConstructor; 1556 compilationUnit.resolveRef(ref.reference).asConstructor;
1522 if (element?._constNode != null) { 1557 if (element?._constNode != null) {
1523 dependencies.add(element._constNode); 1558 dependencies.add(element._constNode);
1524 } 1559 }
1560 intPtr += 2;
1561 break;
1562 case UnlinkedConstOperation.typeCast:
1563 case UnlinkedConstOperation.typeCheck:
1564 refPtr++;
1565 break;
1566 case UnlinkedConstOperation.pushLocalFunctionReference:
1567 intPtr += 2;
1525 break; 1568 break;
1526 default: 1569 default:
1527 break; 1570 break;
1528 } 1571 }
1529 } 1572 }
1530 assert(refPtr == unlinkedConst.references.length); 1573 assert(refPtr == unlinkedConst.references.length);
1574 assert(intPtr == unlinkedConst.ints.length);
1531 } 1575 }
1532 } 1576 }
1533 1577
1534 /** 1578 /**
1535 * Instance of [ConstNode] representing a parameter with a default 1579 * Instance of [ConstNode] representing a parameter with a default
1536 * value. 1580 * value.
1537 */ 1581 */
1538 class ConstParameterNode extends ConstNode { 1582 class ConstParameterNode extends ConstNode {
1539 /** 1583 /**
1540 * The [ParameterElement] to which this node refers. 1584 * The [ParameterElement] to which this node refers.
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after
2344 2388
2345 void _doInvokeMethod() { 2389 void _doInvokeMethod() {
2346 int numNamed = unlinkedConst.ints[intPtr++]; 2390 int numNamed = unlinkedConst.ints[intPtr++];
2347 int numPositional = unlinkedConst.ints[intPtr++]; 2391 int numPositional = unlinkedConst.ints[intPtr++];
2348 List<String> namedArgNames = _getNextStrings(numNamed); 2392 List<String> namedArgNames = _getNextStrings(numNamed);
2349 List<DartType> namedArgTypeList = _popList(numNamed); 2393 List<DartType> namedArgTypeList = _popList(numNamed);
2350 List<DartType> positionalArgTypes = _popList(numPositional); 2394 List<DartType> positionalArgTypes = _popList(numPositional);
2351 // TODO(scheglov) if we pushed target and method name first, we might be 2395 // TODO(scheglov) if we pushed target and method name first, we might be
2352 // able to move work with arguments in _inferExecutableType() 2396 // able to move work with arguments in _inferExecutableType()
2353 String methodName = _getNextString(); 2397 String methodName = _getNextString();
2398 List<DartType> typeArguments = _getTypeArguments();
2354 DartType target = stack.removeLast(); 2399 DartType target = stack.removeLast();
2355 stack.add(() { 2400 stack.add(() {
2356 if (target is InterfaceType) { 2401 if (target is InterfaceType) {
2357 MethodElement method = 2402 MethodElement method =
2358 target.lookUpInheritedMethod(methodName, library: library); 2403 target.lookUpInheritedMethod(methodName, library: library);
2359 FunctionType rawType = method?.type; 2404 FunctionType rawType = method?.type;
2360 FunctionType inferredType = _inferExecutableType(rawType, numNamed, 2405 FunctionType inferredType = _inferExecutableType(
2361 numPositional, namedArgNames, namedArgTypeList, positionalArgTypes); 2406 rawType,
2407 numNamed,
2408 numPositional,
2409 namedArgNames,
2410 namedArgTypeList,
2411 positionalArgTypes,
2412 typeArguments);
2362 if (inferredType != null) { 2413 if (inferredType != null) {
2363 return inferredType.returnType; 2414 return inferredType.returnType;
2364 } 2415 }
2365 } 2416 }
2366 return DynamicTypeImpl.instance; 2417 return DynamicTypeImpl.instance;
2367 }()); 2418 }());
2368 } 2419 }
2369 2420
2370 void _doInvokeMethodRef() { 2421 void _doInvokeMethodRef() {
2371 int numNamed = _getNextInt(); 2422 int numNamed = _getNextInt();
2372 int numPositional = _getNextInt(); 2423 int numPositional = _getNextInt();
2373 List<String> namedArgNames = _getNextStrings(numNamed); 2424 List<String> namedArgNames = _getNextStrings(numNamed);
2374 List<DartType> namedArgTypeList = _popList(numNamed); 2425 List<DartType> namedArgTypeList = _popList(numNamed);
2375 List<DartType> positionalArgTypes = _popList(numPositional); 2426 List<DartType> positionalArgTypes = _popList(numPositional);
2376 EntityRef ref = _getNextRef(); 2427 EntityRef ref = _getNextRef();
2377 ReferenceableElementForLink element = unit.resolveRef(ref.reference); 2428 ReferenceableElementForLink element = unit.resolveRef(ref.reference);
2429 List<DartType> typeArguments = _getTypeArguments();
2378 stack.add(() { 2430 stack.add(() {
2379 DartType rawType = element.asStaticType; 2431 DartType rawType = element.asStaticType;
2380 if (rawType is FunctionType) { 2432 if (rawType is FunctionType) {
2381 FunctionType inferredType = _inferExecutableType(rawType, numNamed, 2433 FunctionType inferredType = _inferExecutableType(
2382 numPositional, namedArgNames, namedArgTypeList, positionalArgTypes); 2434 rawType,
2435 numNamed,
2436 numPositional,
2437 namedArgNames,
2438 namedArgTypeList,
2439 positionalArgTypes,
2440 typeArguments);
2383 if (inferredType != null) { 2441 if (inferredType != null) {
2384 return inferredType.returnType; 2442 return inferredType.returnType;
2385 } 2443 }
2386 } 2444 }
2387 return DynamicTypeImpl.instance; 2445 return DynamicTypeImpl.instance;
2388 }()); 2446 }());
2389 } 2447 }
2390 2448
2391 void _doMakeTypedList() { 2449 void _doMakeTypedList() {
2392 DartType itemType = _getNextTypeRef(); 2450 DartType itemType = _getNextTypeRef();
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 * resolved. 2555 * resolved.
2498 */ 2556 */
2499 DartType _getPropertyType(DartType targetType, String propertyName) { 2557 DartType _getPropertyType(DartType targetType, String propertyName) {
2500 return targetType is InterfaceType 2558 return targetType is InterfaceType
2501 ? targetType 2559 ? targetType
2502 .lookUpInheritedGetter(propertyName, library: library) 2560 .lookUpInheritedGetter(propertyName, library: library)
2503 ?.returnType 2561 ?.returnType
2504 : DynamicTypeImpl.instance; 2562 : DynamicTypeImpl.instance;
2505 } 2563 }
2506 2564
2565 List<DartType> _getTypeArguments() {
2566 int numTypeArguments = _getNextInt();
2567 List<DartType> typeArguments = new List<DartType>(numTypeArguments);
2568 for (int i = 0; i < numTypeArguments; i++) {
2569 typeArguments[i] = _getNextTypeRef();
2570 }
2571 return typeArguments;
2572 }
2573
2507 FunctionType _inferExecutableType( 2574 FunctionType _inferExecutableType(
2508 FunctionType rawMethodType, 2575 FunctionType rawMethodType,
2509 int numNamed, 2576 int numNamed,
2510 int numPositional, 2577 int numPositional,
2511 List<String> namedArgNames, 2578 List<String> namedArgNames,
2512 List<DartType> namedArgTypeList, 2579 List<DartType> namedArgTypeList,
2513 List<DartType> positionalArgTypes) { 2580 List<DartType> positionalArgTypes,
2581 List<DartType> typeArguments) {
2514 TypeSystem ts = linker.typeSystem; 2582 TypeSystem ts = linker.typeSystem;
2515 if (rawMethodType != null) { 2583 if (rawMethodType != null) {
2516 if (rawMethodType.typeFormals.isNotEmpty && ts is StrongTypeSystemImpl) { 2584 if (rawMethodType.typeFormals.isNotEmpty && typeArguments.isNotEmpty) {
2585 Element methodElement = rawMethodType.element;
2586 if (methodElement is TypeParameterizedElement &&
2587 methodElement.typeParameters.length == typeArguments.length) {
2588 return rawMethodType.instantiate(typeArguments);
2589 }
2590 } else if (rawMethodType.typeFormals.isNotEmpty &&
2591 ts is StrongTypeSystemImpl) {
2517 List<DartType> paramTypes = <DartType>[]; 2592 List<DartType> paramTypes = <DartType>[];
2518 List<DartType> argTypes = <DartType>[]; 2593 List<DartType> argTypes = <DartType>[];
2519 // Add positional parameter and argument types. 2594 // Add positional parameter and argument types.
2520 for (int i = 0; i < numPositional; i++) { 2595 for (int i = 0; i < numPositional; i++) {
2521 ParameterElement parameter = rawMethodType.parameters[i]; 2596 ParameterElement parameter = rawMethodType.parameters[i];
2522 if (parameter != null) { 2597 if (parameter != null) {
2523 paramTypes.add(parameter.type); 2598 paramTypes.add(parameter.type);
2524 argTypes.add(positionalArgTypes[i]); 2599 argTypes.add(positionalArgTypes[i]);
2525 } 2600 }
2526 } 2601 }
(...skipping 1989 matching lines...) Expand 10 before | Expand all | Expand 10 after
4516 case UnlinkedConstOperation.assignToRef: 4591 case UnlinkedConstOperation.assignToRef:
4517 // TODO(paulberry): if this reference refers to a variable, should it 4592 // TODO(paulberry): if this reference refers to a variable, should it
4518 // be considered a type inference dependency? 4593 // be considered a type inference dependency?
4519 refPtr++; 4594 refPtr++;
4520 break; 4595 break;
4521 case UnlinkedConstOperation.invokeMethodRef: 4596 case UnlinkedConstOperation.invokeMethodRef:
4522 // TODO(paulberry): if this reference refers to a variable, should it 4597 // TODO(paulberry): if this reference refers to a variable, should it
4523 // be considered a type inference dependency? 4598 // be considered a type inference dependency?
4524 refPtr++; 4599 refPtr++;
4525 intPtr += 2; 4600 intPtr += 2;
4601 int numTypeArguments = unlinkedConst.ints[intPtr++];
4602 refPtr += numTypeArguments;
4526 break; 4603 break;
4527 case UnlinkedConstOperation.invokeMethod: 4604 case UnlinkedConstOperation.invokeMethod:
4528 intPtr += 2; 4605 intPtr += 2;
4606 int numTypeArguments = unlinkedConst.ints[intPtr++];
4607 refPtr += numTypeArguments;
4529 break; 4608 break;
4530 case UnlinkedConstOperation.typeCast: 4609 case UnlinkedConstOperation.typeCast:
4531 case UnlinkedConstOperation.typeCheck: 4610 case UnlinkedConstOperation.typeCheck:
4532 refPtr++; 4611 refPtr++;
4533 break; 4612 break;
4534 case UnlinkedConstOperation.pushLocalFunctionReference: 4613 case UnlinkedConstOperation.pushLocalFunctionReference:
4535 int popCount = unlinkedConst.ints[intPtr++]; 4614 int popCount = unlinkedConst.ints[intPtr++];
4536 assert(popCount == 0); // TODO(paulberry): handle the nonzero case. 4615 assert(popCount == 0); // TODO(paulberry): handle the nonzero case.
4537 dependencies.add(functionElement 4616 dependencies.add(functionElement
4538 .getLocalFunction(unlinkedConst.ints[intPtr++]) 4617 .getLocalFunction(unlinkedConst.ints[intPtr++])
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
4873 * there are no type parameters in scope. 4952 * there are no type parameters in scope.
4874 */ 4953 */
4875 TypeParameterizedElementMixin get _typeParameterContext; 4954 TypeParameterizedElementMixin get _typeParameterContext;
4876 4955
4877 @override 4956 @override
4878 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 4957 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
4879 4958
4880 @override 4959 @override
4881 String toString() => '$enclosingElement.$name'; 4960 String toString() => '$enclosingElement.$name';
4882 } 4961 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698