mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
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:
parent
b62b438e8a
commit
00f75adfaf
10 changed files with 100 additions and 33 deletions
|
@ -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_)>(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]) {}
|
||||
|
||||
|
|
Loading…
Reference in a new issue