Version 2.16.0-153.0.dev
Merge commit 'd48e475956c6b0ee0e5e4dae6eee98dfbf729391' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
index 2441362..4d4da53 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -46,7 +46,7 @@
@override
void visitClassElement(ClassElement element) {
if (opType.includeTypeNameSuggestions) {
- builder.suggestClass(element, kind: kind, prefix: prefix);
+ builder.suggestClass(element, prefix: prefix);
}
if (opType.includeConstructorSuggestions) {
_addConstructorSuggestions(element);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
index ca8280c..1e16887 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -213,7 +213,7 @@
var classElt = declaration.declaredElement;
if (classElt != null && visibilityTracker._isVisible(classElt)) {
if (opType.includeTypeNameSuggestions) {
- builder.suggestClass(classElt, kind: _defaultKind);
+ builder.suggestClass(classElt);
}
// Generate the suggestions for the constructors. We are required to loop
@@ -234,7 +234,7 @@
void declaredClassTypeAlias(ClassTypeAlias declaration) {
var declaredElement = declaration.declaredElement;
if (declaredElement != null && opType.includeTypeNameSuggestions) {
- builder.suggestClass(declaredElement, kind: _defaultKind);
+ builder.suggestClass(declaredElement);
}
}
@@ -249,7 +249,7 @@
if (declaredElement != null &&
visibilityTracker._isVisible(declaredElement) &&
opType.includeTypeNameSuggestions) {
- builder.suggestClass(declaredElement, kind: _defaultKind);
+ builder.suggestClass(declaredElement);
for (var enumConstant in declaration.constants) {
if (!enumConstant.isSynthetic) {
var constantElement = enumConstant.declaredElement;
@@ -385,7 +385,7 @@
declaredElement != null &&
visibilityTracker._isVisible(declaredElement) &&
opType.includeTypeNameSuggestions) {
- builder.suggestClass(declaredElement, kind: _defaultKind);
+ builder.suggestClass(declaredElement);
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 0e7d181..a606391 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -295,16 +295,19 @@
elementKind: protocol.ElementKind.PARAMETER, relevance: relevance));
}
- /// Add a suggestion for a [classElement]. If a [kind] is provided it will
- /// be used as the kind for the suggestion. If the class can only be
+ /// Add a suggestion for a [classElement]. If the class can only be
/// referenced using a prefix, then the [prefix] should be provided.
- void suggestClass(ClassElement classElement,
- {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
- String? prefix}) {
+ void suggestClass(ClassElement classElement, {String? prefix}) {
var relevance = _computeTopLevelRelevance(classElement,
elementType: _instantiateClassElement(classElement));
- _add(_createSuggestion(classElement,
- kind: kind, prefix: prefix, relevance: relevance));
+ _add(
+ _createSuggestion(
+ classElement,
+ kind: CompletionSuggestionKind.IDENTIFIER,
+ prefix: prefix,
+ relevance: relevance,
+ ),
+ );
}
/// Add a suggestion to insert a closure matching the given function [type].
@@ -412,7 +415,7 @@
void suggestElement(Element element,
{CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
if (element is ClassElement) {
- suggestClass(element, kind: kind);
+ suggestClass(element);
} else if (element is ConstructorElement) {
suggestConstructor(element, kind: kind);
} else if (element is ExtensionElement) {
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 2a94276..b73ad91 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -1872,9 +1872,9 @@
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'Object',
elementKind: ElementKind.CLASS);
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'HtmlElement',
elementKind: ElementKind.CLASS);
assertNoResult('test');
});
@@ -2023,7 +2023,7 @@
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'Object',
elementKind: ElementKind.CLASS);
assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
assertNoResult('HtmlElement');
@@ -2039,7 +2039,7 @@
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'HtmlElement');
assertNoResult('test');
});
}
@@ -2258,7 +2258,7 @@
expect(replacementLength, equals(0));
// The class is suggested.
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'A',
elementKind: ElementKind.CLASS);
// Both constructors - default and named, are suggested.
@@ -2324,12 +2324,12 @@
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'A',
elementKind: ElementKind.CLASS);
assertHasResult(CompletionSuggestionKind.INVOCATION, 'a');
assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
assertHasResult(CompletionSuggestionKind.INVOCATION, 'x');
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'DateTime',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'DateTime',
elementKind: ElementKind.CLASS);
});
}
@@ -2369,11 +2369,11 @@
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'Object',
elementKind: ElementKind.CLASS);
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'HtmlElement',
elementKind: ElementKind.CLASS);
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'A',
elementKind: ElementKind.CLASS);
assertNoResult('test');
});
@@ -2392,11 +2392,11 @@
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'Object',
elementKind: ElementKind.CLASS);
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'HtmlElement',
elementKind: ElementKind.CLASS);
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'A',
elementKind: ElementKind.CLASS);
assertNoResult('test');
});
@@ -2432,7 +2432,7 @@
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
+ assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'Object',
elementKind: ElementKind.CLASS);
assertNoResult('HtmlElement');
assertNoResult('test');
@@ -2653,7 +2653,7 @@
});
void assertClass() {
- expect(suggestion.kind, CompletionSuggestionKind.INVOCATION);
+ expect(suggestion.kind, CompletionSuggestionKind.IDENTIFIER);
expect(suggestion.element?.kind, ElementKind.CLASS);
}
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 0485895..7b202bf 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -118,30 +118,34 @@
}
void assertCoreTypeSuggestions() {
- assertSuggest('Comparable');
- assertSuggest('Comparator');
- assertSuggest('DateTime');
- assertSuggest('Deprecated');
- assertSuggest('Duration');
- assertSuggest('Error');
- assertSuggest('Exception');
- assertSuggest('FormatException');
- assertSuggest('Function');
- assertSuggest('Future');
- assertSuggest('Invocation');
- assertSuggest('Iterable');
- assertSuggest('Iterator');
- assertSuggest('List');
- assertSuggest('Map');
- assertSuggest('MapEntry');
- assertSuggest('Null');
- assertSuggest('Object');
- assertSuggest('Pattern');
- assertSuggest('RegExp');
- assertSuggest('Set');
- assertSuggest('StackTrace');
- assertSuggest('Stream');
- assertSuggest('String');
+ assertSuggestClass('Comparable');
+ assertSuggestTypeAlias(
+ 'Comparator',
+ aliasedType: 'int Function(T, T)',
+ returnType: 'int',
+ );
+ assertSuggestClass('DateTime');
+ assertSuggestClass('Deprecated');
+ assertSuggestClass('Duration');
+ assertSuggestClass('Error');
+ assertSuggestClass('Exception');
+ assertSuggestClass('FormatException');
+ assertSuggestClass('Function');
+ assertSuggestClass('Future');
+ assertSuggestClass('Invocation');
+ assertSuggestClass('Iterable');
+ assertSuggestClass('Iterator');
+ assertSuggestClass('List');
+ assertSuggestClass('Map');
+ assertSuggestClass('MapEntry');
+ assertSuggestClass('Null');
+ assertSuggestClass('Object');
+ assertSuggestClass('Pattern');
+ assertSuggestClass('RegExp');
+ assertSuggestClass('Set');
+ assertSuggestClass('StackTrace');
+ assertSuggestClass('Stream');
+ assertSuggestClass('String');
}
void assertHasNoParameterInfo(CompletionSuggestion suggestion) {
@@ -242,7 +246,7 @@
}
CompletionSuggestion assertSuggestClass(String name,
- {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
+ {CompletionSuggestionKind kind = CompletionSuggestionKind.IDENTIFIER,
bool isDeprecated = false,
String? elemFile,
String? elemName,
@@ -293,7 +297,11 @@
CompletionSuggestion assertSuggestEnum(String completion,
{bool isDeprecated = false}) {
- var suggestion = assertSuggest(completion, isDeprecated: isDeprecated);
+ var suggestion = assertSuggest(
+ completion,
+ isDeprecated: isDeprecated,
+ csKind: CompletionSuggestionKind.IDENTIFIER,
+ );
expect(suggestion.isDeprecated, isDeprecated);
expect(suggestion.element!.kind, ElementKind.ENUM);
return suggestion;
@@ -412,7 +420,7 @@
}
CompletionSuggestion assertSuggestMixin(String name,
- {CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
+ {CompletionSuggestionKind kind = CompletionSuggestionKind.IDENTIFIER,
bool isDeprecated = false,
String? elemFile,
String? elemName,
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 804bc3a..1378b11 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -773,7 +773,7 @@
expect(replacementLength, 0);
assertSuggest('a', elemKind: ElementKind.METHOD);
assertSuggest('foo', elemKind: ElementKind.METHOD);
- assertSuggest('B', elemKind: ElementKind.CLASS);
+ assertSuggestClass('B');
assertNotSuggested('A');
assertNotSuggested('Object');
assertSuggestMethod('y', 'A', 'Future<dynamic>');
@@ -3638,7 +3638,7 @@
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
assertNotSuggested('Object');
- assertSuggest('B', elemKind: ElementKind.CLASS);
+ assertSuggestClass('B');
assertSuggestField('a', 'int');
assertSuggestMethod('b', 'B', 'int');
assertSuggestMethod('foo', 'B', 'dynamic');
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index a3ae779..61dc1e9 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -247,7 +247,6 @@
CompileTimeErrorCode.INVALID_CAST_METHOD,
CompileTimeErrorCode.INVALID_CAST_NEW_EXPR,
CompileTimeErrorCode.INVALID_CONSTANT,
- CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME,
CompileTimeErrorCode.INVALID_EXTENSION_ARGUMENT_COUNT,
CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS,
CompileTimeErrorCode.INVALID_IMPLEMENTATION_OVERRIDE,
diff --git a/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
index 1f9befa..01d2337 100644
--- a/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
@@ -180,21 +180,15 @@
!identical(element, enclosingClass)) {
// This error is now reported by the parser.
element = null;
- } else if ((element is PrefixElement?) &&
- (element == null || !_isValidAsPrefix(node))) {
+ } else if (element is PrefixElement && !_isValidAsPrefix(node)) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
+ node,
+ [element.name],
+ );
+ } else if (element == null) {
// TODO(brianwilkerson) Recover from this error.
- if (_isConstructorReturnType(node)) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node);
- } else if (parent is Annotation) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.UNDEFINED_ANNOTATION, parent, [node.name]);
- } else if (element != null) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
- node,
- [element.name]);
- } else if (node.name == "await" && _resolver.enclosingFunction != null) {
+ if (node.name == "await" && _resolver.enclosingFunction != null) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNDEFINED_IDENTIFIER_AWAIT,
node,
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index 5f42ff2..0c25625 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -7045,16 +7045,6 @@
);
/**
- * 7.6 Constructors: It is a compile-time error if the name of a constructor
- * is not a constructor name.
- */
- static const CompileTimeErrorCode INVALID_CONSTRUCTOR_NAME =
- CompileTimeErrorCode(
- 'INVALID_CONSTRUCTOR_NAME',
- "Invalid constructor name.",
- );
-
- /**
* No parameters.
*/
// #### Description
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 0f6e2fe..8e60369 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -6098,11 +6098,6 @@
for more informative errors.
See TODOs in ConstantVisitor
- INVALID_CONSTRUCTOR_NAME:
- problemMessage: Invalid constructor name.
- comment: |-
- 7.6 Constructors: It is a compile-time error if the name of a constructor
- is not a constructor name.
INVALID_EXTENSION_ARGUMENT_COUNT:
problemMessage: "Extension overrides must have exactly one argument: the value of 'this' in the extension method."
correctionMessage: Try specifying exactly one argument.
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index 145865a..b1e3ed3 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -2,32 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/analysis/session.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/scope.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/src/dart/ast/extensions.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
-import 'package:analyzer/src/generated/resolver.dart' show ResolverVisitor;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
-import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/source/source_resource.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'elements_types_mixin.dart';
-import 'test_analysis_context.dart';
-import 'test_support.dart';
+import '../src/dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -35,155 +15,118 @@
});
}
-/// Wrapper around the test package's `fail` function.
-///
-/// Unlike the test package's `fail` function, this function is not annotated
-/// with @alwaysThrows, so we can call it at the top of a test method without
-/// causing the rest of the method to be flagged as dead code.
-void _fail(String message) {
- fail(message);
-}
-
@reflectiveTest
-class StaticTypeAnalyzerTest with ResourceProviderMixin, ElementsTypesMixin {
- /// The error listener to which errors will be reported.
- late final GatheringErrorListener _listener;
-
- /// The resolver visitor used to create the analyzer.
- late final ResolverVisitor _visitor;
-
- /// The library containing the code being resolved.
- late final LibraryElementImpl _definingLibrary;
-
- /// The compilation unit containing the code being resolved.
- late CompilationUnitElementImpl _definingCompilationUnit;
-
- /// The type provider used to access the types.
- late final TypeProvider _typeProvider;
-
- @override
- TypeProvider get typeProvider => _definingLibrary.typeProvider;
-
- /// The type system used to analyze the test cases.
- TypeSystemImpl get _typeSystem => _definingLibrary.typeSystem;
-
- void fail_visitFunctionExpressionInvocation() {
- _fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- void fail_visitMethodInvocation() {
- _fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- void fail_visitSimpleIdentifier() {
- _fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- void setUp() {
- _listener = GatheringErrorListener();
- _createAnalyzer();
- }
-
- @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/44522')
- void test_flatten_derived() {
+class StaticTypeAnalyzerTest extends PubPackageResolutionTest {
+ test_flatten_derived() async {
+ await assertNoErrorsInCode('''
+abstract class Derived<T> extends Future<T> {
+ factory Derived() => throw 'foo';
+}
+late Derived<dynamic> derivedDynamic;
+late Derived<int> derivedInt;
+late Derived<Derived> derivedDerived;
+late Derived<Derived<int>> derivedDerivedInt;
+ ''');
+ var dynamicType = typeProvider.dynamicType;
+ var derivedDynamicType = findElement.topVar('derivedDynamic').type;
+ var derivedIntType = findElement.topVar('derivedInt').type;
+ var derivedDerivedType = findElement.topVar('derivedDerived').type;
+ var derivedDerivedIntType = findElement.topVar('derivedDerivedInt').type;
// class Derived<T> extends Future<T> { ... }
- ClassElementImpl derivedClass =
- ElementFactory.classElement2('Derived', ['T']);
- derivedClass.supertype =
- futureType(typeParameterTypeStar(derivedClass.typeParameters[0]));
- InterfaceType intType = _typeProvider.intType;
- DartType dynamicType = _typeProvider.dynamicType;
- InterfaceType derivedIntType =
- interfaceTypeStar(derivedClass, typeArguments: [intType]);
// flatten(Derived) = dynamic
- InterfaceType derivedDynamicType =
- interfaceTypeStar(derivedClass, typeArguments: [dynamicType]);
expect(_flatten(derivedDynamicType), dynamicType);
// flatten(Derived<int>) = int
expect(_flatten(derivedIntType), intType);
// flatten(Derived<Derived>) = Derived
- expect(
- _flatten(interfaceTypeStar(derivedClass,
- typeArguments: [derivedDynamicType])),
- derivedDynamicType);
+ expect(_flatten(derivedDerivedType), derivedDynamicType);
// flatten(Derived<Derived<int>>) = Derived<int>
- expect(
- _flatten(
- interfaceTypeStar(derivedClass, typeArguments: [derivedIntType])),
- derivedIntType);
+ expect(_flatten(derivedDerivedIntType), derivedIntType);
}
- @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/44522')
- void test_flatten_inhibit_recursion() {
- // class A extends B
- // class B extends A
- ClassElementImpl classA = ElementFactory.classElement2('A', []);
- ClassElementImpl classB = ElementFactory.classElement2('B', []);
- classA.supertype = interfaceTypeStar(classB);
- classB.supertype = interfaceTypeStar(classA);
+ test_flatten_inhibit_recursion() async {
+ await assertErrorsInCode('''
+class A extends B {}
+class B extends A {}
+late A a;
+late B b;
+''', [
+ error(CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, 6, 1),
+ error(CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, 27, 1),
+ ]);
+ var aType = findElement.topVar('a').type;
+ var bType = findElement.topVar('b').type;
// flatten(A) = A and flatten(B) = B, since neither class contains Future
// in its class hierarchy. Even though there is a loop in the class
// hierarchy, flatten() should terminate.
- expect(_flatten(interfaceTypeStar(classA)), interfaceTypeStar(classA));
- expect(_flatten(interfaceTypeStar(classB)), interfaceTypeStar(classB));
+ expect(_flatten(aType), aType);
+ expect(_flatten(bType), bType);
}
- @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/44522')
- void test_flatten_related_derived_types() {
- InterfaceType intType = _typeProvider.intType;
- InterfaceType numType = _typeProvider.numType;
- // class Derived<T> extends Future<T>
- ClassElementImpl derivedClass =
- ElementFactory.classElement2('Derived', ['T']);
- derivedClass.supertype =
- futureType(typeParameterTypeStar(derivedClass.typeParameters[0]));
- // class A extends Derived<int> implements Derived<num> { ... }
- ClassElementImpl classA = ElementFactory.classElement(
- 'A', interfaceTypeStar(derivedClass, typeArguments: [intType]));
- classA.interfaces = <InterfaceType>[
- interfaceTypeStar(derivedClass, typeArguments: [numType]),
- ];
- // class B extends Future<num> implements Future<int> { ... }
- ClassElementImpl classB = ElementFactory.classElement(
- 'B', interfaceTypeStar(derivedClass, typeArguments: [numType]));
- classB.interfaces = <InterfaceType>[
- interfaceTypeStar(derivedClass, typeArguments: [intType])
- ];
- // flatten(A) = flatten(B) = int, since int is more specific than num.
+ test_flatten_related_derived_types() async {
+ await assertErrorsInCode('''
+abstract class Derived<T> extends Future<T> {
+ factory Derived() => throw 'foo';
+}
+abstract class A extends Derived<int> implements Derived<num> {
+ factory A() => throw 'foo';
+}
+abstract class B extends Future<num> implements Future<int> {
+ factory B() => throw 'foo';
+}
+late A a;
+late B b;
+''', [
+ error(CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES, 99, 1),
+ error(CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES, 99, 1),
+ error(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, 133, 12),
+ error(CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES, 195, 1),
+ error(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, 228, 11),
+ ]);
+ InterfaceType intType = typeProvider.intType;
+ InterfaceType numType = typeProvider.numType;
+ var aType = findElement.topVar('a').type;
+ var bType = findElement.topVar('b').type;
// The code in flatten() that inhibits infinite recursion shouldn't be
// fooled by the fact that Derived appears twice in the type hierarchy.
- expect(_flatten(interfaceTypeStar(classA)), intType);
- expect(_flatten(interfaceTypeStar(classB)), intType);
+ expect(_flatten(aType), intType);
+ expect(_flatten(bType), numType);
}
- @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/44522')
- void test_flatten_related_types() {
- InterfaceType intType = _typeProvider.intType;
- InterfaceType numType = _typeProvider.numType;
- // class A extends Future<int> implements Future<num> { ... }
- ClassElementImpl classA =
- ElementFactory.classElement('A', _typeProvider.futureType(intType));
- classA.interfaces = <InterfaceType>[_typeProvider.futureType(numType)];
- // class B extends Future<num> implements Future<int> { ... }
- ClassElementImpl classB =
- ElementFactory.classElement('B', _typeProvider.futureType(numType));
- classB.interfaces = <InterfaceType>[_typeProvider.futureType(intType)];
- // flatten(A) = flatten(B) = int, since int is more specific than num.
- expect(_flatten(interfaceTypeStar(classA)), intType);
- expect(_flatten(interfaceTypeStar(classB)), intType);
+ test_flatten_related_types() async {
+ await assertErrorsInCode('''
+abstract class A extends Future<int> implements Future<num> {
+ factory A() => throw 'foo';
+}
+abstract class B extends Future<num> implements Future<int> {
+ factory B() => throw 'foo';
+}
+late A a;
+late B b;
+''', [
+ error(CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES, 15, 1),
+ error(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, 48, 11),
+ error(CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES, 109, 1),
+ error(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, 142, 11),
+ ]);
+ InterfaceType intType = typeProvider.intType;
+ InterfaceType numType = typeProvider.numType;
+ var aType = findElement.topVar('a').type;
+ var bType = findElement.topVar('b').type;
+ expect(_flatten(aType), intType);
+ expect(_flatten(bType), numType);
}
- void test_flatten_simple() {
- InterfaceType intType = _typeProvider.intType;
- DartType dynamicType = _typeProvider.dynamicType;
- InterfaceType futureDynamicType = _typeProvider.futureDynamicType;
- InterfaceType futureIntType = _typeProvider.futureType(intType);
+ test_flatten_simple() async {
+ // No code needs to be analyzed but we still need to call
+ // assertNoErrorsInCode to get the typeProvider initialized.
+ await assertNoErrorsInCode('');
+ InterfaceType intType = typeProvider.intType;
+ DartType dynamicType = typeProvider.dynamicType;
+ InterfaceType futureDynamicType = typeProvider.futureDynamicType;
+ InterfaceType futureIntType = typeProvider.futureType(intType);
InterfaceType futureFutureDynamicType =
- _typeProvider.futureType(futureDynamicType);
- InterfaceType futureFutureIntType = _typeProvider.futureType(futureIntType);
+ typeProvider.futureType(futureDynamicType);
+ InterfaceType futureFutureIntType = typeProvider.futureType(futureIntType);
// flatten(int) = int
expect(_flatten(intType), intType);
// flatten(dynamic) = dynamic
@@ -198,391 +141,269 @@
expect(_flatten(futureFutureIntType), futureIntType);
}
- @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/44522')
- void test_flatten_unrelated_types() {
- InterfaceType intType = _typeProvider.intType;
- InterfaceType stringType = _typeProvider.stringType;
- // class A extends Future<int> implements Future<String> { ... }
- ClassElementImpl classA =
- ElementFactory.classElement('A', _typeProvider.futureType(intType));
- classA.interfaces = <InterfaceType>[_typeProvider.futureType(stringType)];
- // class B extends Future<String> implements Future<int> { ... }
- ClassElementImpl classB =
- ElementFactory.classElement('B', _typeProvider.futureType(stringType));
- classB.interfaces = <InterfaceType>[_typeProvider.futureType(intType)];
+ test_flatten_unrelated_types() async {
+ await assertErrorsInCode('''
+abstract class A extends Future<int> implements Future<String> {
+ factory A() => throw 'foo';
+}
+abstract class B extends Future<String> implements Future<int> {
+ factory B() => throw 'foo';
+}
+late A a;
+late B b;
+''', [
+ error(CompileTimeErrorCode.INCONSISTENT_INHERITANCE, 15, 1),
+ error(CompileTimeErrorCode.INCONSISTENT_INHERITANCE, 15, 1),
+ error(CompileTimeErrorCode.INCONSISTENT_INHERITANCE, 15, 1),
+ error(CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES, 15, 1),
+ error(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, 48, 14),
+ error(CompileTimeErrorCode.INCONSISTENT_INHERITANCE, 112, 1),
+ error(CompileTimeErrorCode.INCONSISTENT_INHERITANCE, 112, 1),
+ error(CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES, 112, 1),
+ error(CompileTimeErrorCode.INCONSISTENT_INHERITANCE, 112, 1),
+ error(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, 148, 11),
+ ]);
+ var aType = findElement.topVar('a').type;
+ var bType = findElement.topVar('b').type;
// flatten(A) = A and flatten(B) = B, since neither string nor int is more
// specific than the other.
- expect(_flatten(interfaceTypeStar(classA)), interfaceTypeStar(classA));
- expect(_flatten(interfaceTypeStar(classB)), interfaceTypeStar(classB));
+ expect(_flatten(aType), intType);
+ expect(_flatten(bType), stringType);
}
- void test_visitAdjacentStrings() {
- // "a" "b"
- Expression node = AstTestFactory.adjacentStrings(
- [_resolvedString("a"), _resolvedString("b")]);
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
+ test_visitAdjacentStrings() async {
+ await assertNoErrorsInCode('''
+test() => 'a' 'b';
+''');
+ expect(findNode.adjacentStrings("'a' 'b'").staticType,
+ same(typeProvider.stringType));
}
- void test_visitAsExpression() {
- // class A { ... this as B ... }
- // class B extends A {}
- ClassElement superclass = ElementFactory.classElement2("A");
- InterfaceType superclassType = interfaceTypeStar(superclass);
- ClassElement subclass = ElementFactory.classElement("B", superclassType);
- Expression node = AstTestFactory.asExpression(
- AstTestFactory.thisExpression(), AstTestFactory.namedType(subclass));
- expect(_analyze(node, superclassType), interfaceTypeStar(subclass));
- _listener.assertNoErrors();
+ test_visitAsExpression() async {
+ await assertNoErrorsInCode('''
+class A {
+ test() => this as B;
+}
+class B extends A {}
+late B b;
+''');
+ var bType = findElement.topVar('b').type;
+ expect(findNode.as_('this as B').staticType, bType);
}
- void test_visitAwaitExpression_flattened() {
- // await e, where e has type Future<Future<int>>
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType = _typeProvider.futureType(intType);
- InterfaceType futureFutureIntType = _typeProvider.futureType(futureIntType);
- Expression node = AstTestFactory.awaitExpression(
- _resolvedVariable(futureFutureIntType, 'e'));
- expect(_analyze(node), same(futureIntType));
- _listener.assertNoErrors();
+ test_visitAwaitExpression_flattened() async {
+ await assertNoErrorsInCode('''
+test(Future<Future<int>> e) async => await e;
+''');
+ InterfaceType futureIntType = typeProvider.futureType(typeProvider.intType);
+ expect(findNode.awaitExpression('await e').staticType, futureIntType);
}
- void test_visitAwaitExpression_simple() {
+ test_visitAwaitExpression_simple() async {
+ await assertNoErrorsInCode('''
+test(Future<int> e) async => await e;
+''');
// await e, where e has type Future<int>
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType = _typeProvider.futureType(intType);
- Expression node =
- AstTestFactory.awaitExpression(_resolvedVariable(futureIntType, 'e'));
- expect(_analyze(node), same(intType));
- _listener.assertNoErrors();
+ InterfaceType intType = typeProvider.intType;
+ expect(findNode.awaitExpression('await e').staticType, intType);
}
- void test_visitBooleanLiteral_false() {
- // false
- Expression node = AstTestFactory.booleanLiteral(false);
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
+ test_visitBooleanLiteral_false() async {
+ await assertNoErrorsInCode('''
+test() => false;
+''');
+ expect(findNode.booleanLiteral('false').staticType,
+ same(typeProvider.boolType));
}
- void test_visitBooleanLiteral_true() {
- // true
- Expression node = AstTestFactory.booleanLiteral(true);
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
+ test_visitBooleanLiteral_true() async {
+ await assertNoErrorsInCode('''
+test() => true;
+''');
+ expect(findNode.booleanLiteral('true').staticType,
+ same(typeProvider.boolType));
}
- void test_visitCascadeExpression() {
- // a..length
- Expression node = AstTestFactory.cascadeExpression(_resolvedString("a"), [
- AstTestFactory.propertyAccess2(null, "length", TokenType.PERIOD_PERIOD)
- ]);
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
+ test_visitCascadeExpression() async {
+ await assertNoErrorsInCode('''
+test(String a) => a..length;
+''');
+ expect(findNode.cascade('a..length').staticType, typeProvider.stringType);
}
- void test_visitConditionalExpression_differentTypes() {
- // true ? 1.0 : 0
- Expression node = AstTestFactory.conditionalExpression(
- AstTestFactory.booleanLiteral(true),
- _resolvedDouble(1.0),
- _resolvedInteger(0));
- expect(_analyze(node), _typeProvider.numType);
- _listener.assertNoErrors();
+ test_visitConditionalExpression_differentTypes() async {
+ await assertNoErrorsInCode('''
+test(bool b) => b ? 1.0 : 0;
+''');
+ expect(findNode.conditionalExpression('b ? 1.0 : 0').staticType,
+ typeProvider.numType);
}
- void test_visitConditionalExpression_sameTypes() {
- // true ? 1 : 0
- Expression node = AstTestFactory.conditionalExpression(
- AstTestFactory.booleanLiteral(true),
- _resolvedInteger(1),
- _resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
+ test_visitConditionalExpression_sameTypes() async {
+ await assertNoErrorsInCode('''
+test(bool b) => b ? 1 : 0;
+''');
+ expect(findNode.conditionalExpression('b ? 1 : 0').staticType,
+ same(typeProvider.intType));
}
- void test_visitDoubleLiteral() {
- // 4.33
- Expression node = AstTestFactory.doubleLiteral(4.33);
- expect(_analyze(node), same(_typeProvider.doubleType));
- _listener.assertNoErrors();
+ test_visitDoubleLiteral() async {
+ await assertNoErrorsInCode('''
+test() => 4.33;
+''');
+ expect(findNode.doubleLiteral('4.33').staticType,
+ same(typeProvider.doubleType));
}
- void test_visitInstanceCreationExpression_named() {
- // new C.m()
- ClassElementImpl classElement = ElementFactory.classElement2("C");
- _definingCompilationUnit.classes = [classElement];
- String constructorName = "m";
- ConstructorElementImpl constructor =
- ElementFactory.constructorElement2(classElement, constructorName);
- classElement.constructors = <ConstructorElement>[constructor];
- InstanceCreationExpression node =
- AstTestFactory.instanceCreationExpression2(
- null, AstTestFactory.namedType(classElement), [
- AstTestFactory.identifier3(constructorName)
- ..scopeLookupResult = ScopeLookupResult(constructor, null)
- ]);
- expect(_analyze(node), interfaceTypeStar(classElement));
- _listener.assertNoErrors();
+ test_visitInstanceCreationExpression_named() async {
+ await assertNoErrorsInCode('''
+class C {
+ C.m();
+}
+test() => new C.m();
+late C c;
+''');
+ var cType = findElement.topVar('c').type;
+ expect(findNode.instanceCreation('new C.m()').staticType, cType);
}
- void test_visitInstanceCreationExpression_typeParameters() {
- // new C<I>()
- ClassElementImpl elementC = ElementFactory.classElement2("C", ["E"]);
- ClassElementImpl elementI = ElementFactory.classElement2("I");
- ConstructorElementImpl constructor =
- ElementFactory.constructorElement2(elementC, null);
- elementC.constructors = <ConstructorElement>[constructor];
- var typeName = AstTestFactory.namedType(
- elementC, [AstTestFactory.namedType(elementI)]);
- typeName.type = interfaceTypeStar(elementC,
- typeArguments: [interfaceTypeStar(elementI)]);
- InstanceCreationExpression node =
- AstTestFactory.instanceCreationExpression2(null, typeName);
- _definingCompilationUnit.classes = [elementC, elementI];
- InterfaceType type = _analyze(node) as InterfaceType;
+ test_visitInstanceCreationExpression_typeParameters() async {
+ await assertNoErrorsInCode('''
+class C<E> {}
+class I {}
+test() => new C<I>();
+late I i;
+''');
+ var iType = findElement.topVar('i').type;
+ InterfaceType type =
+ findNode.instanceCreation('new C<I>()').staticType as InterfaceType;
List<DartType> typeArgs = type.typeArguments;
expect(typeArgs.length, 1);
- expect(typeArgs[0], interfaceTypeStar(elementI));
- _listener.assertNoErrors();
+ expect(typeArgs[0], iType);
}
- void test_visitInstanceCreationExpression_unnamed() {
- // new C()
- ClassElementImpl classElement = ElementFactory.classElement2("C");
- _definingCompilationUnit.classes = [classElement];
- ConstructorElementImpl constructor =
- ElementFactory.constructorElement2(classElement, null);
- classElement.constructors = <ConstructorElement>[constructor];
- InstanceCreationExpression node =
- AstTestFactory.instanceCreationExpression2(
- null, AstTestFactory.namedType(classElement));
- expect(_analyze(node), interfaceTypeStar(classElement));
- _listener.assertNoErrors();
+ test_visitInstanceCreationExpression_unnamed() async {
+ await assertNoErrorsInCode('''
+class C {}
+test() => new C();
+late C c;
+''');
+ var cType = findElement.topVar('c').type;
+ expect(findNode.instanceCreation('new C()').staticType, cType);
}
- void test_visitIntegerLiteral() {
- // 42
- Expression node = _resolvedInteger(42);
- AstTestFactory.argumentList([node]);
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
+ test_visitIntegerLiteral() async {
+ await assertNoErrorsInCode('''
+test() => 42;
+''');
+ var node = findNode.integerLiteral('42');
+ expect(node.staticType, same(typeProvider.intType));
}
- void test_visitIsExpression_negated() {
- // a is! String
- Expression node = AstTestFactory.isExpression(
- _resolvedString("a"), true, AstTestFactory.namedType4("String"));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
+ test_visitIsExpression_negated() async {
+ await assertNoErrorsInCode('''
+test(Object a) => a is! String;
+''');
+ expect(findNode.isExpression('a is! String').staticType,
+ same(typeProvider.boolType));
}
- void test_visitIsExpression_notNegated() {
- // a is String
- Expression node = AstTestFactory.isExpression(
- _resolvedString("a"), false, AstTestFactory.namedType4("String"));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
+ test_visitIsExpression_notNegated() async {
+ await assertNoErrorsInCode('''
+test(Object a) => a is String;
+''');
+ expect(findNode.isExpression('a is String').staticType,
+ same(typeProvider.boolType));
}
- @FailingTest(reason: 'This is an old unit test, port and remove')
- void test_visitMethodInvocation_then() {
- // then()
- Expression node = AstTestFactory.methodInvocation(null, "then");
- _analyze(node);
- _listener.assertNoErrors();
+ test_visitMethodInvocation() async {
+ await assertNoErrorsInCode('''
+m() => 0;
+test() => m();
+''');
}
- void test_visitNamedExpression() {
- // n: a
- Expression node =
- AstTestFactory.namedExpression2("n", _resolvedString("a"));
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitNullLiteral() {
- // null
- Expression node = AstTestFactory.nullLiteral();
- expect(_analyze(node), same(_typeProvider.nullType));
- _listener.assertNoErrors();
- }
-
- void test_visitParenthesizedExpression() {
- // (0)
- Expression node =
- AstTestFactory.parenthesizedExpression(_resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleStringLiteral() {
- // "a"
- Expression node = _resolvedString("a");
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitStringInterpolation() {
- // "a${'b'}c"
- Expression node = AstTestFactory.string([
- AstTestFactory.interpolationString("a", "a"),
- AstTestFactory.interpolationExpression(_resolvedString("b")),
- AstTestFactory.interpolationString("c", "c")
- ]);
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitSuperExpression() {
- // super
- InterfaceType superType =
- interfaceTypeStar(ElementFactory.classElement2("A"));
- InterfaceType thisType =
- interfaceTypeStar(ElementFactory.classElement("B", superType));
- Expression node = AstTestFactory.superExpression();
- // Place the super expression inside a method declaration
- // (`test() => super.foo;`) so that we don't provoke a
- // SUPER_IN_INVALID_CONTEXT error
- AstTestFactory.methodDeclaration4(
- name: 'test',
- body: AstTestFactory.expressionFunctionBody(
- AstTestFactory.propertyAccess2(node, 'foo')));
- expect(_analyze(node, thisType), same(thisType));
- _listener.assertNoErrors();
- }
-
- void test_visitSymbolLiteral() {
- expect(_analyze(AstTestFactory.symbolLiteral(["a"])),
- same(_typeProvider.symbolType));
- }
-
- void test_visitThisExpression() {
- // this
- InterfaceType thisType = interfaceTypeStar(ElementFactory.classElement(
- "B", interfaceTypeStar(ElementFactory.classElement2("A"))));
- Expression node = AstTestFactory.thisExpression();
- expect(_analyze(node, thisType), same(thisType));
- _listener.assertNoErrors();
- }
-
- void test_visitThrowExpression_withValue() {
- // throw 0
- Expression node = AstTestFactory.throwExpression2(_resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.bottomType));
- _listener.assertNoErrors();
- }
-
- /// Return the type associated with the given [node] after the static type
- /// analyzer has computed a type for it. If [thisType] is provided, it is the
- /// type of 'this'.
- DartType _analyze(Expression node, [InterfaceType? thisType]) {
- if (thisType != null) {
- _visitor.setThisInterfaceType(thisType);
- }
- node.accept(_visitor);
- return node.typeOrThrow;
- }
-
- void _assertType(
- InterfaceTypeImpl expectedType, InterfaceTypeImpl actualType) {
+ test_visitNamedExpression() async {
+ await assertNoErrorsInCode('''
+test(dynamic d, String a) => d(n: a);
+''');
expect(
- actualType.getDisplayString(withNullability: false),
- expectedType.getDisplayString(withNullability: false),
- );
- expect(actualType.element, expectedType.element);
- List<DartType> expectedArguments = expectedType.typeArguments;
- int length = expectedArguments.length;
- List<DartType> actualArguments = actualType.typeArguments;
- expect(actualArguments, hasLength(length));
- for (int i = 0; i < length; i++) {
- _assertType2(expectedArguments[i], actualArguments[i]);
- }
+ findNode.namedExpression('n: a').staticType, typeProvider.stringType);
}
- void _assertType2(DartType expectedType, DartType actualType) {
- if (expectedType is InterfaceTypeImpl) {
- _assertType(expectedType, actualType as InterfaceTypeImpl);
- }
- // TODO(brianwilkerson) Compare other kinds of types then make this a shared
- // utility method.
+ test_visitNullLiteral() async {
+ await assertNoErrorsInCode('''
+test() => null;
+''');
+ expect(
+ findNode.nullLiteral('null').staticType, same(typeProvider.nullType));
}
- /// Create the analyzer used by the tests.
- void _createAnalyzer() {
- var context = TestAnalysisContext();
- var inheritance = InheritanceManager3();
- Source source = FileSource(getFile("/lib.dart"));
- _definingCompilationUnit = CompilationUnitElementImpl();
- _definingCompilationUnit.librarySource =
- _definingCompilationUnit.source = source;
- var featureSet = FeatureSet.latestLanguageVersion();
-
- _definingLibrary = LibraryElementImpl(
- context, _AnalysisSessionMock(), 'name', -1, 0, featureSet);
- _definingLibrary.definingCompilationUnit = _definingCompilationUnit;
-
- _definingLibrary.typeProvider = context.typeProviderLegacy;
- _definingLibrary.typeSystem = context.typeSystemLegacy;
- _typeProvider = context.typeProviderLegacy;
-
- _visitor = ResolverVisitor(
- inheritance, _definingLibrary, source, _typeProvider, _listener,
- featureSet: featureSet,
- flowAnalysisHelper:
- FlowAnalysisHelper(context.typeSystemLegacy, false, featureSet));
+ test_visitParenthesizedExpression() async {
+ await assertNoErrorsInCode('''
+test() => (0);
+''');
+ expect(
+ findNode.parenthesized('(0)').staticType, same(typeProvider.intType));
}
- DartType _flatten(DartType type) => _typeSystem.flatten(type);
-
- /// Return an integer literal that has been resolved to the correct type.
- ///
- /// @param value the value of the literal
- /// @return an integer literal that has been resolved to the correct type
- DoubleLiteral _resolvedDouble(double value) {
- var literal = AstTestFactory.doubleLiteral(value);
- literal.staticType = _typeProvider.doubleType;
- return literal;
+ test_visitSimpleStringLiteral() async {
+ await assertNoErrorsInCode('''
+test() => 'a';
+''');
+ expect(findNode.stringLiteral("'a'").staticType,
+ same(typeProvider.stringType));
}
- /// Return an integer literal that has been resolved to the correct type.
- ///
- /// @param value the value of the literal
- /// @return an integer literal that has been resolved to the correct type
- IntegerLiteral _resolvedInteger(int value) {
- var literal = AstTestFactory.integer(value);
- literal.staticType = _typeProvider.intType;
- return literal;
+ test_visitStringInterpolation() async {
+ await assertNoErrorsInCode(r'''
+test() => "a${'b'}c";
+''');
+ expect(findNode.stringInterpolation(r'''"a${'b'}c"''').staticType,
+ same(typeProvider.stringType));
}
- /// Return a string literal that has been resolved to the correct type.
- ///
- /// @param value the value of the literal
- /// @return a string literal that has been resolved to the correct type
- SimpleStringLiteral _resolvedString(String value) {
- var string = AstTestFactory.string2(value);
- string.staticType = _typeProvider.stringType;
- return string;
- }
-
- /// Return a simple identifier that has been resolved to a variable element
- /// with the given type.
- ///
- /// @param type the type of the variable being represented
- /// @param variableName the name of the variable
- /// @return a simple identifier that has been resolved to a variable element
- /// with the given type
- SimpleIdentifier _resolvedVariable(InterfaceType type, String variableName) {
- var identifier = AstTestFactory.identifier3(variableName);
- VariableElementImpl element =
- ElementFactory.localVariableElement(identifier);
- element.type = type;
- identifier.staticElement = element;
- identifier.staticType = type;
- return identifier;
- }
+ test_visitSuperExpression() async {
+ await assertNoErrorsInCode('''
+class A {
+ int get foo => 0;
}
+class B extends A {
+ test() => super.foo;
+}
+late B b;
+''');
+ var bType = findElement.topVar('b').type;
+ expect(findNode.super_('super').staticType, bType);
+ }
-class _AnalysisSessionMock implements AnalysisSession {
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+ test_visitSymbolLiteral() async {
+ await assertNoErrorsInCode('''
+test() => #a;
+''');
+ expect(
+ findNode.symbolLiteral('#a').staticType, same(typeProvider.symbolType));
+ }
+
+ test_visitThisExpression() async {
+ await assertNoErrorsInCode('''
+class A {}
+class B extends A {
+ test() => this;
+}
+late B b;
+''');
+ var bType = findElement.topVar('b').type;
+ expect(findNode.this_('this').staticType, bType);
+ }
+
+ test_visitThrowExpression_withValue() async {
+ await assertNoErrorsInCode('''
+test() => throw 0;
+''');
+ var node = findNode.throw_('throw 0');
+ expect(node.staticType, same(typeProvider.bottomType));
+ }
+
+ DartType _flatten(DartType type) => typeSystem.flatten(type);
}
diff --git a/pkg/dartdev/lib/src/templates/server_shelf.dart b/pkg/dartdev/lib/src/templates/server_shelf.dart
index ed6b730..33dd442 100644
--- a/pkg/dartdev/lib/src/templates/server_shelf.dart
+++ b/pkg/dartdev/lib/src/templates/server_shelf.dart
@@ -125,7 +125,7 @@
}
Response _echoHandler(Request request) {
- final message = params(request, 'message');
+ final message = request.params['message'];
return Response.ok('$message\n');
}
diff --git a/pkg/dartdev/test/commands/create_integration_test.dart b/pkg/dartdev/test/commands/create_integration_test.dart
index 4856b47..e6f2bf5 100644
--- a/pkg/dartdev/test/commands/create_integration_test.dart
+++ b/pkg/dartdev/test/commands/create_integration_test.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:async';
+import 'dart:convert';
import 'dart:io';
import 'package:dartdev/src/commands/create.dart';
+import 'package:dartdev/src/templates.dart';
+import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import '../utils.dart';
@@ -23,21 +27,22 @@
// Create tests for each template.
for (String templateId in CreateCommand.legalTemplateIds) {
test(templateId, () async {
+ const projectName = 'template_project';
p = project();
+ final templateGenerator = getGenerator(templateId);
ProcessResult createResult = await p.run([
'create',
'--force',
'--template',
templateId,
- 'template_project',
+ projectName,
]);
expect(createResult.exitCode, 0, reason: createResult.stderr);
// Validate that the project analyzes cleanly.
- // TODO: Should we use --fatal-infos here?
ProcessResult analyzeResult =
- await p.run(['analyze'], workingDir: p.dir.path);
+ await p.run(['analyze', '--fatal-infos', projectName]);
expect(analyzeResult.exitCode, 0, reason: analyzeResult.stdout);
// Validate that the code is well formatted.
@@ -46,9 +51,86 @@
'--output',
'none',
'--set-exit-if-changed',
- 'template_project',
+ projectName,
]);
expect(formatResult.exitCode, 0, reason: formatResult.stdout);
+
+ // Process the execution instructions provided by the template.
+ final runCommands = templateGenerator
+ .getInstallInstructions(
+ projectName,
+ projectName,
+ )
+ .split('\n')
+ // Remove directory change instructions.
+ .sublist(1)
+ .map((command) => command.trim())
+ .map((command) {
+ final commandParts = command.split(' ');
+ if (command.startsWith('dart ')) {
+ return commandParts.sublist(1);
+ }
+ return commandParts;
+ }).toList();
+
+ final isServerTemplate = templateGenerator.categories.contains('server');
+ final isWebTemplate = templateGenerator.categories.contains('web');
+ final workingDir = path.join(p.dirPath, projectName);
+
+ // Execute the templates run instructions.
+ for (int i = 0; i < runCommands.length; ++i) {
+ // The last command is always the command to execute the code generated
+ // by the template.
+ final isLastCommand = i == runCommands.length - 1;
+ final command = runCommands[i];
+ Process process;
+
+ if (isLastCommand && isWebTemplate) {
+ // The web template uses `webdev` to execute, not `dart`, so don't
+ // run the test through the project utility method.
+ process = await Process.start(
+ path.join(
+ p.pubCacheBinPath,
+ Platform.isWindows ? '${command.first}.bat' : command.first,
+ ),
+ command.sublist(1),
+ workingDirectory: workingDir,
+ );
+ } else {
+ process = await p.start(
+ command,
+ workingDir: workingDir,
+ );
+ }
+
+ if (isLastCommand && (isServerTemplate || isWebTemplate)) {
+ final completer = Completer<void>();
+ StreamSubscription sub;
+ // Listen for well-known output from specific templates to determine
+ // if they've executed correctly. These templates won't exit on their
+ // own, so we'll need to terminate the process once we've verified it
+ // runs correctly.
+ sub = process.stdout.transform(utf8.decoder).listen((e) {
+ if ((isServerTemplate && e.contains('Server listening on port')) ||
+ (isWebTemplate && e.contains('Succeeded after'))) {
+ sub.cancel();
+ process.kill();
+ completer.complete();
+ }
+ });
+ await completer.future;
+
+ // Since we had to terminate the process manually, we aren't certain
+ // as to what the exit code will be on all platforms (should be -15
+ // for POSIX systems), so we'll just wait for the process to exit
+ // here.
+ await process.exitCode;
+ } else {
+ // If the sample should exit on its own, it should always result in
+ // an exit code of 0.
+ expect(await process.exitCode, 0);
+ }
+ }
});
}
}
diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart
index 8f8147a..404b05e 100644
--- a/pkg/dartdev/test/utils.dart
+++ b/pkg/dartdev/test/utils.dart
@@ -39,6 +39,10 @@
String get dirPath => dir.path;
+ String get pubCachePath => path.join(dirPath, 'pub_cache');
+
+ String get pubCacheBinPath => path.join(pubCachePath, 'bin');
+
String get mainPath => path.join(dirPath, relativeFilePath);
final String name;
@@ -113,7 +117,10 @@
...arguments,
],
workingDirectory: workingDir ?? dir.path,
- environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'});
+ environment: {
+ if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true',
+ 'PUB_CACHE': pubCachePath
+ });
final stdoutContents = _process.stdout.transform(utf8.decoder).join();
final stderrContents = _process.stderr.transform(utf8.decoder).join();
final code = await _process.exitCode;
@@ -136,7 +143,10 @@
...arguments,
],
workingDirectory: workingDir ?? dir.path,
- environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'})
+ environment: {
+ if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true',
+ 'PUB_CACHE': pubCachePath,
+ })
..then((p) => _process = p);
}
diff --git a/runtime/tests/vm/dart/deferred_loading_call_modes_test.dart b/runtime/tests/vm/dart/deferred_loading_call_modes_test.dart
index 954a3d9..0f155d2 100644
--- a/runtime/tests/vm/dart/deferred_loading_call_modes_test.dart
+++ b/runtime/tests/vm/dart/deferred_loading_call_modes_test.dart
@@ -2,9 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--use_table_dispatch=false
-// VMOptions=--use_table_dispatch=true
-
import "splay_test.dart" deferred as splay; // Some non-trivial code.
main() async {
diff --git a/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart b/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
index 26cc7c7..1af4fa3 100644
--- a/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
+++ b/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
@@ -108,7 +108,6 @@
Future<void> testAOT(String dillPath,
{bool useAsm = false,
bool forceDrops = false,
- bool useDispatch = true,
bool stripUtil = false, // Note: forced true if useAsm.
bool stripFlag = false,
bool disassemble = false}) async {
@@ -129,9 +128,6 @@
if (forceDrops) {
descriptionBuilder.write('-dropped');
}
- if (!useDispatch) {
- descriptionBuilder.write('-nodispatch');
- }
if (stripFlag) {
descriptionBuilder.write('-intstrip');
}
@@ -158,7 +154,6 @@
'--no-retain-function-objects',
'--no-retain-code-objects'
],
- useDispatch ? '--use-table-dispatch' : '--no-use-table-dispatch',
if (disassemble) '--disassemble', // Not defined in PRODUCT mode.
dillPath,
];
@@ -434,7 +429,6 @@
// Test unstripped ELF generation directly.
await testAOT(aotDillPath);
await testAOT(aotDillPath, forceDrops: true);
- await testAOT(aotDillPath, forceDrops: true, useDispatch: false);
// Test flag-stripped ELF generation.
await testAOT(aotDillPath, stripFlag: true);
diff --git a/runtime/tests/vm/dart_2/deferred_loading_call_modes_test.dart b/runtime/tests/vm/dart_2/deferred_loading_call_modes_test.dart
index 5efc2bd..940c992 100644
--- a/runtime/tests/vm/dart_2/deferred_loading_call_modes_test.dart
+++ b/runtime/tests/vm/dart_2/deferred_loading_call_modes_test.dart
@@ -4,9 +4,6 @@
// @dart = 2.9
-// VMOptions=--use_table_dispatch=false
-// VMOptions=--use_table_dispatch=true
-
import "splay_test.dart" deferred as splay; // Some non-trivial code.
main() async {
diff --git a/runtime/tests/vm/dart_2/v8_snapshot_profile_writer_test.dart b/runtime/tests/vm/dart_2/v8_snapshot_profile_writer_test.dart
index cf3e581..21db861 100644
--- a/runtime/tests/vm/dart_2/v8_snapshot_profile_writer_test.dart
+++ b/runtime/tests/vm/dart_2/v8_snapshot_profile_writer_test.dart
@@ -110,7 +110,6 @@
Future<void> testAOT(String dillPath,
{bool useAsm = false,
bool forceDrops = false,
- bool useDispatch = true,
bool stripUtil = false, // Note: forced true if useAsm.
bool stripFlag = false,
bool disassemble = false}) async {
@@ -131,9 +130,6 @@
if (forceDrops) {
descriptionBuilder.write('-dropped');
}
- if (!useDispatch) {
- descriptionBuilder.write('-nodispatch');
- }
if (stripFlag) {
descriptionBuilder.write('-intstrip');
}
@@ -160,7 +156,6 @@
'--no-retain-function-objects',
'--no-retain-code-objects'
],
- useDispatch ? '--use-table-dispatch' : '--no-use-table-dispatch',
if (disassemble) '--disassemble', // Not defined in PRODUCT mode.
dillPath,
];
@@ -428,7 +423,6 @@
// Test unstripped ELF generation directly.
await testAOT(aotDillPath);
await testAOT(aotDillPath, forceDrops: true);
- await testAOT(aotDillPath, forceDrops: true, useDispatch: false);
// Test flag-stripped ELF generation.
await testAOT(aotDillPath, stripFlag: true);
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 930e8ad..a893335 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -487,10 +487,8 @@
// as well as other type checks.
HierarchyInfo hierarchy_info(T);
- if (FLAG_use_table_dispatch) {
- dispatch_table_generator_ = new compiler::DispatchTableGenerator(Z);
- dispatch_table_generator_->Initialize(IG->class_table());
- }
+ dispatch_table_generator_ = new compiler::DispatchTableGenerator(Z);
+ dispatch_table_generator_->Initialize(IG->class_table());
// Precompile constructors to compute information such as
// optimized instruction count (used in inlining heuristics).
@@ -1446,8 +1444,6 @@
}
void Precompiler::AddTableSelector(const compiler::TableSelector* selector) {
- ASSERT(FLAG_use_table_dispatch);
-
if (is_tracing()) {
tracer_->WriteTableSelectorRef(selector->id);
}
@@ -1459,10 +1455,6 @@
}
bool Precompiler::IsHitByTableSelector(const Function& function) {
- if (!FLAG_use_table_dispatch) {
- return false;
- }
-
const int32_t selector_id = selector_map()->SelectorId(function);
if (selector_id == compiler::SelectorMap::kInvalidSelectorId) return false;
return seen_table_selectors_.HasKey(selector_id);
@@ -2011,7 +2003,6 @@
void Precompiler::FinalizeDispatchTable() {
PRECOMPILER_TIMER_SCOPE(this, FinalizeDispatchTable);
- if (!FLAG_use_table_dispatch) return;
HANDLESCOPE(T);
// Build the entries used to serialize the dispatch table before
// dropping functions, as we may clear references to Code objects.
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 678905c..2b74839 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -247,7 +247,6 @@
}
compiler::SelectorMap* selector_map() {
- ASSERT(FLAG_use_table_dispatch);
return dispatch_table_generator_->selector_map();
}
diff --git a/runtime/vm/compiler/aot/precompiler_tracer.cc b/runtime/vm/compiler/aot/precompiler_tracer.cc
index d0a2e5f..9588400 100644
--- a/runtime/vm/compiler/aot/precompiler_tracer.cc
+++ b/runtime/vm/compiler/aot/precompiler_tracer.cc
@@ -90,9 +90,7 @@
const auto& fun = Function::Cast(obj);
cls_ = fun.Owner();
const intptr_t selector_id =
- FLAG_use_table_dispatch
- ? precompiler_->selector_map()->SelectorId(fun)
- : -1;
+ precompiler_->selector_map()->SelectorId(fun);
Write("\"%c\",%" Pd ",%" Pd ",%" Pd "",
fun.IsDynamicFunction() ? 'F' : 'S', InternEntity(cls_),
InternString(NameForTrace(fun)), selector_id);
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index a9a71ee..8d265de 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -1604,10 +1604,8 @@
void Assembler::SetupGlobalPoolAndDispatchTable() {
ASSERT(FLAG_precompiled_mode);
ldr(PP, Address(THR, target::Thread::global_object_pool_offset()));
- if (FLAG_use_table_dispatch) {
- ldr(DISPATCH_TABLE_REG,
- Address(THR, target::Thread::dispatch_table_array_offset()));
- }
+ ldr(DISPATCH_TABLE_REG,
+ Address(THR, target::Thread::dispatch_table_array_offset()));
}
void Assembler::LoadIsolate(Register rd) {
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index b4dcf19..07bcb13 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -1552,10 +1552,8 @@
ASSERT(FLAG_precompiled_mode);
ldr(PP, Address(THR, target::Thread::global_object_pool_offset()));
sub(PP, PP, Operand(kHeapObjectTag)); // Pool in PP is untagged!
- if (FLAG_use_table_dispatch) {
- ldr(DISPATCH_TABLE_REG,
- Address(THR, target::Thread::dispatch_table_array_offset()));
- }
+ ldr(DISPATCH_TABLE_REG,
+ Address(THR, target::Thread::dispatch_table_array_offset()));
}
void Assembler::CheckCodePointer() {
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index 0f9e5ea..1faa8d3 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -470,9 +470,7 @@
});
COMPILER_PASS(UseTableDispatch, {
- if (FLAG_use_table_dispatch) {
- state->call_specializer->ReplaceInstanceCallsWithDispatchTableCalls();
- }
+ state->call_specializer->ReplaceInstanceCallsWithDispatchTableCalls();
});
COMPILER_PASS_REPEAT(CSE, { return DominatorBasedCSE::Optimize(flow_graph); });
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 86b49ff..bf9a9ad 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -3636,10 +3636,7 @@
const auto unboxing_info =
unboxing_info_metadata_helper_.GetUnboxingInfoMetadata(kernel_offset);
- // TODO(dartbug.com/32292): accept unboxed parameters and return value
- // when FLAG_use_table_dispatch == false.
- if (FLAG_precompiled_mode && unboxing_info != nullptr &&
- FLAG_use_table_dispatch) {
+ if (FLAG_precompiled_mode && unboxing_info != nullptr) {
for (intptr_t i = 0; i < unboxing_info->unboxed_args_info.length(); i++) {
SetupUnboxingInfoOfParameter(function, i, unboxing_info);
}
@@ -3655,10 +3652,7 @@
const auto unboxing_info =
unboxing_info_metadata_helper_.GetUnboxingInfoMetadata(kernel_offset);
- // TODO(dartbug.com/32292): accept unboxed parameters and return value
- // when FLAG_use_table_dispatch == false.
- if (FLAG_precompiled_mode && unboxing_info != nullptr &&
- FLAG_use_table_dispatch) {
+ if (FLAG_precompiled_mode && unboxing_info != nullptr) {
if (field_accessor.IsImplicitSetterFunction()) {
for (intptr_t i = 0; i < unboxing_info->unboxed_args_info.length(); i++) {
SetupUnboxingInfoOfParameter(field_accessor, i, unboxing_info);
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index cccfdfb..6e885be 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -184,7 +184,6 @@
P(reorder_basic_blocks, bool, true, "Reorder basic blocks") \
C(stress_async_stacks, false, false, bool, false, \
"Stress test async stack traces") \
- P(use_table_dispatch, bool, true, "Enable dispatch table based calls.") \
P(retain_function_objects, bool, true, \
"Serialize function objects for all code objects even if not otherwise " \
"needed in the precompiled runtime.") \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 9bb4bb7..3259317 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -10161,8 +10161,9 @@
return true;
}
- // If table dispatch is disabled, all instance calls use switchable calls.
- if (!(FLAG_precompiled_mode && FLAG_use_table_dispatch)) {
+ // AOT mode uses table dispatch.
+ // In JIT mode all instance calls use switchable calls.
+ if (!FLAG_precompiled_mode) {
return true;
}
diff --git a/tools/VERSION b/tools/VERSION
index 8faa73f..0eafd3c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 152
+PRERELEASE 153
PRERELEASE_PATCH 0
\ No newline at end of file