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/element/element.dart'; | 10 import 'package:analyzer/dart/element/element.dart'; |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
506 // prepare ConstructorElement | 506 // prepare ConstructorElement |
507 String constructorName; | 507 String constructorName; |
508 if (info.element is ConstructorElement) { | 508 if (info.element is ConstructorElement) { |
509 constructorName = info.name; | 509 constructorName = info.name; |
510 } else if (info.element is ClassElement) { | 510 } else if (info.element is ClassElement) { |
511 constructorName = null; | 511 constructorName = null; |
512 } else { | 512 } else { |
513 throw new StateError('Unsupported element for invokeConstructor ' | 513 throw new StateError('Unsupported element for invokeConstructor ' |
514 '${info.element?.runtimeType}'); | 514 '${info.element?.runtimeType}'); |
515 } | 515 } |
516 _DeferredConstructorElement constructorElement = | 516 InterfaceType definingType = |
517 resynthesizer._createConstructorElement(info, ref.typeArguments); | 517 resynthesizer._createConstructorDefiningType(info, ref.typeArguments); |
518 ConstructorElement constructorElement = resynthesizer | |
519 ._createConstructorElement(definingType, info, ref.typeArguments); | |
518 // prepare arguments | 520 // prepare arguments |
519 List<Expression> arguments; | 521 List<Expression> arguments; |
520 { | 522 { |
521 int numNamedArgs = uc.ints[intPtr++]; | 523 int numNamedArgs = uc.ints[intPtr++]; |
522 int numPositionalArgs = uc.ints[intPtr++]; | 524 int numPositionalArgs = uc.ints[intPtr++]; |
523 int numArgs = numNamedArgs + numPositionalArgs; | 525 int numArgs = numNamedArgs + numPositionalArgs; |
524 arguments = _removeTopItems(numArgs); | 526 arguments = _removeTopItems(numArgs); |
525 // add names to the named arguments | 527 // add names to the named arguments |
526 for (int i = 0; i < numNamedArgs; i++) { | 528 for (int i = 0; i < numNamedArgs; i++) { |
527 String name = uc.strings[stringPtr++]; | 529 String name = uc.strings[stringPtr++]; |
528 int index = numPositionalArgs + i; | 530 int index = numPositionalArgs + i; |
529 arguments[index] = AstFactory.namedExpression2(name, arguments[index]); | 531 arguments[index] = AstFactory.namedExpression2(name, arguments[index]); |
530 } | 532 } |
531 } | 533 } |
532 // create TypeName | 534 // create TypeName |
533 TypeName typeNode = _buildTypeAst(constructorElement._definingType); | 535 TypeName typeNode = _buildTypeAst(definingType); |
534 // create ConstructorName | 536 // create ConstructorName |
535 ConstructorName constructorNode; | 537 ConstructorName constructorNode; |
536 if (constructorName != null) { | 538 if (constructorName != null) { |
537 constructorNode = AstFactory.constructorName(typeNode, constructorName); | 539 constructorNode = AstFactory.constructorName(typeNode, constructorName); |
538 constructorNode.name.staticElement = constructorElement; | 540 constructorNode.name.staticElement = constructorElement; |
539 } else { | 541 } else { |
540 constructorNode = AstFactory.constructorName(typeNode, null); | 542 constructorNode = AstFactory.constructorName(typeNode, null); |
541 } | 543 } |
542 constructorNode.staticElement = constructorElement; | 544 constructorNode.staticElement = constructorElement; |
543 // create InstanceCreationExpression | 545 // create InstanceCreationExpression |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
593 * then the type parameters of [_definingType] are not guaranteed to be | 595 * then the type parameters of [_definingType] are not guaranteed to be |
594 * valid. | 596 * valid. |
595 */ | 597 */ |
596 final InterfaceType _definingType; | 598 final InterfaceType _definingType; |
597 | 599 |
598 /** | 600 /** |
599 * The constructor name. | 601 * The constructor name. |
600 */ | 602 */ |
601 final String name; | 603 final String name; |
602 | 604 |
603 /** | |
604 * Indicates whether the deferred element is a [ConstructorMember] or simply | |
605 * a [ConstructorElement]. | |
606 */ | |
607 final bool _isMember; | |
608 | |
609 factory _DeferredConstructorElement(InterfaceType definingType, String name) { | 605 factory _DeferredConstructorElement(InterfaceType definingType, String name) { |
610 List<String> components = definingType.element.location.components.toList(); | 606 List<String> components = definingType.element.location.components.toList(); |
611 components.add(name); | 607 components.add(name); |
612 ElementLocationImpl location = new ElementLocationImpl.con3(components); | 608 ElementLocationImpl location = new ElementLocationImpl.con3(components); |
613 return new _DeferredConstructorElement._( | 609 return new _DeferredConstructorElement._(definingType, name, location); |
614 definingType, name, location, true); | |
615 } | 610 } |
616 | 611 |
617 _DeferredConstructorElement._( | 612 _DeferredConstructorElement._( |
618 this._definingType, this.name, ElementLocation location, this._isMember) | 613 this._definingType, this.name, ElementLocation location) |
619 : super(null, location); | 614 : super(null, location); |
620 | 615 |
621 @override | 616 @override |
622 Element get actualElement { | 617 Element get actualElement => enclosingElement.getNamedConstructor(name); |
623 ConstructorElement element = enclosingElement.getNamedConstructor(name); | |
624 if (_isMember && _definingType.typeArguments.isNotEmpty) { | |
625 return new ConstructorMember(element, _definingType); | |
626 } else { | |
627 return element; | |
628 } | |
629 } | |
630 | 618 |
631 @override | 619 @override |
632 AnalysisContext get context => _definingType.element.context; | 620 AnalysisContext get context => _definingType.element.context; |
633 | 621 |
634 @override | 622 @override |
635 String get displayName => name; | 623 String get displayName => name; |
636 | 624 |
637 @override | 625 @override |
638 ClassElement get enclosingElement { | 626 ClassElement get enclosingElement { |
639 return _definingType.element; | 627 return _definingType.element; |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
934 currentConstructor.factory = serializedExecutable.isFactory; | 922 currentConstructor.factory = serializedExecutable.isFactory; |
935 currentConstructor.const2 = serializedExecutable.isConst; | 923 currentConstructor.const2 = serializedExecutable.isConst; |
936 currentConstructor.constantInitializers = serializedExecutable | 924 currentConstructor.constantInitializers = serializedExecutable |
937 .constantInitializers | 925 .constantInitializers |
938 .map(buildConstantInitializer) | 926 .map(buildConstantInitializer) |
939 .toList(); | 927 .toList(); |
940 if (serializedExecutable.isRedirectedConstructor) { | 928 if (serializedExecutable.isRedirectedConstructor) { |
941 if (serializedExecutable.isFactory) { | 929 if (serializedExecutable.isFactory) { |
942 EntityRef redirectedConstructor = | 930 EntityRef redirectedConstructor = |
943 serializedExecutable.redirectedConstructor; | 931 serializedExecutable.redirectedConstructor; |
932 _ReferenceInfo info = referenceInfos[redirectedConstructor.reference]; | |
933 List<EntityRef> typeArguments = redirectedConstructor.typeArguments; | |
944 currentConstructor.redirectedConstructor = _createConstructorElement( | 934 currentConstructor.redirectedConstructor = _createConstructorElement( |
945 referenceInfos[redirectedConstructor.reference], | 935 _createConstructorDefiningType(info, typeArguments), |
946 redirectedConstructor.typeArguments); | 936 info, |
937 typeArguments); | |
947 } else { | 938 } else { |
948 List<String> locationComponents = | 939 List<String> locationComponents = |
949 currentCompilationUnit.location.components.toList(); | 940 currentCompilationUnit.location.components.toList(); |
950 locationComponents.add(classType.name); | 941 locationComponents.add(classType.name); |
951 locationComponents.add(serializedExecutable.redirectedConstructorName); | 942 locationComponents.add(serializedExecutable.redirectedConstructorName); |
952 currentConstructor.redirectedConstructor = | 943 currentConstructor.redirectedConstructor = |
953 new _DeferredConstructorElement._( | 944 new _DeferredConstructorElement._( |
954 classType, | 945 classType, |
955 serializedExecutable.redirectedConstructorName, | 946 serializedExecutable.redirectedConstructorName, |
956 new ElementLocationImpl.con3(locationComponents), | 947 new ElementLocationImpl.con3(locationComponents)); |
957 false); | |
958 } | 948 } |
959 } | 949 } |
960 holder.addConstructor(currentConstructor); | 950 holder.addConstructor(currentConstructor); |
961 currentConstructor = null; | 951 currentConstructor = null; |
962 } | 952 } |
963 | 953 |
964 /** | 954 /** |
965 * Build the documentation for the given [element]. Does nothing if | 955 * Build the documentation for the given [element]. Does nothing if |
966 * [serializedDocumentationComment] is `null`. | 956 * [serializedDocumentationComment] is `null`. |
967 */ | 957 */ |
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1898 /** | 1888 /** |
1899 * Return the new handle of the `String.length` getter element. | 1889 * Return the new handle of the `String.length` getter element. |
1900 */ | 1890 */ |
1901 PropertyAccessorElementHandle _buildStringLengthPropertyAccessorElement() => | 1891 PropertyAccessorElementHandle _buildStringLengthPropertyAccessorElement() => |
1902 new PropertyAccessorElementHandle( | 1892 new PropertyAccessorElementHandle( |
1903 summaryResynthesizer, | 1893 summaryResynthesizer, |
1904 new ElementLocationImpl.con3( | 1894 new ElementLocationImpl.con3( |
1905 <String>['dart:core', 'dart:core', 'String', 'length?'])); | 1895 <String>['dart:core', 'dart:core', 'String', 'length?'])); |
1906 | 1896 |
1907 /** | 1897 /** |
1898 * Return the defining type for a [ConstructorElement] by applying | |
1899 * [typeArgumentRefs] to the given linked [info]. | |
1900 */ | |
1901 InterfaceType _createConstructorDefiningType( | |
1902 _ReferenceInfo info, List<EntityRef> typeArgumentRefs) { | |
1903 bool isClass = info.element is ClassElement; | |
1904 _ReferenceInfo classInfo = isClass ? info : info.enclosing; | |
1905 List<DartType> typeArguments = typeArgumentRefs.map(buildType).toList(); | |
1906 return classInfo.buildType((i) { | |
1907 if (i < typeArguments.length) { | |
1908 return typeArguments[i]; | |
1909 } else { | |
1910 return DynamicTypeImpl.instance; | |
1911 } | |
1912 }, const <int>[]); | |
1913 } | |
1914 | |
1915 /** | |
1908 * Return the [ConstructorElement] by applying [typeArgumentRefs] to the | 1916 * Return the [ConstructorElement] by applying [typeArgumentRefs] to the |
1909 * given linked [info]. Both cases when [info] is a [ClassElement] and | 1917 * given linked [info]. Both cases when [info] is a [ClassElement] and |
1910 * [ConstructorElement] are supported. | 1918 * [ConstructorElement] are supported. |
1911 */ | 1919 */ |
1912 _DeferredConstructorElement _createConstructorElement( | 1920 ConstructorElement _createConstructorElement(InterfaceType classType, |
1913 _ReferenceInfo info, List<EntityRef> typeArgumentRefs) { | 1921 _ReferenceInfo info, List<EntityRef> typeArgumentRefs) { |
scheglov
2016/02/10 21:53:26
Do we need "typeArgumentRefs" here now?
Shoudl we
Paul Berry
2016/02/10 22:10:59
You're right--we don't need it anymore. I've remo
| |
1914 bool isClass = info.element is ClassElement; | 1922 bool isClass = info.element is ClassElement; |
1915 _ReferenceInfo classInfo = isClass ? info : info.enclosing; | |
1916 List<DartType> typeArguments = typeArgumentRefs.map(buildType).toList(); | |
1917 InterfaceType classType = classInfo.buildType((i) { | |
1918 if (i < typeArguments.length) { | |
1919 return typeArguments[i]; | |
1920 } else { | |
1921 return DynamicTypeImpl.instance; | |
1922 } | |
1923 }, const <int>[]); | |
1924 String name = isClass ? '' : info.name; | 1923 String name = isClass ? '' : info.name; |
1925 return new _DeferredConstructorElement(classType, name); | 1924 _DeferredConstructorElement element = |
1925 new _DeferredConstructorElement(classType, name); | |
1926 if (info.numTypeParameters != 0) { | |
1927 return new ConstructorMember(element, classType); | |
1928 } else { | |
1929 return element; | |
1930 } | |
1926 } | 1931 } |
1927 | 1932 |
1928 /** | 1933 /** |
1929 * If the given [kind] is a top-level or class member property accessor, and | 1934 * If the given [kind] is a top-level or class member property accessor, and |
1930 * the given [name] does not end with `=`, i.e. does not denote a setter, | 1935 * the given [name] does not end with `=`, i.e. does not denote a setter, |
1931 * return the getter identifier by appending `?`. | 1936 * return the getter identifier by appending `?`. |
1932 */ | 1937 */ |
1933 static String _getElementIdentifier(String name, ReferenceKind kind) { | 1938 static String _getElementIdentifier(String name, ReferenceKind kind) { |
1934 if (kind == ReferenceKind.topLevelPropertyAccessor || | 1939 if (kind == ReferenceKind.topLevelPropertyAccessor || |
1935 kind == ReferenceKind.propertyAccessor) { | 1940 kind == ReferenceKind.propertyAccessor) { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2059 } | 2064 } |
2060 : () => this.element; | 2065 : () => this.element; |
2061 // TODO(paulberry): Is it a bug that we have to pass `false` for | 2066 // TODO(paulberry): Is it a bug that we have to pass `false` for |
2062 // isInstantiated? | 2067 // isInstantiated? |
2063 return new DeferredFunctionTypeImpl(computer, null, typeArguments, false); | 2068 return new DeferredFunctionTypeImpl(computer, null, typeArguments, false); |
2064 } else { | 2069 } else { |
2065 return null; | 2070 return null; |
2066 } | 2071 } |
2067 } | 2072 } |
2068 } | 2073 } |
OLD | NEW |