Instantiate to bounds when resolving type names.
R=brianwilkerson@google.com
Change-Id: I55ea6339b5b949f986f7e6becc60c0328496489e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99188
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index b5623fb..b8a1a61 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -245,7 +245,7 @@
library.resolveTypes(nodesToBuildType);
}
computeSimplyBounded(bundleContext, builders.values);
- TypeBuilder(linkingBundleContext).build(nodesToBuildType);
+ TypeBuilder(typeSystem).build(nodesToBuildType);
}
}
diff --git a/pkg/analyzer/lib/src/summary2/type_builder.dart b/pkg/analyzer/lib/src/summary2/type_builder.dart
index 7093935..ccad03b 100644
--- a/pkg/analyzer/lib/src/summary2/type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/type_builder.dart
@@ -9,9 +9,8 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/generated/type_system.dart';
import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linking_bundle_context.dart';
/// Type annotations and declarations to build types for.
///
@@ -44,9 +43,9 @@
/// Build types in a [NodesToBuildType].
class TypeBuilder {
- final LinkingBundleContext bundleContext;
+ final Dart2TypeSystem typeSystem;
- TypeBuilder(this.bundleContext);
+ TypeBuilder(this.typeSystem);
DynamicTypeImpl get _dynamicType {
return DynamicTypeImpl.instance;
@@ -122,102 +121,56 @@
if (element.isEnum) {
node.type = InterfaceTypeImpl.explicit(element, const []);
} else {
- // TODO(scheglov) Use instantiate to bounds.
+ var rawType = element.type;
+
var typeParametersLength = element.typeParameters.length;
- if (typeArguments == null ||
- typeArguments.length != typeParametersLength) {
- typeArguments = List<DartType>.filled(
- typeParametersLength,
- DynamicTypeImpl.instance,
- );
+ if (typeParametersLength == 0) {
+ node.type = rawType;
+ return;
}
+
+ if (typeArguments == null) {
+ node.type = typeSystem.instantiateToBounds(rawType);
+ return;
+ }
+
+ if (typeArguments.length != typeParametersLength) {
+ typeArguments = _listOfDynamic(typeParametersLength);
+ }
+
node.type = InterfaceTypeImpl.explicit(element, typeArguments);
}
} else if (element is GenericTypeAliasElement) {
- // TODO(scheglov) Use instantiate to bounds.
- var typeParametersLength = element.typeParameters.length;
- if (typeArguments == null ||
- typeArguments.length != typeParametersLength) {
- typeArguments = List<DartType>.filled(
- typeParametersLength,
- DynamicTypeImpl.instance,
+ var rawType = element.function.type;
+
+ var typeParameters = element.typeParameters;
+ var typeParametersLength = typeParameters.length;
+ if (typeParametersLength == 0) {
+ node.type = rawType;
+ return;
+ }
+
+ if (typeArguments == null) {
+ typeArguments = typeSystem.instantiateTypeFormalsToBounds(
+ typeParameters,
);
+ } else if (typeArguments.length != typeParametersLength) {
+ typeArguments = _listOfDynamic(typeParametersLength);
}
var substitution = Substitution.fromPairs(
- element.typeParameters,
+ typeParameters,
typeArguments,
);
-
- // TODO(scheglov) Not sure if I like this.
- var type = substitution.substituteType(element.function.type);
- node.type = type;
+ node.type = substitution.substituteType(rawType);
} else if (element is TypeParameterElement) {
node.type = TypeParameterTypeImpl(element);
} else {
-// throw UnimplementedError('${element.runtimeType}');
- // TODO(scheglov) implement
- node.type = DynamicTypeImpl.instance;
+ // We might get all kinds of elements, including not type at all.
+ // For example a PrefixElement, or a getter, etc.
+ // In all these cases the type is dynamic.
+ node.type = _dynamicType;
}
-
-// var referenceIndex = typeNameElementIndex(node.typeName_name);
-// var reference = bundleContext.referenceOfIndex(referenceIndex);
-//
-// List<LinkedNodeTypeBuilder> typeArguments;
-// var typeArgumentList = node.typeName_typeArguments;
-// if (typeArgumentList != null) {
-// typeArguments = typeArgumentList.typeArgumentList_arguments
-// .map((node) => _getType(node))
-// .toList();
-// }
-//
-// if (reference.isClass) {
-// // TODO(scheglov) Use instantiate to bounds.
-// var typeParametersLength = _typeParametersLength(reference);
-// if (typeArguments == null ||
-// typeArguments.length != typeParametersLength) {
-// typeArguments = List<LinkedNodeTypeBuilder>.filled(
-// typeParametersLength,
-// _dynamicType,
-// );
-// }
-// node.typeName_type = LinkedNodeTypeBuilder(
-// kind: LinkedNodeTypeKind.interface,
-// interfaceClass: referenceIndex,
-// interfaceTypeArguments: typeArguments,
-// );
-// } else if (reference.isDynamic) {
-// node.typeName_type = LinkedNodeTypeBuilder(
-// kind: LinkedNodeTypeKind.dynamic_,
-// );
-// } else if (reference.isTypeAlias) {
-// // TODO(scheglov) Use instantiate to bounds.
-// var typeParametersLength = _typeParametersLength(reference);
-// if (typeArguments == null ||
-// typeArguments.length != typeParametersLength) {
-// typeArguments = List<LinkedNodeTypeBuilder>.filled(
-// typeParametersLength,
-// _dynamicType,
-// );
-// }
-// node.typeName_type = LinkedNodeTypeBuilder(
-// kind: LinkedNodeTypeKind.genericTypeAlias,
-// genericTypeAliasReference: referenceIndex,
-// genericTypeAliasTypeArguments: typeArguments,
-// );
-// } else if (reference.isEnum) {
-// node.typeName_type = LinkedNodeTypeBuilder(
-// kind: LinkedNodeTypeKind.interface,
-// interfaceClass: referenceIndex,
-// );
-// } else if (reference.isTypeParameter) {
-// node.typeName_type = LinkedNodeTypeBuilder(
-// kind: LinkedNodeTypeKind.typeParameter,
-// typeParameterParameter: referenceIndex,
-// );
-// } else {
-// node.typeName_type = _dynamicType;
-// }
}
void _fieldFormalParameter(FieldFormalParameter node) {
@@ -243,32 +196,9 @@
LazyAst.setType(node, type);
}
-// LinkedNodeTypeBuilder _getFormalParameterType(LinkedNode node) {
-// var kind = node.kind;
-// if (kind == LinkedNodeKind.defaultFormalParameter) {
-// return _getFormalParameterType(node.defaultFormalParameter_parameter);
-// }
-// if (kind == LinkedNodeKind.functionTypedFormalParameter) {
-// return node.functionTypedFormalParameter_type2;
-// }
-// if (kind == LinkedNodeKind.simpleFormalParameter) {
-// return _getType(node.simpleFormalParameter_type);
-// }
-// throw UnimplementedError('$kind');
-// }
-
-// LinkedNodeTypeBuilder _getType(LinkedNodeBuilder node) {
-// if (node == null) return _dynamicType;
-//
-// var kind = node.kind;
-// if (kind == LinkedNodeKind.genericFunctionType) {
-// return node.genericFunctionType_type;
-// } else if (kind == LinkedNodeKind.typeName) {
-// return node.typeName_type;
-// } else {
-// throw UnimplementedError('$kind');
-// }
-// }
+ List<DartType> _listOfDynamic(int typeParametersLength) {
+ return List<DartType>.filled(typeParametersLength, _dynamicType);
+ }
void _setTypesForDeclaration(AstNode node) {
if (node is FieldFormalParameter) {
@@ -298,52 +228,5 @@
} else {
throw UnimplementedError('${node.runtimeType}');
}
-// var kind = node.kind;
-// if (kind == LinkedNodeKind.fieldFormalParameter) {
-// _fieldFormalParameter(node);
-// } else if (kind == LinkedNodeKind.functionDeclaration) {
-// node.functionDeclaration_returnType2 = _getType(
-// node.functionDeclaration_returnType,
-// );
-// } else if (kind == LinkedNodeKind.functionTypeAlias) {
-// node.functionTypeAlias_returnType2 = _getType(
-// node.functionTypeAlias_returnType,
-// );
-// } else if (kind == LinkedNodeKind.functionTypedFormalParameter) {
-// _functionTypedFormalParameter(node);
-// } else if (kind == LinkedNodeKind.genericFunctionType) {
-// node.genericFunctionType_returnType2 = _getType(
-// node.genericFunctionType_returnType,
-// );
-// } else if (kind == LinkedNodeKind.methodDeclaration) {
-// node.methodDeclaration_returnType2 = _getType(
-// node.methodDeclaration_returnType,
-// );
-// } else if (kind == LinkedNodeKind.simpleFormalParameter) {
-// node.simpleFormalParameter_type2 = _getType(
-// node.simpleFormalParameter_type,
-// );
-// } else if (kind == LinkedNodeKind.variableDeclarationList) {
-// var typeNode = node.variableDeclarationList_type;
-// for (var variable in node.variableDeclarationList_variables) {
-// variable.variableDeclaration_type2 = _getType(typeNode);
-// }
-// } else {
-// throw UnimplementedError('$kind');
-// }
- }
-
-// int _typeParametersLength(Reference reference) {
-// var node = bundleContext.elementFactory.nodeOfReference(reference);
-// return LinkedUnitContext.getTypeParameters(node)?.length ?? 0;
-// }
-
- static int typeNameElementIndex(LinkedNode name) {
- if (name.kind == LinkedNodeKind.simpleIdentifier) {
- return name.simpleIdentifier_element;
- } else {
- var identifier = name.prefixedIdentifier_identifier;
- return identifier.simpleIdentifier_element;
- }
}
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 2eb6848..99b8730 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -196,12 +196,6 @@
@override
@failingTest
- test_class_notSimplyBounded_complex_by_cycle() async {
- await super.test_class_notSimplyBounded_complex_by_cycle();
- }
-
- @override
- @failingTest
test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type() async {
await super
.test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type();
@@ -209,12 +203,6 @@
@override
@failingTest
- test_class_notSimplyBounded_refers_to_circular_typedef() async {
- await super.test_class_notSimplyBounded_refers_to_circular_typedef();
- }
-
- @override
- @failingTest
test_class_type_parameters_bound() async {
await super.test_class_type_parameters_bound();
}
@@ -444,42 +432,12 @@
@override
@failingTest
- test_instantiateToBounds_boundRefersToEarlierTypeArgument() async {
- await super.test_instantiateToBounds_boundRefersToEarlierTypeArgument();
- }
-
- @override
- @failingTest
- test_instantiateToBounds_boundRefersToItself() async {
- await super.test_instantiateToBounds_boundRefersToItself();
- }
-
- @override
- @failingTest
- test_instantiateToBounds_boundRefersToLaterTypeArgument() async {
- await super.test_instantiateToBounds_boundRefersToLaterTypeArgument();
- }
-
- @override
- @failingTest
test_instantiateToBounds_functionTypeAlias_reexported() async {
await super.test_instantiateToBounds_functionTypeAlias_reexported();
}
@override
@failingTest
- test_instantiateToBounds_functionTypeAlias_simple() async {
- await super.test_instantiateToBounds_functionTypeAlias_simple();
- }
-
- @override
- @failingTest
- test_instantiateToBounds_simple() async {
- await super.test_instantiateToBounds_simple();
- }
-
- @override
- @failingTest
test_invalidUri_part_emptyUri() async {
await super.test_invalidUri_part_emptyUri();
}
@@ -578,13 +536,6 @@
@override
@failingTest
- test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included() async {
- await super
- .test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included();
- }
-
- @override
- @failingTest
test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted() async {
await super
.test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted();
@@ -592,27 +543,6 @@
@override
@failingTest
- test_typedef_notSimplyBounded_dependency_via_param_type_old_style() async {
- await super
- .test_typedef_notSimplyBounded_dependency_via_param_type_old_style();
- }
-
- @override
- @failingTest
- test_typedef_notSimplyBounded_dependency_via_return_type_new_style() async {
- await super
- .test_typedef_notSimplyBounded_dependency_via_return_type_new_style();
- }
-
- @override
- @failingTest
- test_typedef_notSimplyBounded_dependency_via_return_type_old_style() async {
- await super
- .test_typedef_notSimplyBounded_dependency_via_return_type_old_style();
- }
-
- @override
- @failingTest
test_typedef_type_parameters_bound() async {
await super.test_typedef_type_parameters_bound();
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 0bc59334..315fd79 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1247,11 +1247,19 @@
class C<T extends F> {}
typedef F(C value);
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = dynamic Function(C<(C<dynamic>) → dynamic> value);
+notSimplyBounded class C<T extends (C<dynamic>) → dynamic> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = dynamic Function(C<dynamic> value);
notSimplyBounded class C<T extends (C<dynamic>) → dynamic> {
}
''');
+ }
}
test_class_notSimplyBounded_circularity_with_type_params() async {
@@ -1359,12 +1367,21 @@
typedef F(G value);
typedef G(F value);
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = dynamic Function(((dynamic) → dynamic) → dynamic value);
+notSimplyBounded typedef G = dynamic Function(((dynamic) → dynamic) → dynamic value);
+notSimplyBounded class C<T extends ((dynamic) → dynamic) → dynamic> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = dynamic Function(((...) → dynamic) → dynamic value);
notSimplyBounded typedef G = dynamic Function(((...) → dynamic) → dynamic value);
notSimplyBounded class C<T extends ((...) → dynamic) → dynamic> {
}
''');
+ }
}
test_class_notSimplyBounded_self() async {
@@ -9244,11 +9261,19 @@
typedef F = void Function(C c);
class C<T extends C<T>> {}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = void Function(C<dynamic> c);
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = void Function(C<C<dynamic>> c);
notSimplyBounded class C<T extends C<T>> {
}
''');
+ }
}
test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted() async {
@@ -9258,11 +9283,19 @@
typedef F = void Function(C);
class C<T extends C<T>> {}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = void Function(C<dynamic> );
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = void Function(C<C<dynamic>> );
notSimplyBounded class C<T extends C<T>> {
}
''');
+ }
}
test_typedef_notSimplyBounded_dependency_via_param_type_old_style() async {
@@ -9272,11 +9305,19 @@
typedef void F(C c);
class C<T extends C<T>> {}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = void Function(C<dynamic> c);
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = void Function(C<C<dynamic>> c);
notSimplyBounded class C<T extends C<T>> {
}
''');
+ }
}
test_typedef_notSimplyBounded_dependency_via_return_type_new_style() async {
@@ -9286,11 +9327,19 @@
typedef F = C Function();
class C<T extends C<T>> {}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = C<dynamic> Function();
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = C<C<dynamic>> Function();
notSimplyBounded class C<T extends C<T>> {
}
''');
+ }
}
test_typedef_notSimplyBounded_dependency_via_return_type_old_style() async {
@@ -9300,11 +9349,19 @@
typedef C F();
class C<T extends C<T>> {}
''');
- checkElementText(library, r'''
+ if (isAstBasedSummary) {
+ checkElementText(library, r'''
+notSimplyBounded typedef F = C<dynamic> Function();
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+ } else {
+ checkElementText(library, r'''
notSimplyBounded typedef F = C<C<dynamic>> Function();
notSimplyBounded class C<T extends C<T>> {
}
''');
+ }
}
test_typedef_parameter_parameters() async {