remove "infer from overrides" option which is now obsolete

R=vsm@google.com

Review URL: https://codereview.chromium.org/1398873002 .
This commit is contained in:
John Messerly 2015-10-09 10:56:21 -07:00
parent 3be8a25942
commit 1147d8a5b9
7 changed files with 86 additions and 173 deletions

View file

@ -21,9 +21,8 @@ class _OverrideChecker {
bool _failure = false;
final TypeRules _rules;
final AnalysisErrorListener _reporter;
final bool _inferFromOverrides;
_OverrideChecker(this._rules, this._reporter, StrongModeOptions options)
: _inferFromOverrides = options.inferFromOverrides;
_OverrideChecker(this._rules, this._reporter);
void check(ClassDeclaration node) {
if (node.element.type.isObject) return;
@ -336,11 +335,10 @@ class CodeChecker extends RecursiveAstVisitor {
_overrideChecker._failure = false;
}
CodeChecker(TypeRules rules, AnalysisErrorListener reporter,
StrongModeOptions options)
CodeChecker(TypeRules rules, AnalysisErrorListener reporter)
: rules = rules,
reporter = reporter,
_overrideChecker = new _OverrideChecker(rules, reporter, options);
_overrideChecker = new _OverrideChecker(rules, reporter);
@override
void visitCompilationUnit(CompilationUnit unit) {

View file

@ -160,23 +160,17 @@ class LibraryResolverWithInference extends LibraryResolver {
if (supertypeClass != null) visit(supertypeClass);
}
if (_options.inferFromOverrides) {
// Infer field types from overrides first, otherwise from initializers.
var pending = new Set<VariableDeclaration>();
cls.members
.where(_isInstanceField)
.forEach((f) => _inferFieldTypeFromOverride(f, pending));
if (pending.isNotEmpty) _inferVariableFromInitializer(pending);
// Infer field types from overrides first, otherwise from initializers.
var pending = new Set<VariableDeclaration>();
cls.members
.where(_isInstanceField)
.forEach((f) => _inferFieldTypeFromOverride(f, pending));
if (pending.isNotEmpty) _inferVariableFromInitializer(pending);
// Infer return-types and param-types from overrides
cls.members
.where((m) => m is MethodDeclaration && !m.isStatic)
.forEach(_inferMethodTypesFromOverride);
} else {
_inferVariableFromInitializer(cls.members
.where(_isInstanceField)
.expand((f) => f.fields.variables));
}
// Infer return-types and param-types from overrides
cls.members
.where((m) => m is MethodDeclaration && !m.isStatic)
.forEach(_inferMethodTypesFromOverride);
}
classes.forEach(visit);
}

View file

@ -354,15 +354,11 @@ abstract class AbstractCompiler {
[AnalysisErrorListener reporter])
: context = context,
options = options,
checker = createChecker(context.typeProvider, options.strongOptions,
checker = new CodeChecker(
new RestrictedRules(context.typeProvider,
options: options.strongOptions),
reporter ?? AnalysisErrorListener.NULL_LISTENER);
static CodeChecker createChecker(TypeProvider typeProvider,
StrongModeOptions options, AnalysisErrorListener reporter) {
return new CodeChecker(
new RestrictedRules(typeProvider, options: options), reporter, options);
}
String get outputDir => options.codegenOptions.outputDir;
TypeRules get rules => checker.rules;
AnalysisErrorListener get reporter => checker.reporter;

View file

@ -45,7 +45,7 @@ class StrongChecker {
.instance.useTaskModel) enableDevCompilerInference(context, options);
var rules = new RestrictedRules(context.typeProvider, options: options);
var reporter = new _ErrorCollector(options.hints);
var checker = new CodeChecker(rules, reporter, options);
var checker = new CodeChecker(rules, reporter);
return new StrongChecker._(context, checker, reporter);
}
@ -79,10 +79,6 @@ class _ErrorCollector implements AnalysisErrorListener {
}
class StrongModeOptions {
/// Whether to infer return types and field types from overridden members.
final bool inferFromOverrides;
static const inferFromOverridesDefault = true;
/// Whether to infer types for consts and fields by looking at initializers on
/// the RHS. For example, in a constant declaration like:
///
@ -123,7 +119,6 @@ class StrongModeOptions {
const StrongModeOptions(
{this.hints: false,
this.inferFromOverrides: inferFromOverridesDefault,
this.inferTransitively: inferTransitivelyDefault,
this.onlyInferConstsAndFinalFields: onlyInferConstAndFinalFieldsDefault,
this.inferDownwards: inferDownwardsDefault,
@ -133,7 +128,6 @@ class StrongModeOptions {
StrongModeOptions.fromArguments(ArgResults args, {String prefix: ''})
: relaxedCasts = args[prefix + 'relaxed-casts'],
inferDownwards = args[prefix + 'infer-downwards'],
inferFromOverrides = args[prefix + 'infer-from-overrides'],
inferTransitively = args[prefix + 'infer-transitively'],
onlyInferConstsAndFinalFields = args[prefix + 'infer-only-finals'],
nonnullableTypes = _optionsToList(args[prefix + 'nonnullable'],
@ -160,11 +154,6 @@ class StrongModeOptions {
help: 'Infer types downwards from local context',
defaultsTo: inferDownwardsDefault,
hide: hide)
..addFlag(prefix + 'infer-from-overrides',
help: 'Infer unspecified types of fields and return types from\n'
'definitions in supertypes',
defaultsTo: inferFromOverridesDefault,
hide: hide)
..addFlag(prefix + 'infer-transitively',
help: 'Infer consts/fields from definitions in other libraries',
defaultsTo: inferTransitivelyDefault,
@ -178,8 +167,7 @@ class StrongModeOptions {
bool operator ==(Object other) {
if (other is! StrongModeOptions) return false;
StrongModeOptions s = other;
return inferFromOverrides == s.inferFromOverrides &&
inferTransitively == s.inferTransitively &&
return inferTransitively == s.inferTransitively &&
onlyInferConstsAndFinalFields == s.onlyInferConstsAndFinalFields &&
inferDownwards == s.inferDownwards &&
relaxedCasts == s.relaxedCasts &&

View file

@ -1346,10 +1346,8 @@ void main() {
'''
});
testChecker(
'field/field override',
{
'/main.dart': '''
testChecker('field/field override', {
'/main.dart': '''
class A {}
class B extends A {}
class C extends B {}
@ -1368,13 +1366,10 @@ void main() {
/*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/dynamic f4;
}
'''
},
inferFromOverrides: true);
});
testChecker(
'getter/getter override',
{
'/main.dart': '''
testChecker('getter/getter override', {
'/main.dart': '''
class A {}
class B extends A {}
class C extends B {}
@ -1393,13 +1388,10 @@ void main() {
/*severe:InvalidMethodOverride*/dynamic get f4 => null;
}
'''
},
inferFromOverrides: true);
});
testChecker(
'field/getter override',
{
'/main.dart': '''
testChecker('field/getter override', {
'/main.dart': '''
class A {}
class B extends A {}
class C extends B {}
@ -1418,8 +1410,7 @@ void main() {
/*severe:InvalidMethodOverride*/dynamic get f4 => null;
}
'''
},
inferFromOverrides: true);
});
testChecker('setter/setter override', {
'/main.dart': '''
@ -1475,10 +1466,8 @@ void main() {
'''
});
testChecker(
'method override',
{
'/main.dart': '''
testChecker('method override', {
'/main.dart': '''
class A {}
class B extends A {}
class C extends B {}
@ -1501,8 +1490,7 @@ void main() {
/*severe:InvalidMethodOverride*/dynamic m6(dynamic value) {}
}
'''
},
inferFromOverrides: true);
});
testChecker('unary operators', {
'/main.dart': '''

View file

@ -559,10 +559,8 @@ void main() {
});
group('infer type on overridden fields', () {
testChecker(
'2',
{
'/main.dart': '''
testChecker('2', {
'/main.dart': '''
class A {
int x = 2;
}
@ -576,13 +574,10 @@ void main() {
int z = new B().x;
}
'''
},
inferFromOverrides: true);
});
testChecker(
'4',
{
'/main.dart': '''
testChecker('4', {
'/main.dart': '''
class A {
int x = 2;
}
@ -596,37 +591,29 @@ void main() {
int z = new B().x;
}
'''
},
inferFromOverrides: true);
});
});
group('infer types on generic instantiations', () {
for (bool infer in [true, false]) {
testChecker(
'infer: $infer',
{
'/main.dart': '''
class A<T> {
T x;
}
testChecker('infer', {
'/main.dart': '''
class A<T> {
T x;
}
class B implements A<int> {
/*severe:InvalidMethodOverride*/dynamic get x => 3;
}
class B implements A<int> {
/*severe:InvalidMethodOverride*/dynamic get x => 3;
}
foo() {
String y = /*info:DynamicCast*/new B().x;
int z = /*info:DynamicCast*/new B().x;
}
'''
},
inferFromOverrides: infer);
}
foo() {
String y = /*info:DynamicCast*/new B().x;
int z = /*info:DynamicCast*/new B().x;
}
'''
});
testChecker(
'3',
{
'/main.dart': '''
testChecker('3', {
'/main.dart': '''
class A<T> {
T x;
T w;
@ -642,13 +629,10 @@ void main() {
int z = new B().x;
}
'''
},
inferFromOverrides: true);
});
testChecker(
'4',
{
'/main.dart': '''
testChecker('4', {
'/main.dart': '''
class A<T> {
T x;
}
@ -663,13 +647,10 @@ void main() {
String z = new B<String>().x;
}
'''
},
inferFromOverrides: true);
});
testChecker(
'5',
{
'/main.dart': '''
testChecker('5', {
'/main.dart': '''
abstract class I<E> {
String m(a, String f(v, T e));
}
@ -695,19 +676,16 @@ void main() {
String z = new B().m(null, null);
}
'''
},
inferFromOverrides: true);
});
});
testChecker(
'infer type regardless of declaration order or cycles',
{
'/b.dart': '''
testChecker('infer type regardless of declaration order or cycles', {
'/b.dart': '''
import 'main.dart';
class B extends A { }
''',
'/main.dart': '''
'/main.dart': '''
import 'b.dart';
class C extends B {
get x;
@ -720,22 +698,19 @@ void main() {
String y = /*severe:StaticTypeError*/new C().x;
}
'''
},
inferFromOverrides: true);
});
// Note: this is a regression test for a non-deterministic behavior we used to
// have with inference in library cycles. If you see this test flake out,
// change `test` to `skip_test` and reopen bug #48.
testChecker(
'infer types on generic instantiations in library cycle',
{
'/a.dart': '''
testChecker('infer types on generic instantiations in library cycle', {
'/a.dart': '''
import 'main.dart';
abstract class I<E> {
A<E> m(a, String f(v, int e));
}
''',
'/main.dart': '''
'/main.dart': '''
import 'a.dart';
abstract class A<E> implements I<E> {
@ -760,15 +735,11 @@ void main() {
String z = new B<String>().m(null, null).value;
}
'''
},
inferFromOverrides: true);
});
group('do not infer overridden fields that explicitly say dynamic', () {
for (bool infer in [true, false]) {
testChecker(
'infer: $infer',
{
'/main.dart': '''
testChecker('infer', {
'/main.dart': '''
class A {
int x = 2;
}
@ -782,15 +753,11 @@ void main() {
int z = /*info:DynamicCast*/new B().x;
}
'''
},
inferFromOverrides: infer);
}
});
});
testChecker(
'conflicts can happen',
{
'/main.dart': '''
testChecker('conflicts can happen', {
'/main.dart': '''
class I1 {
int x;
}
@ -815,13 +782,10 @@ void main() {
/*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/get a => null;
}
'''
},
inferFromOverrides: true);
});
testChecker(
'conflicts can happen 2',
{
'/main.dart': '''
testChecker('conflicts can happen 2', {
'/main.dart': '''
class I1 {
int x;
}
@ -850,13 +814,11 @@ void main() {
/*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/get a => null;
}
'''
},
inferFromOverrides: true);
});
testChecker(
'infer from RHS only if it wont conflict with overridden fields',
{
'/main.dart': '''
'infer from RHS only if it wont conflict with overridden fields', {
'/main.dart': '''
class A {
var x;
}
@ -870,13 +832,11 @@ void main() {
int z = /*info:DynamicCast*/new B().x;
}
'''
},
inferFromOverrides: true);
});
testChecker(
'infer from RHS only if it wont conflict with overridden fields 2',
{
'/main.dart': '''
'infer from RHS only if it wont conflict with overridden fields 2', {
'/main.dart': '''
class A {
final x;
}
@ -890,13 +850,10 @@ void main() {
int z = new B().x;
}
'''
},
inferFromOverrides: true);
});
testChecker(
'infer correctly on multiple variables declared together',
{
'/main.dart': '''
testChecker('infer correctly on multiple variables declared together', {
'/main.dart': '''
class A {
var x, y = 2, z = "hi";
}
@ -920,8 +877,7 @@ void main() {
i = new B().w;
}
'''
},
inferFromOverrides: true);
});
testChecker(
'infer consts transitively',
@ -946,7 +902,6 @@ void main() {
}
'''
},
inferFromOverrides: true,
inferTransitively: true);
testChecker(
@ -974,7 +929,6 @@ void main() {
}
'''
},
inferFromOverrides: true,
inferTransitively: true);
testChecker(
@ -993,7 +947,6 @@ void main() {
}
'''
},
inferFromOverrides: true,
inferTransitively: true);
testChecker(
@ -1025,7 +978,6 @@ void main() {
}
'''
},
inferFromOverrides: true,
inferTransitively: true);
testChecker(
@ -1045,7 +997,6 @@ void main() {
'''
},
inferFromOverrides: true,
inferTransitively: true);
testChecker(

View file

@ -77,7 +77,6 @@ void testChecker(String name, Map<String, String> testFiles,
customUrlMappings: const {},
relaxedCasts: true,
inferDownwards: StrongModeOptions.inferDownwardsDefault,
inferFromOverrides: StrongModeOptions.inferFromOverridesDefault,
inferTransitively: StrongModeOptions.inferTransitivelyDefault,
nonnullableTypes: StrongModeOptions.NONNULLABLE_TYPES}) {
test(name, () {
@ -102,7 +101,6 @@ void testChecker(String name, Map<String, String> testFiles,
new StrongModeOptions(
relaxedCasts: relaxedCasts,
inferDownwards: inferDownwards,
inferFromOverrides: inferFromOverrides,
inferTransitively: inferTransitively,
nonnullableTypes: nonnullableTypes,
hints: true));