Build types for not simply bounded elements using dynamic type arguments.
R=brianwilkerson@google.com
Change-Id: Ia3c2d5193212a8cf58caad2323185e1ac9e31c9c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99716
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 8ba88df..b0bdfcd 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -554,6 +554,7 @@
node.implementsClause?.accept(this);
node.withClause?.accept(this);
node.members.accept(this);
+ nodesToBuildType.add(node);
scope = outerScope;
reference = outerReference;
diff --git a/pkg/analyzer/lib/src/summary2/type_builder.dart b/pkg/analyzer/lib/src/summary2/type_builder.dart
index 8db0314..2182e4e 100644
--- a/pkg/analyzer/lib/src/summary2/type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/type_builder.dart
@@ -49,6 +49,11 @@
}
}
+ void _buildElement(Element element) {
+ var node = (element as ElementImpl).linkedNode;
+ _build(node);
+ }
+
FunctionType _buildFunctionType(
TypeParameterList typeParameterList,
TypeAnnotation returnTypeNode,
@@ -82,7 +87,9 @@
}
void _declaration(AstNode node) {
- if (node is FieldFormalParameter) {
+ if (node is ClassDeclaration) {
+ _typeParameterList(node.typeParameters);
+ } else if (node is FieldFormalParameter) {
_fieldFormalParameter(node);
} else if (node is FunctionDeclaration) {
var defaultReturnType = node.isSetter ? _voidType : _dynamicType;
@@ -183,19 +190,28 @@
}
}
+ List<DartType> _typeArgumentList(TypeArgumentList node) {
+ if (node == null) return null;
+
+ var argumentNodes = node.arguments;
+ var argumentTypes = List<DartType>(argumentNodes.length);
+ for (var i = 0; i < argumentNodes.length; ++i) {
+ var argumentNode = argumentNodes[i];
+ _build(argumentNode);
+ argumentTypes[i] = argumentNode.type;
+ }
+ return argumentTypes;
+ }
+
void _typeName(TypeName node) {
var element = node.name.staticElement;
-
- List<DartType> typeArguments;
- var typeArgumentList = node.typeArguments;
- if (typeArgumentList != null) {
- typeArguments = typeArgumentList.arguments.map((a) => a.type).toList();
- }
-
if (element is ClassElement) {
if (element.isEnum) {
node.type = InterfaceTypeImpl.explicit(element, const []);
} else {
+ _buildElement(element);
+ var typeArguments = _typeArgumentList(node.typeArguments);
+
var rawType = element.type;
var typeParametersLength = element.typeParameters.length;
@@ -205,7 +221,12 @@
}
if (typeArguments == null) {
- node.type = typeSystem.instantiateToBounds(rawType);
+ if (element.isSimplyBounded) {
+ node.type = typeSystem.instantiateToBounds(rawType);
+ } else {
+ typeArguments = _listOfDynamic(typeParametersLength);
+ node.type = InterfaceTypeImpl.explicit(element, typeArguments);
+ }
return;
}
@@ -216,7 +237,8 @@
node.type = InterfaceTypeImpl.explicit(element, typeArguments);
}
} else if (element is GenericTypeAliasElement) {
- _build((element as ElementImpl).linkedNode);
+ _buildElement(element);
+ var typeArguments = _typeArgumentList(node.typeArguments);
var rawType = element.function.type;
@@ -228,9 +250,13 @@
}
if (typeArguments == null) {
- typeArguments = typeSystem.instantiateTypeFormalsToBounds(
- typeParameters,
- );
+ if (element.isSimplyBounded) {
+ typeArguments = typeSystem.instantiateTypeFormalsToBounds(
+ typeParameters,
+ );
+ } else {
+ typeArguments = _listOfDynamic(typeParametersLength);
+ }
} else if (typeArguments.length != typeParametersLength) {
typeArguments = _listOfDynamic(typeParametersLength);
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 47de718..666393d 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1270,12 +1270,21 @@
class C<T extends D> {}
class D<T extends C> {}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded class C<T extends D<dynamic>> {
+}
+notSimplyBounded class D<T extends C<dynamic>> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded class C<T extends D<dynamic>> {
}
notSimplyBounded class D<T extends C<D<dynamic>>> {
}
''');
+ }
}
test_class_notSimplyBounded_complex_by_reference_to_cycle() async {
@@ -6872,11 +6881,19 @@
class C<S extends num, T extends C<S, T>> {}
C c;
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded class C<S extends num, T extends C<S, T>> {
+}
+C<dynamic, dynamic> c;
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded class C<S extends num, T extends C<S, T>> {
}
C<num, C<num, dynamic>> c;
''');
+ }
}
test_instantiateToBounds_boundRefersToItself() async {
@@ -6888,7 +6905,18 @@
var c3 = new C();
}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded class C<T extends C<T>> {
+}
+class B {
+ C<C<dynamic>> c3;
+}
+C<dynamic> c;
+C<C<dynamic>> c2;
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded class C<T extends C<T>> {
}
class B {
@@ -6897,6 +6925,7 @@
C<C<dynamic>> c;
C<C<dynamic>> c2;
''');
+ }
}
test_instantiateToBounds_boundRefersToLaterTypeArgument() async {
@@ -6904,11 +6933,19 @@
class C<T extends C<T, U>, U extends num> {}
C c;
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded class C<T extends C<T, U>, U extends num> {
+}
+C<dynamic, dynamic> c;
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded class C<T extends C<T, U>, U extends num> {
}
C<C<dynamic, num>, num> c;
''');
+ }
}
test_instantiateToBounds_functionTypeAlias_reexported() async {
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 4a036db..7f58c00 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -29,6 +29,8 @@
*/
bool get mayCheckTypesOfLocals;
+ bool get useSummary2;
+
/**
* Add a new file with the given [name] and [content].
*/
@@ -3549,13 +3551,23 @@
class B<T extends /*error:NOT_INSTANTIATED_BOUND*/A> {}
B v = null;
''');
- checkElementText(unit.library, r'''
+ if (useSummary2) {
+ checkElementText(unit.library, r'''
+notSimplyBounded class A<T1 extends int, T2 extends T1> {
+}
+notSimplyBounded class B<T extends A<dynamic, dynamic>> {
+}
+B<dynamic> v;
+''');
+ } else {
+ checkElementText(unit.library, r'''
notSimplyBounded class A<T1 extends int, T2 extends T1> {
}
notSimplyBounded class B<T extends A<int, int>> {
}
B<A<int, int>> v;
''');
+ }
}
test_instantiateToBounds_typeName_error2() async {
@@ -3564,13 +3576,23 @@
class B<T extends /*error:NOT_INSTANTIATED_BOUND*/A> {}
B v = null;
''');
- checkElementText(unit.library, r'''
+ if (useSummary2) {
+ checkElementText(unit.library, r'''
+notSimplyBounded class A<T1 extends T2, T2 extends int> {
+}
+notSimplyBounded class B<T extends A<dynamic, dynamic>> {
+}
+B<dynamic> v;
+''');
+ } else {
+ checkElementText(unit.library, r'''
notSimplyBounded class A<T1 extends T2, T2 extends int> {
}
notSimplyBounded class B<T extends A<int, int>> {
}
B<A<int, int>> v;
''');
+ }
}
test_instantiateToBounds_typeName_error3() async {
@@ -3579,13 +3601,23 @@
class B<T extends /*error:NOT_INSTANTIATED_BOUND*/A> {}
B v = null;
''');
- checkElementText(unit.library, r'''
+ if (useSummary2) {
+ checkElementText(unit.library, r'''
+notSimplyBounded class A<T1 extends int, T2 extends List<T1>> {
+}
+notSimplyBounded class B<T extends A<dynamic, dynamic>> {
+}
+B<dynamic> v;
+''');
+ } else {
+ checkElementText(unit.library, r'''
notSimplyBounded class A<T1 extends int, T2 extends List<T1>> {
}
notSimplyBounded class B<T extends A<int, List<int>>> {
}
B<A<int, List<int>>> v;
''');
+ }
}
test_instantiateToBounds_typeName_OK_hasBound_definedAfter() async {
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 03726eb..e8be4ba 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -242,9 +242,11 @@
AnalysisContext _context = null;
AnalysisDriver _driver = null;
+ Map<String, List<Folder>> packageMap;
+
List<String> get enabledExperiments => [];
- Map<String, List<Folder>> packageMap;
+ bool get useSummary2 => _driver.useSummary2;
/// Adds a file to check. The file should contain:
///