mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:58:29 +00:00
[ddc-kernel] Fix how mock members for fields are generated
Bug: Change-Id: I6b910c9faa741fd8c8121250fbce55e9a9d29c50 Reviewed-on: https://dart-review.googlesource.com/24121 Reviewed-by: Kevin Millikin <kmillikin@google.com> Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
parent
db383f64ad
commit
316bc2d96e
|
@ -1562,8 +1562,9 @@ class ProgramCompiler
|
|||
}
|
||||
}
|
||||
|
||||
jsMethods.addAll(_classProperties.mockMembers.values
|
||||
.map((e) => _implementMockMember(e, c)));
|
||||
for (Member m in _classProperties.mockMembers.values) {
|
||||
_addMockMembers(m, c, jsMethods);
|
||||
}
|
||||
|
||||
// If the type doesn't have an `iterator`, but claims to implement Iterable,
|
||||
// we inject the adaptor method here, as it's less code size to put the
|
||||
|
@ -1719,69 +1720,108 @@ class ProgramCompiler
|
|||
/// return core.bool.as(this.noSuchMethod(
|
||||
/// new dart.InvocationImpl.new('eatFood', args)));
|
||||
/// }
|
||||
JS.Method _implementMockMember(Procedure method, Class c) {
|
||||
var invocationProps = <JS.Property>[];
|
||||
addProperty(String name, JS.Expression value) {
|
||||
invocationProps.add(new JS.Property(js.string(name), value));
|
||||
}
|
||||
///
|
||||
/// Same technique is applied if interface I has fields, and C doesn't declare
|
||||
/// neither the fields nor the corresponding getters and setters.
|
||||
Iterable<JS.Method> _addMockMembers(
|
||||
Member member, Class c, List<JS.Method> jsMethods) {
|
||||
JS.Method implementMockMember(
|
||||
List<TypeParameter> typeParameters,
|
||||
List<VariableDeclaration> namedParameters,
|
||||
ProcedureKind mockMemberKind,
|
||||
DartType returnType) {
|
||||
assert(mockMemberKind != ProcedureKind.Factory);
|
||||
|
||||
var args = new JS.TemporaryId('args');
|
||||
var function = method.function;
|
||||
var typeParams = _emitTypeFormals(function.typeParameters);
|
||||
var fnArgs = new List<JS.Parameter>.from(typeParams);
|
||||
JS.Expression positionalArgs;
|
||||
|
||||
if (function.namedParameters.isNotEmpty) {
|
||||
addProperty('namedArguments', _callHelper('extractNamedArgs(#)', [args]));
|
||||
}
|
||||
|
||||
if (!method.isAccessor) {
|
||||
addProperty('isMethod', js.boolean(true));
|
||||
|
||||
fnArgs.add(new JS.RestParameter(args));
|
||||
positionalArgs = args;
|
||||
} else {
|
||||
if (method.isGetter) {
|
||||
addProperty('isGetter', js.boolean(true));
|
||||
|
||||
positionalArgs = new JS.ArrayInitializer([]);
|
||||
} else if (method.isSetter) {
|
||||
addProperty('isSetter', js.boolean(true));
|
||||
|
||||
fnArgs.add(args);
|
||||
positionalArgs = new JS.ArrayInitializer([args]);
|
||||
var invocationProps = <JS.Property>[];
|
||||
addProperty(String name, JS.Expression value) {
|
||||
invocationProps.add(new JS.Property(js.string(name), value));
|
||||
}
|
||||
|
||||
var args = new JS.TemporaryId('args');
|
||||
var typeParams = _emitTypeFormals(typeParameters);
|
||||
var fnArgs = new List<JS.Parameter>.from(typeParams);
|
||||
JS.Expression positionalArgs;
|
||||
|
||||
if (namedParameters.isNotEmpty) {
|
||||
addProperty(
|
||||
'namedArguments', _callHelper('extractNamedArgs(#)', [args]));
|
||||
}
|
||||
|
||||
if (mockMemberKind != ProcedureKind.Getter &&
|
||||
mockMemberKind != ProcedureKind.Setter) {
|
||||
addProperty('isMethod', js.boolean(true));
|
||||
|
||||
fnArgs.add(new JS.RestParameter(args));
|
||||
positionalArgs = args;
|
||||
} else {
|
||||
if (mockMemberKind == ProcedureKind.Getter) {
|
||||
addProperty('isGetter', js.boolean(true));
|
||||
|
||||
positionalArgs = new JS.ArrayInitializer([]);
|
||||
} else if (mockMemberKind == ProcedureKind.Setter) {
|
||||
addProperty('isSetter', js.boolean(true));
|
||||
|
||||
fnArgs.add(args);
|
||||
positionalArgs = new JS.ArrayInitializer([args]);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeParams.isNotEmpty) {
|
||||
addProperty('typeArguments', new JS.ArrayInitializer(typeParams));
|
||||
}
|
||||
|
||||
var fnBody =
|
||||
js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [
|
||||
_runtimeModule,
|
||||
_declareMemberName(member),
|
||||
positionalArgs,
|
||||
new JS.ObjectInitializer(invocationProps)
|
||||
]);
|
||||
|
||||
if (!types.isTop(returnType)) {
|
||||
fnBody = js.call('#._check(#)', [_emitType(returnType), fnBody]);
|
||||
}
|
||||
|
||||
var fn = new JS.Fun(fnArgs, js.statement('{ return #; }', [fnBody]),
|
||||
typeParams: typeParams);
|
||||
|
||||
return new JS.Method(
|
||||
_declareMemberName(member,
|
||||
useExtension: _extensionTypes.isNativeClass(c)),
|
||||
fn,
|
||||
isGetter: mockMemberKind == ProcedureKind.Getter,
|
||||
isSetter: mockMemberKind == ProcedureKind.Setter,
|
||||
isStatic: false);
|
||||
}
|
||||
|
||||
if (typeParams.isNotEmpty) {
|
||||
addProperty('typeArguments', new JS.ArrayInitializer(typeParams));
|
||||
if (member is Field) {
|
||||
jsMethods.add(implementMockMember(
|
||||
const <TypeParameter>[],
|
||||
const <VariableDeclaration>[],
|
||||
ProcedureKind.Getter,
|
||||
Substitution
|
||||
.fromSupertype(
|
||||
hierarchy.getClassAsInstanceOf(c, member.enclosingClass))
|
||||
.substituteType(member.type)));
|
||||
if (!member.isFinal) {
|
||||
jsMethods.add(implementMockMember(
|
||||
const <TypeParameter>[],
|
||||
const <VariableDeclaration>[],
|
||||
ProcedureKind.Setter,
|
||||
new DynamicType()));
|
||||
}
|
||||
} else {
|
||||
Procedure procedure = member as Procedure;
|
||||
FunctionNode function = procedure.function;
|
||||
jsMethods.add(implementMockMember(
|
||||
function.typeParameters,
|
||||
function.namedParameters,
|
||||
procedure.kind,
|
||||
Substitution
|
||||
.fromSupertype(
|
||||
hierarchy.getClassAsInstanceOf(c, member.enclosingClass))
|
||||
.substituteType(function.returnType)));
|
||||
}
|
||||
|
||||
var fnBody =
|
||||
js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [
|
||||
_runtimeModule,
|
||||
_declareMemberName(method),
|
||||
positionalArgs,
|
||||
new JS.ObjectInitializer(invocationProps)
|
||||
]);
|
||||
|
||||
var returnType = Substitution
|
||||
.fromSupertype(hierarchy.getClassAsInstanceOf(c, method.enclosingClass))
|
||||
.substituteType(method.function.functionType);
|
||||
if (!types.isTop(returnType)) {
|
||||
fnBody = js.call('#._check(#)', [_emitType(returnType), fnBody]);
|
||||
}
|
||||
|
||||
var fn = new JS.Fun(fnArgs, js.statement('{ return #; }', [fnBody]),
|
||||
typeParams: typeParams);
|
||||
|
||||
return new JS.Method(
|
||||
_declareMemberName(method,
|
||||
useExtension: _extensionTypes.isNativeClass(c)),
|
||||
fn,
|
||||
isGetter: method.isGetter,
|
||||
isSetter: method.isSetter,
|
||||
isStatic: false);
|
||||
}
|
||||
|
||||
/// This is called whenever a derived class needs to introduce a new field,
|
||||
|
|
|
@ -282,25 +282,12 @@ class ClassPropertyModel {
|
|||
|
||||
for (var m in c.members) {
|
||||
if (m is Constructor) continue;
|
||||
if (m is Procedure && m.isStatic) continue;
|
||||
|
||||
var isAbstract = classIsAbstract || m.isAbstract;
|
||||
addMember(bool setter) {
|
||||
var name = m.name.name;
|
||||
if (setter) name += '=';
|
||||
if (isAbstract) {
|
||||
mockMembers[name] = m;
|
||||
} else {
|
||||
concreteMembers.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
var name = m.name.name;
|
||||
if (m is Field) {
|
||||
addMember(false);
|
||||
if (!m.isFinal) addMember(true);
|
||||
if (classIsAbstract || m.isAbstract) {
|
||||
mockMembers[m.name.name] = m;
|
||||
} else {
|
||||
var p = m as Procedure;
|
||||
if (!p.isStatic) addMember(p.isSetter);
|
||||
concreteMembers.add(m.name.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -453,19 +453,6 @@ first_class_types_literals_test/07: MissingCompileTimeError
|
|||
first_class_types_literals_test/10: MissingCompileTimeError
|
||||
first_class_types_literals_test/11: MissingCompileTimeError
|
||||
first_class_types_literals_test/12: MissingCompileTimeError
|
||||
flatten_test/01: Crash
|
||||
flatten_test/02: Crash
|
||||
flatten_test/03: Crash
|
||||
flatten_test/04: Crash
|
||||
flatten_test/05: Crash
|
||||
flatten_test/06: Crash
|
||||
flatten_test/07: Crash
|
||||
flatten_test/08: Crash
|
||||
flatten_test/09: Crash
|
||||
flatten_test/10: Crash
|
||||
flatten_test/11: Crash
|
||||
flatten_test/12: Crash
|
||||
flatten_test/none: Crash
|
||||
function_propagation_test: CompileTimeError
|
||||
function_subtype_bound_closure7_test: CompileTimeError
|
||||
function_type_parameter2_negative_test: Fail
|
||||
|
@ -743,8 +730,6 @@ mixin_type_parameters_errors_test/02: MissingCompileTimeError
|
|||
mixin_type_parameters_errors_test/03: MissingCompileTimeError
|
||||
mixin_type_parameters_errors_test/04: MissingCompileTimeError
|
||||
mixin_type_parameters_errors_test/05: MissingCompileTimeError
|
||||
mock_writable_final_field_test: Crash
|
||||
mock_writable_final_private_field_test: Crash
|
||||
multiline_newline_test/06: MissingCompileTimeError
|
||||
multiline_newline_test/06r: MissingCompileTimeError
|
||||
named_constructor_test/01: MissingCompileTimeError
|
||||
|
@ -1102,6 +1087,10 @@ expect_test: RuntimeError # Issue 29920; Expect.identical did not fail
|
|||
f_bounded_quantification3_test: RuntimeError # Issue 29920; Uncaught Error: type arguments should not be null: (F1, F2) => {
|
||||
field_increment_bailout_test: RuntimeError # Issue 29920; UnimplementedError: JsInstanceMirror.delegate unimplemented
|
||||
field_initialization_order_test/none: RuntimeError # Expect.equals(expected: <b.a.ai.bi.>, actual: <b.bi.a.ai.>) fails.
|
||||
flatten_test/05: MissingRuntimeError # Issue 29920
|
||||
flatten_test/08: MissingRuntimeError # Issue 29920
|
||||
flatten_test/09: MissingRuntimeError # Issue 29920
|
||||
flatten_test/12: MissingRuntimeError # Issue 29920
|
||||
for_variable_capture_test: RuntimeError # Issue 29920; Expect.equals(expected: <1>, actual: <0>) fails.
|
||||
function_subtype_inline2_test: RuntimeError # Expect.fail('Missing type error: 'new C.c1(m2)'.')
|
||||
function_type_alias6_test/none: RuntimeError # Expect.isTrue(false) fails.
|
||||
|
@ -1175,10 +1164,6 @@ expect_test: RuntimeError # Issue 29920
|
|||
f_bounded_quantification3_test: RuntimeError # Issue 29920
|
||||
final_field_initialization_order_test: RuntimeError # Issue 31058
|
||||
first_class_types_test: RuntimeError, OK # Strong mode reifies inferred type argument.
|
||||
flatten_test/05: MissingRuntimeError # Issue 29920
|
||||
flatten_test/08: MissingRuntimeError # Issue 29920
|
||||
flatten_test/09: MissingRuntimeError # Issue 29920
|
||||
flatten_test/12: MissingRuntimeError # Issue 29920
|
||||
fuzzy_arrows_test/03: RuntimeError # Issue 29630
|
||||
generic_method_types_test/02: RuntimeError
|
||||
getter_closure_execution_order_test: RuntimeError # Issue 29920
|
||||
|
|
Loading…
Reference in a new issue