mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:27:17 +00:00
Detect references to instance variables without declared type.
R=paulberry@google.com Bug: https://github.com/dart-lang/sdk/issues/33976 Change-Id: Iea377061a784d73d41a4f77f10f74077f8797813 Reviewed-on: https://dart-review.googlesource.com/75623 Reviewed-by: Paul Berry <paulberry@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
a0776096b9
commit
41273507b2
|
@ -2352,6 +2352,17 @@ class FieldElementForLink_ClassField extends VariableElementForLink
|
|||
@override
|
||||
bool get isStatic => unlinkedVariable.isStatic;
|
||||
|
||||
@override
|
||||
DartType get type {
|
||||
if (declaredType != null) {
|
||||
return declaredType;
|
||||
}
|
||||
if (Linker._isPerformingVariableTypeInference && !isStatic) {
|
||||
return DynamicTypeImpl.instance;
|
||||
}
|
||||
return inferredType;
|
||||
}
|
||||
|
||||
@override
|
||||
void set type(DartType inferredType) {
|
||||
assert(!isStatic);
|
||||
|
@ -3585,6 +3596,11 @@ class Linker {
|
|||
/// instance variables in that same cycle.
|
||||
static LibraryCycleForLink _initializerTypeInferenceCycle;
|
||||
|
||||
/// If a top-level or an instance variable type inference is in progress,
|
||||
/// this flag it set to `true`. It is used to prevent type inference for
|
||||
/// other instance variables (when they don't have declared type).
|
||||
static bool _isPerformingVariableTypeInference = false;
|
||||
|
||||
/// Callback to ask the client for a [LinkedLibrary] for a
|
||||
/// dependency.
|
||||
final GetDependencyCallback getDependency;
|
||||
|
@ -4952,11 +4968,13 @@ abstract class VariableElementForLink
|
|||
assert(Linker._initializerTypeInferenceCycle == null);
|
||||
Linker._initializerTypeInferenceCycle =
|
||||
compilationUnit.library.libraryCycleForLink;
|
||||
Linker._isPerformingVariableTypeInference = true;
|
||||
try {
|
||||
new TypeInferenceDependencyWalker().walk(_typeInferenceNode);
|
||||
assert(_inferredType != null);
|
||||
} finally {
|
||||
Linker._initializerTypeInferenceCycle = null;
|
||||
Linker._isPerformingVariableTypeInference = false;
|
||||
}
|
||||
} else if (compilationUnit.isInBuildUnit) {
|
||||
_inferredType = DynamicTypeImpl.instance;
|
||||
|
|
|
@ -15,6 +15,7 @@ import 'instance_member_inference_class_test.dart'
|
|||
import 'instance_member_inference_mixin_test.dart'
|
||||
as instance_member_inference_mixin_test;
|
||||
import 'mixin_test.dart' as mixin_test;
|
||||
import 'top_type_inference_test.dart' as top_type_inference_test;
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
|
@ -27,5 +28,6 @@ main() {
|
|||
instance_member_inference_class_test.main();
|
||||
instance_member_inference_mixin_test.main();
|
||||
mixin_test.main();
|
||||
top_type_inference_test.main();
|
||||
}, name: 'resolution');
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// 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 'driver_resolution.dart';
|
||||
import 'resolution.dart';
|
||||
import 'task_resolution.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(TopTypeInferenceDriverResolutionTest);
|
||||
defineReflectiveTests(TopTypeInferenceTaskResolutionTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class TopTypeInferenceDriverResolutionTest extends DriverResolutionTest
|
||||
with TopTypeInstanceMixin {}
|
||||
|
||||
@reflectiveTest
|
||||
class TopTypeInferenceTaskResolutionTest extends TaskResolutionTest
|
||||
with TopTypeInstanceMixin {}
|
||||
|
||||
abstract class TopTypeInstanceMixin implements ResolutionTest {
|
||||
test_referenceInstanceVariable_withDeclaredType() async {
|
||||
addTestFile(r'''
|
||||
class A {
|
||||
final int a = b + 1;
|
||||
}
|
||||
final b = new A().a;
|
||||
''');
|
||||
await resolveTestFile();
|
||||
assertNoTestErrors();
|
||||
|
||||
assertElementTypeString(findElement.field('a').type, 'int');
|
||||
assertElementTypeString(findElement.topVar('b').type, 'int');
|
||||
}
|
||||
|
||||
test_referenceInstanceVariable_withoutDeclaredType() async {
|
||||
addTestFile(r'''
|
||||
class A {
|
||||
final a = b + 1;
|
||||
}
|
||||
final b = new A().a;
|
||||
''');
|
||||
await resolveTestFile();
|
||||
assertTestErrors([StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
|
||||
|
||||
assertElementTypeDynamic(findElement.field('a').type);
|
||||
assertElementTypeDynamic(findElement.topVar('b').type);
|
||||
}
|
||||
}
|
|
@ -527,7 +527,7 @@ var x = new C().f; // Inferred type: int
|
|||
''');
|
||||
LibraryElementForLink library = linker.getLibrary(testDartUri);
|
||||
expect(_getVariable(library.getContainedName('x')).inferredType.toString(),
|
||||
'int');
|
||||
'dynamic');
|
||||
}
|
||||
|
||||
void test_inferredTypeFromOutsideBuildUnit_instanceField_toInstanceField() {
|
||||
|
@ -545,7 +545,7 @@ class D {
|
|||
''');
|
||||
LibraryElementForLink library = linker.getLibrary(testDartUri);
|
||||
ClassElementForLink_Class classD = library.getContainedName('D');
|
||||
expect(classD.fields[0].inferredType.toString(), 'int');
|
||||
expect(classD.fields[0].inferredType.toString(), 'dynamic');
|
||||
}
|
||||
|
||||
void test_inferredTypeFromOutsideBuildUnit_methodParamType_viaInheritance() {
|
||||
|
|
|
@ -697,7 +697,7 @@ var t1 = x;
|
|||
''');
|
||||
checkElementText(library, r'''
|
||||
import 'a.dart';
|
||||
int t1;
|
||||
dynamic t1;
|
||||
''');
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue