Revert "Stop reporting StrongModeCode.TOP_LEVEL_INSTANCE_GETTER"
This reverts commit 649f7cf689ee007e98c09c6a3e9f484e9d853cac.
Reason for revert: Breaks google3: b/185875256
Original change's description:
> Stop reporting StrongModeCode.TOP_LEVEL_INSTANCE_GETTER
>
> Change-Id: I947e1edb042825a5cfc3394d2554ad3272f86b91
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195302
> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
# Not skipping CQ checks because original CL landed > 1 day ago.
Change-Id: Ic019fa570f048e213290ac04d02d1b4655415b47
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196282
Reviewed-by: David Morgan <davidmorgan@google.com>
Commit-Queue: David Morgan <davidmorgan@google.com>
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 128aa38..0134b77 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -848,6 +848,8 @@
StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION,
+ StrongModeCode.TOP_LEVEL_IDENTIFIER_NO_TYPE,
+ StrongModeCode.TOP_LEVEL_INSTANCE_GETTER,
TodoCode.TODO,
];
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index bef21eb..9900a5e 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -14180,3 +14180,63 @@
@override
ErrorType get type => ErrorType.STATIC_WARNING;
}
+
+/**
+ * This class has Strong Mode specific error codes.
+ *
+ * "Strong Mode" was the prototype for Dart 2's sound type system. Many of these
+ * errors became part of Dart 2. Some of them are optional flags, used for
+ * stricter checking.
+ *
+ * These error codes tend to use the same message across different severity
+ * levels, so they are grouped for clarity.
+ */
+class StrongModeCode extends ErrorCode {
+ /*
+ * TODO(brianwilkerson) Make the TOP_LEVEL_ error codes be errors rather than
+ * hints and then clean up the function _errorSeverity in
+ * test/src/task/strong/strong_test_helper.dart.
+ */
+ /* TODO(leafp) Delete most of these.
+ */
+
+ static const StrongModeCode TOP_LEVEL_IDENTIFIER_NO_TYPE = StrongModeCode(
+ ErrorType.HINT,
+ 'TOP_LEVEL_IDENTIFIER_NO_TYPE',
+ "The type of '{0}' can't be inferred because the type of '{1}' "
+ "couldn't be inferred.",
+ correction:
+ "Try adding an explicit type to either the variable '{0}' or the "
+ "variable '{1}'.");
+
+ static const StrongModeCode TOP_LEVEL_INSTANCE_GETTER = StrongModeCode(
+ ErrorType.STATIC_WARNING,
+ 'TOP_LEVEL_INSTANCE_GETTER',
+ "The type of '{0}' can't be inferred because it refers to an instance "
+ "getter, '{1}', which has an implicit type.",
+ correction: "Add an explicit type for either '{0}' or '{1}'.");
+
+ @override
+ final ErrorType type;
+
+ /**
+ * Initialize a newly created error code to have the given [type] and [name].
+ *
+ * The message associated with the error will be created from the given
+ * [message] template. The correction associated with the error will be
+ * created from the optional [correction] template.
+ */
+ const StrongModeCode(ErrorType type, String name, String message,
+ {String? correction, bool hasPublishedDocs = false})
+ : type = type,
+ super(
+ correction: correction,
+ hasPublishedDocs: hasPublishedDocs,
+ message: message,
+ name: name,
+ uniqueName: 'StrongModeCode.$name',
+ );
+
+ @override
+ ErrorSeverity get errorSeverity => type.severity;
+}
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 9f51dba..4138d99 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -376,6 +376,15 @@
return _node.name.name;
}
+ bool get isImplicitlyTypedInstanceField {
+ var variables = _node.parent as VariableDeclarationList;
+ if (variables.type == null) {
+ var parent = variables.parent;
+ return parent is FieldDeclaration && !parent.isStatic;
+ }
+ return false;
+ }
+
PropertyInducingElementImpl get _elementImpl {
return _node.declaredElement as PropertyInducingElementImpl;
}
@@ -391,7 +400,19 @@
return const <_InferenceNode>[];
}
- return collector._set.map(_walker.getNode).whereNotNull().toList();
+ var dependencies =
+ collector._set.map(_walker.getNode).whereNotNull().toList();
+
+ for (var node in dependencies) {
+ if (node is _VariableInferenceNode &&
+ node.isImplicitlyTypedInstanceField) {
+ _elementImpl.type = DynamicTypeImpl.instance;
+ isEvaluated = true;
+ return const <_InferenceNode>[];
+ }
+ }
+
+ return dependencies;
}
@override
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3d179d7..bd2547c 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -17,7 +17,8 @@
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/error/codes.dart' show CompileTimeErrorCode;
+import 'package:analyzer/src/error/codes.dart'
+ show CompileTimeErrorCode, StrongModeCode;
import 'package:analyzer/src/task/inference_error.dart';
Element? _getKnownElement(Expression expression) {
@@ -496,21 +497,14 @@
@override
void visitVariableDeclaration(VariableDeclaration node) {
- var element = node.declaredElement;
- if (element is PropertyInducingElementImpl) {
- var error = element.typeInferenceError;
- if (error != null) {
- if (error.kind == TopLevelInferenceErrorKind.dependencyCycle) {
- // Errors on const should have been reported with
- // [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT].
- if (!element.isConst) {
- _recordMessage(
- node.name,
- CompileTimeErrorCode.TOP_LEVEL_CYCLE,
- [element.name, error.arguments],
- );
- }
- }
+ var variableElement = node.declaredElement;
+ var parent = node.parent;
+ if (variableElement is PropertyInducingElement &&
+ parent is VariableDeclarationList &&
+ parent.type == null) {
+ var initializer = node.initializer;
+ if (initializer != null) {
+ _validateTopLevelInitializer(variableElement.name, initializer);
}
}
node.visitChildren(this);
@@ -922,6 +916,10 @@
reporter.onError(error);
}
+ void _validateTopLevelInitializer(String name, Expression n) {
+ n.accept(_TopLevelInitializerValidator(this, name));
+ }
+
void _visitForEachParts(ForEachParts node, SimpleIdentifier loopVariable) {
if (loopVariable.staticElement is! VariableElement) {
return;
@@ -985,3 +983,169 @@
throw StateError('${e.runtimeType} is unhandled type');
}
}
+
+class _TopLevelInitializerValidator extends RecursiveAstVisitor<void> {
+ final CodeChecker _codeChecker;
+ final String _name;
+
+ _TopLevelInitializerValidator(this._codeChecker, this._name);
+
+ void validateHasType(AstNode n, PropertyAccessorElement e) {
+ if (e.hasImplicitReturnType) {
+ var variable = e.declaration.variable as PropertyInducingElementImpl;
+ var error = variable.typeInferenceError;
+ if (error != null) {
+ if (error.kind == TopLevelInferenceErrorKind.dependencyCycle) {
+ // Errors on const should have been reported with
+ // [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT].
+ if (!variable.isConst) {
+ _codeChecker._recordMessage(n, CompileTimeErrorCode.TOP_LEVEL_CYCLE,
+ [_name, error.arguments]);
+ }
+ } else {
+ _codeChecker._recordMessage(
+ n, StrongModeCode.TOP_LEVEL_IDENTIFIER_NO_TYPE, [_name, e.name]);
+ }
+ }
+ }
+ }
+
+ void validateIdentifierElement(AstNode n, Element? e,
+ {bool isMethodCall = false}) {
+ if (e == null) {
+ return;
+ }
+
+ var enclosing = e.enclosingElement;
+ if (enclosing is CompilationUnitElement) {
+ if (e is PropertyAccessorElement) {
+ validateHasType(n, e);
+ }
+ } else if (enclosing is ClassElement) {
+ if (e is PropertyAccessorElement) {
+ if (e.isStatic) {
+ validateHasType(n, e);
+ } else if (e.hasImplicitReturnType) {
+ _codeChecker._recordMessage(
+ n, StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, [_name, e.name]);
+ }
+ }
+ }
+ }
+
+ @override
+ visitAsExpression(AsExpression node) {
+ // Nothing to validate.
+ }
+
+ @override
+ visitBinaryExpression(BinaryExpression node) {
+ TokenType operator = node.operator.type;
+ if (operator == TokenType.AMPERSAND_AMPERSAND ||
+ operator == TokenType.BAR_BAR ||
+ operator == TokenType.EQ_EQ ||
+ operator == TokenType.BANG_EQ) {
+ // These operators give 'bool', no need to validate operands.
+ } else {
+ node.leftOperand.accept(this);
+ }
+ }
+
+ @override
+ visitCascadeExpression(CascadeExpression node) {
+ node.target.accept(this);
+ }
+
+ @override
+ visitConditionalExpression(ConditionalExpression node) {
+ // No need to validate the condition, since it can't affect type inference.
+ node.thenExpression.accept(this);
+ node.elseExpression.accept(this);
+ }
+
+ @override
+ visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ if (node.typeArguments != null) {
+ return;
+ }
+
+ var function = node.function;
+ if (function is PropertyAccess) {
+ var propertyName = function.propertyName;
+ validateIdentifierElement(propertyName, propertyName.staticElement);
+ }
+
+ var functionType = node.function.staticType;
+ if (functionType is FunctionType && functionType.typeFormals.isNotEmpty) {
+ node.argumentList.accept(this);
+ }
+ }
+
+ @override
+ visitIndexExpression(IndexExpression node) {
+ // Nothing to validate.
+ }
+
+ @override
+ visitInstanceCreationExpression(InstanceCreationExpression node) {
+ var constructor = node.constructorName.staticElement;
+ var class_ = constructor?.enclosingElement;
+ if (node.constructorName.type.typeArguments == null &&
+ class_ != null &&
+ class_.typeParameters.isNotEmpty) {
+ // Type inference might depend on the parameters
+ super.visitInstanceCreationExpression(node);
+ }
+ }
+
+ @override
+ visitIsExpression(IsExpression node) {
+ // Nothing to validate.
+ }
+
+ @override
+ visitListLiteral(ListLiteral node) {
+ if (node.typeArguments == null) {
+ super.visitListLiteral(node);
+ }
+ }
+
+ @override
+ visitMethodInvocation(MethodInvocation node) {
+ node.target?.accept(this);
+ var method = node.methodName.staticElement;
+ validateIdentifierElement(node, method, isMethodCall: true);
+ if (method is ExecutableElement) {
+ if (node.typeArguments == null && method.typeParameters.isNotEmpty) {
+ // Type inference might depend on the parameters
+ node.argumentList.accept(this);
+ }
+ }
+ }
+
+ @override
+ visitPrefixExpression(PrefixExpression node) {
+ if (node.operator.type == TokenType.BANG) {
+ // This operator gives 'bool', no need to validate operands.
+ } else {
+ node.operand.accept(this);
+ }
+ }
+
+ @override
+ visitSetOrMapLiteral(SetOrMapLiteral node) {
+ if (node.typeArguments == null) {
+ super.visitSetOrMapLiteral(node);
+ }
+ }
+
+ @override
+ visitSimpleIdentifier(SimpleIdentifier node) {
+ validateIdentifierElement(node, node.staticElement);
+ }
+
+ @override
+ visitThrowExpression(ThrowExpression node) {
+ // Nothing to validate.
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
index 85e16c6..77fa53c 100644
--- a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
@@ -34,8 +34,7 @@
}
final b = new A().a;
''', [
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 18, 1),
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 37, 1),
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 49, 1),
]);
assertTypeDynamic(findElement.field('a').type);
diff --git a/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
index 52e2b7c..c3b6d67 100644
--- a/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
@@ -93,6 +93,7 @@
final y = x;
}
''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 37, 1),
error(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, 37, 1),
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart b/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart
index fbe9053..0f72b33 100644
--- a/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart
@@ -20,8 +20,8 @@
var x = y + 1;
var y = x + 1;
''', [
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 19, 1),
+ error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 8, 1),
+ error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 23, 1),
]);
}
@@ -29,7 +29,7 @@
await assertErrorsInCode(r'''
var x = x;
''', [
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
+ error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 8, 1),
]);
}
@@ -41,7 +41,7 @@
],
];
''', [
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 5),
+ error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 25, 5),
]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart b/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
index 3a78473..8153be9 100644
--- a/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
@@ -2,6 +2,7 @@
// 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/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
@@ -81,71 +82,81 @@
}
test_implicitlyTyped() async {
- await assertNoErrorsInCode('''
+ await assertErrorsInCode('''
class A {
get g => 0;
}
var b = new A().g;
-''');
- assertTypeDynamic(findElement.topVar('b').type);
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 42, 1),
+ ]);
}
test_implicitlyTyped_call() async {
- await assertNoErrorsInCode('''
+ await assertErrorsInCode('''
class A {
get g => () => 0;
}
var a = new A();
var b = a.g();
-''');
- assertTypeDynamic(findElement.topVar('b').type);
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 59, 1),
+ ]);
}
test_implicitlyTyped_field() async {
- await assertNoErrorsInCode('''
+ await assertErrorsInCode('''
class A {
var g = 0;
}
var b = new A().g;
-''');
- assertType(findElement.topVar('b').type, 'int');
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 41, 1),
+ ]);
}
test_implicitlyTyped_field_call() async {
- await assertNoErrorsInCode('''
+ await assertErrorsInCode('''
class A {
var g = () => 0;
}
var a = new A();
var b = a.g();
-''');
- assertType(findElement.topVar('b').type, 'int');
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 58, 1),
+ ]);
}
test_implicitlyTyped_field_prefixedIdentifier() async {
- await assertNoErrorsInCode('''
+ await assertErrorsInCode('''
class A {
var g = 0;
}
var a = new A();
var b = a.g;
-''');
- assertType(findElement.topVar('b').type, 'int');
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 52, 1),
+ ]);
}
test_implicitlyTyped_fn() async {
- await assertNoErrorsInCode('''
+ // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
+ // generic, so the type of a.x might affect the type of b.
+ await assertErrorsInCode('''
class A {
var x = 0;
}
int f<T>(x) => 0;
var a = new A();
var b = f(a.x);
-''');
- assertType(findElement.topVar('b').type, 'int');
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 72, 1),
+ ]);
}
test_implicitlyTyped_fn_explicit_type_params() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
class A {
var x = 0;
@@ -154,10 +165,11 @@
var a = new A();
var b = f<int>(a.x);
''');
- assertType(findElement.topVar('b').type, 'int');
}
test_implicitlyTyped_fn_not_generic() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
class A {
var x = 0;
@@ -166,10 +178,11 @@
var a = new A();
var b = f(a.x);
''');
- assertType(findElement.topVar('b').type, 'int');
}
test_implicitlyTyped_indexExpression() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
class A {
var x = 0;
@@ -178,21 +191,25 @@
var a = new A();
var b = a[a.x];
''');
- assertType(findElement.topVar('b').type, 'int');
}
test_implicitlyTyped_invoke() async {
- await assertNoErrorsInCode('''
+ // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the
+ // closure is generic, so the type of a.x might affect the type of b.
+ await assertErrorsInCode('''
class A {
var x = 0;
}
var a = new A();
var b = (<T>(y) => 0)(a.x);
-''');
- assertType(findElement.topVar('b').type, 'int');
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 66, 1),
+ ]);
}
test_implicitlyTyped_invoke_explicit_type_params() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
class A {
var x = 0;
@@ -200,10 +217,11 @@
var a = new A();
var b = (<T>(y) => 0)<int>(a.x);
''');
- assertType(findElement.topVar('b').type, 'int');
}
test_implicitlyTyped_invoke_not_generic() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
class A {
var x = 0;
@@ -211,22 +229,26 @@
var a = new A();
var b = ((y) => 0)(a.x);
''');
- assertType(findElement.topVar('b').type, 'int');
}
test_implicitlyTyped_method() async {
- await assertNoErrorsInCode('''
+ // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
+ // generic, so the type of a.x might affect the type of b.
+ await assertErrorsInCode('''
class A {
var x = 0;
int f<T>(int x) => 0;
}
var a = new A();
var b = a.f(a.x);
-''');
- assertType(findElement.topVar('b').type, 'int');
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 80, 1),
+ ]);
}
test_implicitlyTyped_method_explicit_type_params() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
class A {
var x = 0;
@@ -235,10 +257,11 @@
var a = new A();
var b = a.f<int>(a.x);
''');
- assertType(findElement.topVar('b').type, 'int');
}
test_implicitlyTyped_method_not_generic() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
class A {
var x = 0;
@@ -247,24 +270,28 @@
var a = new A();
var b = a.f(a.x);
''');
- assertType(findElement.topVar('b').type, 'int');
}
test_implicitlyTyped_new() async {
- await assertNoErrorsInCode('''
+ // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
+ // generic, so the type of a.x might affect the type of b.
+ await assertErrorsInCode('''
class A {
var x = 0;
}
class B<T> {
- B(T x);
+ B(x);
}
var a = new A();
var b = new B(a.x);
-''');
- assertType(findElement.topVar('b').type, 'B<int>');
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 81, 1),
+ ]);
}
test_implicitlyTyped_new_explicit_type_params() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
class A {
var x = 0;
@@ -275,10 +302,11 @@
var a = new A();
var b = new B<int>(a.x);
''');
- assertType(findElement.topVar('b').type, 'B<int>');
}
test_implicitlyTyped_new_explicit_type_params_named() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
class A {
var x = 0;
@@ -289,10 +317,11 @@
var a = new A();
var b = new B<int>.named(a.x);
''');
- assertType(findElement.topVar('b').type, 'B<int>');
}
test_implicitlyTyped_new_explicit_type_params_prefixed() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
newFile('$testPackageLibPath/lib1.dart', content: '''
class B<T> {
B(x);
@@ -306,24 +335,28 @@
var a = new A();
var b = new foo.B<int>(a.x);
''');
- assertType(findElement.topVar('b').type, 'B<int>');
}
test_implicitlyTyped_new_named() async {
- await assertNoErrorsInCode('''
+ // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
+ // generic, so the type of a.x might affect the type of b.
+ await assertErrorsInCode('''
class A {
var x = 0;
}
class B<T> {
- B.named(T x);
+ B.named(x);
}
var a = new A();
var b = new B.named(a.x);
-''');
- assertType(findElement.topVar('b').type, 'B<int>');
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 93, 1),
+ ]);
}
test_implicitlyTyped_new_not_generic() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
class A {
var x = 0;
@@ -334,10 +367,11 @@
var a = new A();
var b = new B(a.x);
''');
- assertType(findElement.topVar('b').type, 'B');
}
test_implicitlyTyped_new_not_generic_named() async {
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
class A {
var x = 0;
@@ -348,7 +382,6 @@
var a = new A();
var b = new B.named(a.x);
''');
- assertType(findElement.topVar('b').type, 'B');
}
test_implicitlyTyped_new_not_generic_prefixed() async {
@@ -357,6 +390,8 @@
B(x);
}
''');
+ // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+ // it can't possibly affect the type of b.
await assertNoErrorsInCode('''
import 'lib1.dart' as foo;
class A {
@@ -365,39 +400,44 @@
var a = new A();
var b = new foo.B(a.x);
''');
- assertType(findElement.topVar('b').type, 'B');
}
test_implicitlyTyped_new_prefixed() async {
newFile('$testPackageLibPath/lib1.dart', content: '''
class B<T> {
- B(T x);
+ B(x);
}
''');
- await assertNoErrorsInCode('''
+ // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
+ // generic, so the type of a.x might affect the type of b.
+ await assertErrorsInCode('''
import 'lib1.dart' as foo;
class A {
var x = 0;
}
var a = new A();
var b = new foo.B(a.x);
-''');
- assertType(findElement.topVar('b').type, 'B<int>');
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 89, 1),
+ ]);
}
test_implicitlyTyped_prefixedIdentifier() async {
- await assertNoErrorsInCode('''
+ await assertErrorsInCode('''
class A {
get g => 0;
}
var a = new A();
var b = a.g;
-''');
- assertType(findElement.topVar('b').type, 'dynamic');
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 53, 1),
+ ]);
}
test_implicitlyTyped_propertyAccessLhs() async {
- await assertNoErrorsInCode('''
+ // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the type
+ // of a.x affects the lookup of y, which in turn affects the type of b.
+ await assertErrorsInCode('''
class A {
var x = new B();
int operator[](int value) => 0;
@@ -407,8 +447,9 @@
}
var a = new A();
var b = (a.x).y;
-''');
- assertType(findElement.topVar('b').type, 'int');
+''', [
+ error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 118, 1),
+ ]);
}
test_prefixedIdentifier() async {
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index d7828d1..5675f3f 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -101,8 +101,8 @@
var a = b;
var b = a;
''', [
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 15, 1),
+ error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 8, 1),
+ error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 19, 1),
]);
}
@@ -718,7 +718,7 @@
class C {
int f;
}
-int x;
+dynamic x;
''');
}
@@ -735,7 +735,7 @@
''');
checkElementText(library, r'''
import 'package:test/a.dart';
-int x;
+dynamic x;
''');
}
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 d20ec18..d77818f 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -364,8 +364,8 @@
var x = () => y;
var y = () => x;
''', [
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 21, 1),
+ error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 14, 1),
+ error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 31, 1),
]);
var x = _resultUnitElement.topLevelVariables[0];
@@ -381,8 +381,8 @@
var x = () => y;
var y = () => x;
''', [
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
- error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 21, 1),
+ error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 14, 1),
+ error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 31, 1),
]);
var x = _resultUnitElement.topLevelVariables[0];
diff --git a/tests/language/variable/inst_field_initializer1_test.dart b/tests/language/variable/inst_field_initializer1_test.dart
index 550a03e..edc85c8 100644
--- a/tests/language/variable/inst_field_initializer1_test.dart
+++ b/tests/language/variable/inst_field_initializer1_test.dart
@@ -10,6 +10,8 @@
// ^
// [analyzer] COMPILE_TIME_ERROR.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
// [cfe] Can't access 'this' in a field initializer to read 'x'.
+ // ^
+ // [analyzer] STATIC_WARNING.TOP_LEVEL_INSTANCE_GETTER
}
void main() {
diff --git a/tests/language_2/variable/inst_field_initializer1_test.dart b/tests/language_2/variable/inst_field_initializer1_test.dart
index 550a03e..edc85c8 100644
--- a/tests/language_2/variable/inst_field_initializer1_test.dart
+++ b/tests/language_2/variable/inst_field_initializer1_test.dart
@@ -10,6 +10,8 @@
// ^
// [analyzer] COMPILE_TIME_ERROR.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
// [cfe] Can't access 'this' in a field initializer to read 'x'.
+ // ^
+ // [analyzer] STATIC_WARNING.TOP_LEVEL_INSTANCE_GETTER
}
void main() {