Emit a compile-time error on incorrect types of initializing formals

Fixes #32526.

Bug: http://dartbug.com/32526
Change-Id: I1e4738937ade7592f7fb1d16bf485ad4ccd077c2
Reviewed-on: https://dart-review.googlesource.com/46801
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
Reviewed-by: Peter von der Ahé <ahe@google.com>
This commit is contained in:
Dmitry Stefantsov 2018-05-31 13:31:42 +00:00 committed by commit-bot@chromium.org
parent b62b438e8a
commit 00f75adfaf
10 changed files with 100 additions and 33 deletions

View file

@ -2813,6 +2813,59 @@ const MessageCode messageInitializedVariableInForEach = const MessageCode(
tip:
r"""Try removing the initializer, or using a different kind of loop.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
String name,
DartType _type,
DartType
_type2)> templateInitializingFormalTypeMismatch = const Template<
Message Function(String name, DartType _type, DartType _type2)>(
messageTemplate:
r"""The type of parameter '#name' (#type) is not a subtype of the corresponding field's type (#type2).""",
tipTemplate:
r"""Try changing the type of parameter '#name' to a subtype of #type2.""",
withArguments: _withArgumentsInitializingFormalTypeMismatch);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String name, DartType _type, DartType _type2)>
codeInitializingFormalTypeMismatch =
const Code<Message Function(String name, DartType _type, DartType _type2)>(
"InitializingFormalTypeMismatch",
templateInitializingFormalTypeMismatch,
analyzerCode: "INVALID_PARAMETER_DECLARATION",
dart2jsCode: "*fatal*",
severity: Severity.errorLegacyWarning);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsInitializingFormalTypeMismatch(
String name, DartType _type, DartType _type2) {
NameSystem nameSystem = new NameSystem();
StringBuffer buffer = new StringBuffer();
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
String type = '$buffer';
buffer = new StringBuffer();
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type2);
String type2 = '$buffer';
return new Message(codeInitializingFormalTypeMismatch,
message:
"""The type of parameter '$name' ($type) is not a subtype of the corresponding field's type ($type2).""",
tip: """Try changing the type of parameter '$name' to a subtype of $type2.""",
arguments: {'name': name, 'type': _type, 'type2': _type2});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeInitializingFormalTypeMismatchField =
messageInitializingFormalTypeMismatchField;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageInitializingFormalTypeMismatchField =
const MessageCode("InitializingFormalTypeMismatchField",
severity: Severity.context,
message: r"""The field that corresponds to the parameter.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(Uri uri_)> templateInputFileNotFound =
const Template<Message Function(Uri uri_)>(

View file

@ -585,7 +585,8 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
true,
formal.name,
formal.charOffset,
toExpression(new VariableGet(formal.declaration)));
toExpression(new VariableGet(formal.declaration)),
formalType: formal.declaration.type);
}
member.addInitializer(initializer, _typeInferrer);
}
@ -3914,9 +3915,19 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
return initializer;
}
/// Parameter [formalType] should only be passed in the special case of
/// building a field initializer as a desugaring of an initializing formal
/// parameter. The spec says the following:
///
/// "If an explicit type is attached to the initializing formal, that is its
/// static type. Otherwise, the type of an initializing formal named _id_ is
/// _Tid_, where _Tid_ is the type of the instance variable named _id_ in the
/// immediately enclosing class. It is a static warning if the static type of
/// _id_ is not a subtype of _Tid_."
@override
Initializer buildFieldInitializer(
bool isSynthetic, String name, int offset, Expression expression) {
bool isSynthetic, String name, int offset, Expression expression,
{DartType formalType}) {
Declaration builder =
classBuilder.scope.local[name] ?? classBuilder.origin.scope.local[name];
if (builder is KernelFieldBuilder && builder.isInstanceMember) {
@ -3950,6 +3961,21 @@ abstract class BodyBuilder<Expression, Statement, Arguments>
charOffset: offset)))),
offset);
} else {
if (library.loader.target.strongMode &&
formalType != null &&
!_typeInferrer.typeSchemaEnvironment
.isSubtypeOf(formalType, builder.field.type)) {
library.addProblem(
fasta.templateInitializingFormalTypeMismatch
.withArguments(name, formalType, builder.field.type),
offset,
noLength,
uri,
context: [
fasta.messageInitializingFormalTypeMismatchField
.withLocation(builder.fileUri, builder.charOffset, noLength)
]);
}
return new ShadowFieldInitializer(
builder.field, toKernelExpression(expression))
..fileOffset = offset

View file

@ -80,7 +80,8 @@ abstract class ExpressionGeneratorHelper<Expression, Statement, Arguments>
Initializer buildInvalidInitializer(Expression expression, [int offset]);
Initializer buildFieldInitializer(
bool isSynthetic, String name, int offset, Expression expression);
bool isSynthetic, String name, int offset, Expression expression,
{DartType formalType});
Initializer buildSuperInitializer(
bool isSynthetic, Constructor constructor, Arguments arguments,

View file

@ -2207,3 +2207,19 @@ ForInLoopExactlyOneVariable:
template: "A for-in loop can't have more than one loop variable."
severity: ERROR
statement: "for (var x, y in []) {}"
InitializingFormalTypeMismatch:
template: "The type of parameter '#name' (#type) is not a subtype of the corresponding field's type (#type2)."
tip: "Try changing the type of parameter '#name' to a subtype of #type2."
severity: ERROR_LEGACY_WARNING
analyzerCode: INVALID_PARAMETER_DECLARATION
dart2jsCode: "*fatal*"
script: >
class C {
int x;
C(num this.x);
}
InitializingFormalTypeMismatchField:
template: "The field that corresponds to the parameter."
severity: CONTEXT

View file

@ -57,6 +57,7 @@ LibTest/math/pow_A10_t01: CompileTimeError
Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: MissingCompileTimeError
Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: MissingCompileTimeError
Language/Classes/Constructors/Constant_Constructors/invalid_constant_initializer_t02: MissingCompileTimeError
Language/Classes/Constructors/Generative_Constructors/static_type_t01: CompileTimeError
Language/Classes/Instance_Methods/same_name_setter_t02: CompileTimeError # Issue 14736
Language/Classes/Setters/name_t03: CompileTimeError
Language/Classes/Setters/name_t04: CompileTimeError

View file

@ -1152,7 +1152,6 @@ override_inheritance_field_test/50: CompileTimeError
override_inheritance_generic_test/02: CompileTimeError
override_inheritance_method_test/28: CompileTimeError
override_inheritance_method_test/29: CompileTimeError
parameter_initializer_test: CompileTimeError
parser_quirks_test: CompileTimeError
regress_22976_test/01: CompileTimeError
regress_22976_test/02: CompileTimeError

View file

@ -918,8 +918,6 @@ compile_time_constant_k_test/02: MissingCompileTimeError
compile_time_constant_k_test/03: MissingCompileTimeError
compile_time_constant_o_test/01: MissingCompileTimeError
compile_time_constant_o_test/02: MissingCompileTimeError
compile_time_constant_static2_test/04: MissingCompileTimeError
compile_time_constant_static3_test/04: MissingCompileTimeError
compile_time_constant_static5_test/11: CompileTimeError
compile_time_constant_static5_test/16: CompileTimeError
compile_time_constant_static5_test/21: CompileTimeError
@ -1047,8 +1045,6 @@ identical_const_test/03: MissingCompileTimeError
identical_const_test/04: MissingCompileTimeError
if_null_precedence_test/none: RuntimeError
infinity_test: RuntimeError # non JS number semantics - Issue 4984
initializing_formal_type_annotation_test/01: MissingCompileTimeError
initializing_formal_type_annotation_test/02: MissingCompileTimeError
instance_creation_in_function_annotation_test: RuntimeError
instantiate_tearoff_of_call_test: CompileTimeError
int64_literal_test/01: RuntimeError
@ -1458,8 +1454,6 @@ compile_time_constant_k_test/02: MissingCompileTimeError
compile_time_constant_k_test/03: MissingCompileTimeError
compile_time_constant_o_test/01: MissingCompileTimeError
compile_time_constant_o_test/02: MissingCompileTimeError
compile_time_constant_static2_test/04: MissingCompileTimeError
compile_time_constant_static3_test/04: MissingCompileTimeError
compile_time_constant_static5_test/11: CompileTimeError
compile_time_constant_static5_test/16: CompileTimeError
compile_time_constant_static5_test/21: CompileTimeError
@ -1581,8 +1575,6 @@ identical_const_test/03: MissingCompileTimeError
identical_const_test/04: MissingCompileTimeError
if_null_precedence_test/none: RuntimeError
infinity_test: RuntimeError # non JS number semantics - Issue 4984
initializing_formal_type_annotation_test/01: MissingCompileTimeError
initializing_formal_type_annotation_test/02: MissingCompileTimeError
instance_creation_in_function_annotation_test: RuntimeError
instantiate_tearoff_of_call_test: CompileTimeError
int64_literal_test/01: RuntimeError

View file

@ -141,7 +141,6 @@ override_inheritance_field_test/50: CompileTimeError
override_inheritance_generic_test/02: CompileTimeError
override_inheritance_method_test/28: CompileTimeError
override_inheritance_method_test/29: CompileTimeError
parameter_initializer_test: CompileTimeError
part_refers_to_core_library_test/01: Crash
prefix_shadow_test/01: MissingCompileTimeError # Issue 33005
regress_23089_test: MissingCompileTimeError
@ -322,8 +321,6 @@ compile_time_constant_k_test/02: MissingCompileTimeError
compile_time_constant_k_test/03: MissingCompileTimeError
compile_time_constant_o_test/01: MissingCompileTimeError
compile_time_constant_o_test/02: MissingCompileTimeError
compile_time_constant_static2_test/04: MissingCompileTimeError
compile_time_constant_static3_test/04: MissingCompileTimeError
compile_time_constant_static4_test/02: MissingCompileTimeError
compile_time_constant_static4_test/03: MissingCompileTimeError
compile_time_constant_static5_test/11: CompileTimeError # Issue 31537
@ -415,8 +412,6 @@ implicit_creation/implicit_const_not_default_values_test/e3: Pass
implicit_creation/implicit_const_not_default_values_test/e30: Pass
implicit_creation/implicit_const_not_default_values_test/e6: Pass
implicit_creation/implicit_const_not_default_values_test/e9: Pass
initializing_formal_type_annotation_test/01: MissingCompileTimeError
initializing_formal_type_annotation_test/02: MissingCompileTimeError
instantiate_tearoff_of_call_test: CompileTimeError
issue18628_2_test/01: MissingCompileTimeError
issue31596_override_test/07: MissingCompileTimeError

View file

@ -699,8 +699,6 @@ regress_30339_test: RuntimeError
type_variable_bounds4_test/01: RuntimeError
[ $compiler == dartk && $runtime == vm && !$checked && $strong ]
compile_time_constant_static2_test/04: MissingCompileTimeError
compile_time_constant_static3_test/04: MissingCompileTimeError
conditional_rewrite_test: RuntimeError # Issue 31402 (Not)
type_error_test: RuntimeError # Issue 31402 (Variable declaration)
@ -772,8 +770,6 @@ generic_no_such_method_dispatcher_test: CompileTimeError # Issue 31533
generic_tearoff_test: CompileTimeError
generic_tearoff_test: RuntimeError
if_null_evaluation_order_test: Pass
initializing_formal_type_annotation_test/01: MissingCompileTimeError
initializing_formal_type_annotation_test/02: MissingCompileTimeError
instantiate_tearoff_of_call_test: CompileTimeError
issue18628_2_test/01: MissingCompileTimeError
issue31596_super_test/01: CompileTimeError
@ -984,8 +980,6 @@ type_variable_bounds4_test/01: RuntimeError
[ $compiler == dartkp && $runtime == dart_precompiled && !$checked && $strong ]
assertion_initializer_const_error_test/01: MissingCompileTimeError
assertion_initializer_const_function_error_test/01: MissingCompileTimeError
compile_time_constant_static2_test/04: MissingCompileTimeError
compile_time_constant_static3_test/04: MissingCompileTimeError
conditional_rewrite_test: RuntimeError # Issue 31402 (Not)
implicit_downcast_during_combiner_test: RuntimeError
implicit_downcast_during_compound_assignment_test: RuntimeError
@ -1115,8 +1109,6 @@ implicit_downcast_during_variable_declaration_test: Pass # Correctly passes.
implicit_downcast_during_while_statement_test: Pass # Correctly passes.
implicit_downcast_during_yield_star_test: Pass # Correctly passes.
implicit_downcast_during_yield_test: Pass # Correctly passes.
initializing_formal_type_annotation_test/01: MissingCompileTimeError
initializing_formal_type_annotation_test/02: MissingCompileTimeError
instance_creation_in_function_annotation_test: SkipByDesign
instantiate_tearoff_of_call_test: CompileTimeError
invocation_mirror2_test: SkipByDesign
@ -1483,10 +1475,6 @@ const_instance_field_test/01: Crash # Issue 32326.
deopt_inlined_function_lazy_test: Skip
[ $fasta && $strong ]
compile_time_constant_static2_test/04: MissingCompileTimeError
compile_time_constant_static3_test/04: MissingCompileTimeError
initializing_formal_type_annotation_test/01: MissingCompileTimeError
initializing_formal_type_annotation_test/02: MissingCompileTimeError
issue18628_2_test/01: MissingCompileTimeError
map_literal3_test/03: MissingCompileTimeError
redirecting_factory_infinite_steps_test/01: MissingCompileTimeError

View file

@ -9,9 +9,6 @@ class ParameterInitializerTest {
var obj = new Foo.untyped(1);
Expect.equals(1, obj.x);
obj = new Foo.supertype(9);
Expect.equals(9, obj.x);
obj = new Foo.subtype(7);
Expect.equals(7, obj.x);
@ -40,7 +37,6 @@ class Foo {
}
Foo.untyped(this.x) {}
Foo.supertype(Object this.x) {}
Foo.subtype(int this.x) {}
Foo.optional([this.x = 5]) {}