[cfe] Handle default values on extension methods
Closes #38541 Change-Id: I078800cc98b5444c2c7f6f87b2d89bcf764bfc23 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/118582 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
1ffbebe07a
commit
b03d472e4c
@@ -6,6 +6,7 @@ library fasta.procedure_builder;
|
||||
|
||||
import 'dart:core' hide MapEntry;
|
||||
|
||||
import 'package:front_end/src/fasta/kernel/kernel_api.dart';
|
||||
import 'package:kernel/ast.dart' hide Variance;
|
||||
|
||||
import 'package:kernel/type_algebra.dart';
|
||||
@@ -361,6 +362,27 @@ abstract class FunctionBuilder extends MemberBuilder {
|
||||
return function = result;
|
||||
}
|
||||
|
||||
/// Returns the [index]th parameter of this function.
|
||||
///
|
||||
/// The index is the syntactical index, including both positional and named
|
||||
/// parameter in the order they are declared, and excluding the synthesized
|
||||
/// this parameter on extension instance members.
|
||||
VariableDeclaration getFormalParameter(int index) {
|
||||
if (isExtensionInstanceMember) {
|
||||
return formals[index + 1].variable;
|
||||
} else {
|
||||
return formals[index].variable;
|
||||
}
|
||||
}
|
||||
|
||||
/// If this is an extension instance method, the tear off closure parameter
|
||||
/// corresponding to the [index]th parameter on the instance method is
|
||||
/// returned.
|
||||
///
|
||||
/// This is used to update the default value for the closure parameter when
|
||||
/// it has been computed for the original parameter.
|
||||
VariableDeclaration getExtensionTearOffParameter(int index) => null;
|
||||
|
||||
/// Returns the parameter for 'this' synthetically added to extension
|
||||
/// instance members.
|
||||
VariableDeclaration get extensionThis {
|
||||
@@ -451,6 +473,14 @@ class ProcedureBuilder extends FunctionBuilder {
|
||||
/// the synthetically created tear off function.
|
||||
Procedure _extensionTearOff;
|
||||
|
||||
/// If this is an extension instance method then
|
||||
/// [_extensionTearOffParameterMap] holds a map from the parameters of
|
||||
/// the methods to the parameter of the closure returned in the tear-off.
|
||||
///
|
||||
/// This map is used to set the default values on the closure parameters when
|
||||
/// these have been built.
|
||||
Map<VariableDeclaration, VariableDeclaration> _extensionTearOffParameterMap;
|
||||
|
||||
ProcedureBuilder(
|
||||
List<MetadataBuilder> metadata,
|
||||
int modifiers,
|
||||
@@ -585,6 +615,8 @@ class ProcedureBuilder extends FunctionBuilder {
|
||||
_extensionTearOff != null, "No extension tear off created for $this.");
|
||||
if (_extensionTearOff.name != null) return;
|
||||
|
||||
_extensionTearOffParameterMap = {};
|
||||
|
||||
int fileOffset = _procedure.fileOffset;
|
||||
|
||||
int extensionTypeParameterCount =
|
||||
@@ -592,17 +624,18 @@ class ProcedureBuilder extends FunctionBuilder {
|
||||
|
||||
List<TypeParameter> typeParameters = <TypeParameter>[];
|
||||
|
||||
Map<TypeParameter, DartType> substitutionMap = {};
|
||||
List<DartType> typeArguments = <DartType>[];
|
||||
for (TypeParameter typeParameter in function.typeParameters) {
|
||||
TypeParameter newTypeParameter = new TypeParameter(typeParameter.name);
|
||||
typeParameters.add(newTypeParameter);
|
||||
typeArguments.add(new TypeParameterType(newTypeParameter));
|
||||
typeArguments.add(substitutionMap[typeParameter] =
|
||||
new TypeParameterType(newTypeParameter));
|
||||
}
|
||||
|
||||
List<TypeParameter> tearOffTypeParameters = <TypeParameter>[];
|
||||
List<TypeParameter> closureTypeParameters = <TypeParameter>[];
|
||||
Substitution substitution =
|
||||
Substitution.fromPairs(function.typeParameters, typeArguments);
|
||||
Substitution substitution = Substitution.fromMap(substitutionMap);
|
||||
for (int index = 0; index < typeParameters.length; index++) {
|
||||
TypeParameter newTypeParameter = typeParameters[index];
|
||||
newTypeParameter.bound =
|
||||
@@ -618,12 +651,11 @@ class ProcedureBuilder extends FunctionBuilder {
|
||||
VariableDeclaration copyParameter(
|
||||
VariableDeclaration parameter, DartType type,
|
||||
{bool isOptional}) {
|
||||
// TODO(johnniwinther): Handle default values.
|
||||
return new VariableDeclaration(parameter.name,
|
||||
type: type,
|
||||
initializer: isOptional ? new NullLiteral() : null,
|
||||
isFinal: parameter.isFinal)
|
||||
VariableDeclaration newParameter = new VariableDeclaration(parameter.name,
|
||||
type: type, isFinal: parameter.isFinal)
|
||||
..fileOffset = parameter.fileOffset;
|
||||
_extensionTearOffParameterMap[parameter] = newParameter;
|
||||
return newParameter;
|
||||
}
|
||||
|
||||
VariableDeclaration extensionThis = copyParameter(
|
||||
@@ -697,6 +729,14 @@ class ProcedureBuilder extends FunctionBuilder {
|
||||
_extensionTearOff.function.parent = _extensionTearOff;
|
||||
}
|
||||
|
||||
@override
|
||||
VariableDeclaration getExtensionTearOffParameter(int index) {
|
||||
if (_extensionTearOffParameterMap != null) {
|
||||
return _extensionTearOffParameterMap[getFormalParameter(index)];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// The [Procedure] built by this builder.
|
||||
Procedure get procedure => isPatch ? origin.procedure : _procedure;
|
||||
|
||||
|
||||
@@ -789,18 +789,31 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
||||
FormalParameterBuilder parameter = formals.parameters[i];
|
||||
Expression initializer = parameter.target.initializer;
|
||||
if (parameter.isOptional || initializer != null) {
|
||||
VariableDeclaration realParameter = builder.formals[i].target;
|
||||
if (parameter.isOptional) {
|
||||
initializer ??= forest.createNullLiteral(
|
||||
// TODO(ahe): Should store: realParameter.fileOffset
|
||||
// TODO(ahe): Should store: originParameter.fileOffset
|
||||
// https://github.com/dart-lang/sdk/issues/32289
|
||||
null);
|
||||
}
|
||||
realParameter.initializer = initializer..parent = realParameter;
|
||||
VariableDeclaration originParameter = builder.getFormalParameter(i);
|
||||
originParameter.initializer = initializer..parent = originParameter;
|
||||
typeInferrer?.inferParameterInitializer(
|
||||
this, initializer, realParameter.type);
|
||||
this, initializer, originParameter.type);
|
||||
libraryBuilder.loader.transformPostInference(
|
||||
realParameter, transformSetLiterals, transformCollections);
|
||||
originParameter, transformSetLiterals, transformCollections);
|
||||
|
||||
VariableDeclaration extensionTearOffParameter =
|
||||
builder.getExtensionTearOffParameter(i);
|
||||
if (extensionTearOffParameter != null) {
|
||||
cloner ??= new CloneVisitor();
|
||||
Expression tearOffInitializer = cloner.clone(initializer);
|
||||
extensionTearOffParameter.initializer = tearOffInitializer
|
||||
..parent = extensionTearOffParameter;
|
||||
libraryBuilder.loader.transformPostInference(
|
||||
extensionTearOffParameter,
|
||||
transformSetLiterals,
|
||||
transformCollections);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2019, 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.
|
||||
|
||||
class Class {}
|
||||
|
||||
extension Extension on Class {
|
||||
method0([a]) => a;
|
||||
method1([a = 42]) => a;
|
||||
method2({b = 87}) => b;
|
||||
method3({c = staticMethod}) => c();
|
||||
static staticMethod() => 123;
|
||||
}
|
||||
|
||||
main() {
|
||||
Class c = new Class();
|
||||
var tearOff0 = c.method0;
|
||||
expect(0, tearOff0(0));
|
||||
expect(null, tearOff0());
|
||||
var tearOff1 = c.method1;
|
||||
expect(0, tearOff1(0));
|
||||
expect(42, tearOff1());
|
||||
var tearOff2 = c.method2;
|
||||
expect(0, tearOff2(b: 0));
|
||||
expect(87, tearOff2());
|
||||
var tearOff3 = c.method3;
|
||||
expect(0, tearOff3(c: () => 0));
|
||||
expect(123, tearOff3());
|
||||
}
|
||||
|
||||
|
||||
expect(expected, actual) {
|
||||
if (expected != actual) {
|
||||
throw 'Mismatch: expected=$expected, actual=$actual';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Class extends core::Object {
|
||||
synthetic constructor •() → self::Class*
|
||||
;
|
||||
}
|
||||
extension Extension on self::Class* {
|
||||
method method0 = self::Extension|method0;
|
||||
tearoff method0 = self::Extension|get#method0;
|
||||
method method1 = self::Extension|method1;
|
||||
tearoff method1 = self::Extension|get#method1;
|
||||
method method2 = self::Extension|method2;
|
||||
tearoff method2 = self::Extension|get#method2;
|
||||
method method3 = self::Extension|method3;
|
||||
tearoff method3 = self::Extension|get#method3;
|
||||
static method staticMethod = self::Extension|staticMethod;
|
||||
}
|
||||
static method Extension|method0(final self::Class* #this, [dynamic a]) → dynamic
|
||||
;
|
||||
static method Extension|get#method0(final self::Class* #this) → ([dynamic]) →* dynamic
|
||||
return ([dynamic a]) → dynamic => self::Extension|method0(#this, a);
|
||||
static method Extension|method1(final self::Class* #this, [dynamic a]) → dynamic
|
||||
;
|
||||
static method Extension|get#method1(final self::Class* #this) → ([dynamic]) →* dynamic
|
||||
return ([dynamic a]) → dynamic => self::Extension|method1(#this, a);
|
||||
static method Extension|method2(final self::Class* #this, {dynamic b}) → dynamic
|
||||
;
|
||||
static method Extension|get#method2(final self::Class* #this) → ({b: dynamic}) →* dynamic
|
||||
return ({dynamic b}) → dynamic => self::Extension|method2(#this, b: b);
|
||||
static method Extension|method3(final self::Class* #this, {dynamic c}) → dynamic
|
||||
;
|
||||
static method Extension|get#method3(final self::Class* #this) → ({c: dynamic}) →* dynamic
|
||||
return ({dynamic c}) → dynamic => self::Extension|method3(#this, c: c);
|
||||
static method Extension|staticMethod() → dynamic
|
||||
;
|
||||
static method main() → dynamic
|
||||
;
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic
|
||||
;
|
||||
@@ -0,0 +1,65 @@
|
||||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Class extends core::Object {
|
||||
synthetic constructor •() → self::Class*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
extension Extension on self::Class* {
|
||||
method method0 = self::Extension|method0;
|
||||
tearoff method0 = self::Extension|get#method0;
|
||||
method method1 = self::Extension|method1;
|
||||
tearoff method1 = self::Extension|get#method1;
|
||||
method method2 = self::Extension|method2;
|
||||
tearoff method2 = self::Extension|get#method2;
|
||||
method method3 = self::Extension|method3;
|
||||
tearoff method3 = self::Extension|get#method3;
|
||||
static method staticMethod = self::Extension|staticMethod;
|
||||
}
|
||||
static method Extension|method0(final self::Class* #this, [dynamic a = #C1]) → dynamic
|
||||
return a;
|
||||
static method Extension|get#method0(final self::Class* #this) → ([dynamic]) →* dynamic
|
||||
return ([dynamic a = #C1]) → dynamic => self::Extension|method0(#this, a);
|
||||
static method Extension|method1(final self::Class* #this, [dynamic a = #C2]) → dynamic
|
||||
return a;
|
||||
static method Extension|get#method1(final self::Class* #this) → ([dynamic]) →* dynamic
|
||||
return ([dynamic a = #C2]) → dynamic => self::Extension|method1(#this, a);
|
||||
static method Extension|method2(final self::Class* #this, {dynamic b = #C3}) → dynamic
|
||||
return b;
|
||||
static method Extension|get#method2(final self::Class* #this) → ({b: dynamic}) →* dynamic
|
||||
return ({dynamic b = #C3}) → dynamic => self::Extension|method2(#this, b: b);
|
||||
static method Extension|method3(final self::Class* #this, {dynamic c = #C4}) → dynamic
|
||||
return c.call();
|
||||
static method Extension|get#method3(final self::Class* #this) → ({c: dynamic}) →* dynamic
|
||||
return ({dynamic c = #C4}) → dynamic => self::Extension|method3(#this, c: c);
|
||||
static method Extension|staticMethod() → dynamic
|
||||
return 123;
|
||||
static method main() → dynamic {
|
||||
self::Class* c = new self::Class::•();
|
||||
([dynamic]) →* dynamic tearOff0 = self::Extension|get#method0(c);
|
||||
self::expect(0, tearOff0.call(0));
|
||||
self::expect(null, tearOff0.call());
|
||||
([dynamic]) →* dynamic tearOff1 = self::Extension|get#method1(c);
|
||||
self::expect(0, tearOff1.call(0));
|
||||
self::expect(42, tearOff1.call());
|
||||
({b: dynamic}) →* dynamic tearOff2 = self::Extension|get#method2(c);
|
||||
self::expect(0, tearOff2.call(b: 0));
|
||||
self::expect(87, tearOff2.call());
|
||||
({c: dynamic}) →* dynamic tearOff3 = self::Extension|get#method3(c);
|
||||
self::expect(0, tearOff3.call(c: () → core::int* => 0));
|
||||
self::expect(123, tearOff3.call());
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!expected.{core::Object::==}(actual)) {
|
||||
throw "Mismatch: expected=${expected}, actual=${actual}";
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = null
|
||||
#C2 = 42
|
||||
#C3 = 87
|
||||
#C4 = tearoff self::Extension|staticMethod
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Class extends core::Object {
|
||||
synthetic constructor •() → self::Class*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
extension Extension on self::Class* {
|
||||
method method0 = self::Extension|method0;
|
||||
tearoff method0 = self::Extension|get#method0;
|
||||
method method1 = self::Extension|method1;
|
||||
tearoff method1 = self::Extension|get#method1;
|
||||
method method2 = self::Extension|method2;
|
||||
tearoff method2 = self::Extension|get#method2;
|
||||
method method3 = self::Extension|method3;
|
||||
tearoff method3 = self::Extension|get#method3;
|
||||
static method staticMethod = self::Extension|staticMethod;
|
||||
}
|
||||
static method Extension|method0(final self::Class* #this, [dynamic a = #C1]) → dynamic
|
||||
return a;
|
||||
static method Extension|get#method0(final self::Class* #this) → ([dynamic]) →* dynamic
|
||||
return ([dynamic a = #C1]) → dynamic => self::Extension|method0(#this, a);
|
||||
static method Extension|method1(final self::Class* #this, [dynamic a = #C2]) → dynamic
|
||||
return a;
|
||||
static method Extension|get#method1(final self::Class* #this) → ([dynamic]) →* dynamic
|
||||
return ([dynamic a = #C2]) → dynamic => self::Extension|method1(#this, a);
|
||||
static method Extension|method2(final self::Class* #this, {dynamic b = #C3}) → dynamic
|
||||
return b;
|
||||
static method Extension|get#method2(final self::Class* #this) → ({b: dynamic}) →* dynamic
|
||||
return ({dynamic b = #C3}) → dynamic => self::Extension|method2(#this, b: b);
|
||||
static method Extension|method3(final self::Class* #this, {dynamic c = #C4}) → dynamic
|
||||
return c.call();
|
||||
static method Extension|get#method3(final self::Class* #this) → ({c: dynamic}) →* dynamic
|
||||
return ({dynamic c = #C4}) → dynamic => self::Extension|method3(#this, c: c);
|
||||
static method Extension|staticMethod() → dynamic
|
||||
return 123;
|
||||
static method main() → dynamic {
|
||||
self::Class* c = new self::Class::•();
|
||||
([dynamic]) →* dynamic tearOff0 = self::Extension|get#method0(c);
|
||||
self::expect(0, tearOff0.call(0));
|
||||
self::expect(null, tearOff0.call());
|
||||
([dynamic]) →* dynamic tearOff1 = self::Extension|get#method1(c);
|
||||
self::expect(0, tearOff1.call(0));
|
||||
self::expect(42, tearOff1.call());
|
||||
({b: dynamic}) →* dynamic tearOff2 = self::Extension|get#method2(c);
|
||||
self::expect(0, tearOff2.call(b: 0));
|
||||
self::expect(87, tearOff2.call());
|
||||
({c: dynamic}) →* dynamic tearOff3 = self::Extension|get#method3(c);
|
||||
self::expect(0, tearOff3.call(c: () → core::int* => 0));
|
||||
self::expect(123, tearOff3.call());
|
||||
}
|
||||
static method expect(dynamic expected, dynamic actual) → dynamic {
|
||||
if(!expected.{core::Object::==}(actual)) {
|
||||
throw "Mismatch: expected=${expected}, actual=${actual}";
|
||||
}
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = null
|
||||
#C2 = 42
|
||||
#C3 = 87
|
||||
#C4 = tearoff self::Extension|staticMethod
|
||||
}
|
||||
@@ -76,11 +76,11 @@ static method Extension|get#writeSetterRequired(final self::Class* #this) → (d
|
||||
static method Extension|writeSetterOptional(final self::Class* #this, [dynamic value]) → dynamic
|
||||
;
|
||||
static method Extension|get#writeSetterOptional(final self::Class* #this) → ([dynamic]) →* dynamic
|
||||
return ([dynamic value = null]) → dynamic => self::Extension|writeSetterOptional(#this, value);
|
||||
return ([dynamic value]) → dynamic => self::Extension|writeSetterOptional(#this, value);
|
||||
static method Extension|writeSetterNamed(final self::Class* #this, {dynamic value}) → dynamic
|
||||
;
|
||||
static method Extension|get#writeSetterNamed(final self::Class* #this) → ({value: dynamic}) →* dynamic
|
||||
return ({dynamic value = null}) → dynamic => self::Extension|writeSetterNamed(#this, value: value);
|
||||
return ({dynamic value}) → dynamic => self::Extension|writeSetterNamed(#this, value: value);
|
||||
static method Extension|get#tearOffGetterNoArgs(final self::Class* #this) → dynamic
|
||||
;
|
||||
static method Extension|get#tearOffGetterRequired(final self::Class* #this) → dynamic
|
||||
@@ -116,11 +116,11 @@ static method GenericExtension|get#writeSetterRequired<T extends core::Object* =
|
||||
static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value]) → dynamic
|
||||
;
|
||||
static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
|
||||
return ([self::GenericExtension|get#writeSetterOptional::T* value = null]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#writeSetterOptional::T*>(#this, value);
|
||||
return ([self::GenericExtension|get#writeSetterOptional::T* value]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#writeSetterOptional::T*>(#this, value);
|
||||
static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value}) → dynamic
|
||||
;
|
||||
static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
|
||||
return ({self::GenericExtension|get#writeSetterNamed::T* value = null}) → dynamic => self::GenericExtension|writeSetterNamed<self::GenericExtension|get#writeSetterNamed::T*>(#this, value: value);
|
||||
return ({self::GenericExtension|get#writeSetterNamed::T* value}) → dynamic => self::GenericExtension|writeSetterNamed<self::GenericExtension|get#writeSetterNamed::T*>(#this, value: value);
|
||||
static method GenericExtension|genericWriteSetterRequired<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterRequired::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterRequired::T*>* #this, self::GenericExtension|genericWriteSetterRequired::S* value) → dynamic
|
||||
;
|
||||
static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
|
||||
@@ -128,9 +128,9 @@ static method GenericExtension|get#genericWriteSetterRequired<T extends core::Ob
|
||||
static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value]) → dynamic
|
||||
;
|
||||
static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
|
||||
return <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S* value = null]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#genericWriteSetterOptional::T*, S*>(#this, value);
|
||||
return <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S* value]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#genericWriteSetterOptional::T*, S*>(#this, value);
|
||||
static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
|
||||
return <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({S* value = null}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#genericWriteSetterNamed::T*, S*>(#this, value: value);
|
||||
return <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({S* value}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#genericWriteSetterNamed::T*, S*>(#this, value: value);
|
||||
static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value}) → dynamic
|
||||
;
|
||||
static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
|
||||
|
||||
@@ -77,12 +77,12 @@ static method Extension|writeSetterRequired(final self::Class* #this, dynamic va
|
||||
}
|
||||
static method Extension|get#writeSetterRequired(final self::Class* #this) → (dynamic) →* dynamic
|
||||
return (dynamic value) → dynamic => self::Extension|writeSetterRequired(#this, value);
|
||||
static method Extension|writeSetterOptional(final self::Class* #this = #C1, [dynamic value = #C1]) → dynamic {
|
||||
static method Extension|writeSetterOptional(final self::Class* #this, [dynamic value = #C1]) → dynamic {
|
||||
self::Extension|set#property(#this, value);
|
||||
}
|
||||
static method Extension|get#writeSetterOptional(final self::Class* #this) → ([dynamic]) →* dynamic
|
||||
return ([dynamic value = #C1]) → dynamic => self::Extension|writeSetterOptional(#this, value);
|
||||
static method Extension|writeSetterNamed(final self::Class* #this = #C1, {dynamic value = #C1}) → dynamic {
|
||||
static method Extension|writeSetterNamed(final self::Class* #this, {dynamic value = #C1}) → dynamic {
|
||||
self::Extension|set#property(#this, value);
|
||||
}
|
||||
static method Extension|get#writeSetterNamed(final self::Class* #this) → ({value: dynamic}) →* dynamic
|
||||
@@ -144,12 +144,12 @@ static method GenericExtension|writeSetterRequired<T extends core::Object* = dyn
|
||||
}
|
||||
static method GenericExtension|get#writeSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterRequired::T*>* #this) → (self::GenericExtension|get#writeSetterRequired::T*) →* dynamic
|
||||
return (self::GenericExtension|get#writeSetterRequired::T* value) → dynamic => self::GenericExtension|writeSetterRequired<self::GenericExtension|get#writeSetterRequired::T*>(#this, value);
|
||||
static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this = #C1, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
|
||||
static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
|
||||
self::GenericExtension|set#property<self::GenericExtension|writeSetterOptional::T*>(#this, value);
|
||||
}
|
||||
static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
|
||||
return ([self::GenericExtension|get#writeSetterOptional::T* value = #C1]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#writeSetterOptional::T*>(#this, value);
|
||||
static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this = #C1, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
|
||||
static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
|
||||
self::GenericExtension|set#property<self::GenericExtension|writeSetterNamed::T*>(#this, value);
|
||||
}
|
||||
static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
|
||||
@@ -159,14 +159,14 @@ static method GenericExtension|genericWriteSetterRequired<T extends core::Object
|
||||
}
|
||||
static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
|
||||
return <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S* value) → dynamic => self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|get#genericWriteSetterRequired::T*, S*>(#this, value);
|
||||
static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this = #C1, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
|
||||
static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
|
||||
self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterOptional::T*>(#this, value);
|
||||
}
|
||||
static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
|
||||
return <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S* value = #C1]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#genericWriteSetterOptional::T*, S*>(#this, value);
|
||||
static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
|
||||
return <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({S* value = #C1}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#genericWriteSetterNamed::T*, S*>(#this, value: value);
|
||||
static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this = #C1, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
|
||||
static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
|
||||
self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterNamed::T*>(#this, value);
|
||||
}
|
||||
static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
|
||||
|
||||
+6
-6
@@ -77,12 +77,12 @@ static method Extension|writeSetterRequired(final self::Class* #this, dynamic va
|
||||
}
|
||||
static method Extension|get#writeSetterRequired(final self::Class* #this) → (dynamic) →* dynamic
|
||||
return (dynamic value) → dynamic => self::Extension|writeSetterRequired(#this, value);
|
||||
static method Extension|writeSetterOptional(final self::Class* #this = #C1, [dynamic value = #C1]) → dynamic {
|
||||
static method Extension|writeSetterOptional(final self::Class* #this, [dynamic value = #C1]) → dynamic {
|
||||
self::Extension|set#property(#this, value);
|
||||
}
|
||||
static method Extension|get#writeSetterOptional(final self::Class* #this) → ([dynamic]) →* dynamic
|
||||
return ([dynamic value = #C1]) → dynamic => self::Extension|writeSetterOptional(#this, value);
|
||||
static method Extension|writeSetterNamed(final self::Class* #this = #C1, {dynamic value = #C1}) → dynamic {
|
||||
static method Extension|writeSetterNamed(final self::Class* #this, {dynamic value = #C1}) → dynamic {
|
||||
self::Extension|set#property(#this, value);
|
||||
}
|
||||
static method Extension|get#writeSetterNamed(final self::Class* #this) → ({value: dynamic}) →* dynamic
|
||||
@@ -144,12 +144,12 @@ static method GenericExtension|writeSetterRequired<T extends core::Object* = dyn
|
||||
}
|
||||
static method GenericExtension|get#writeSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterRequired::T*>* #this) → (self::GenericExtension|get#writeSetterRequired::T*) →* dynamic
|
||||
return (self::GenericExtension|get#writeSetterRequired::T* value) → dynamic => self::GenericExtension|writeSetterRequired<self::GenericExtension|get#writeSetterRequired::T*>(#this, value);
|
||||
static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this = #C1, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
|
||||
static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
|
||||
self::GenericExtension|set#property<self::GenericExtension|writeSetterOptional::T*>(#this, value);
|
||||
}
|
||||
static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
|
||||
return ([self::GenericExtension|get#writeSetterOptional::T* value = #C1]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#writeSetterOptional::T*>(#this, value);
|
||||
static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this = #C1, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
|
||||
static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
|
||||
self::GenericExtension|set#property<self::GenericExtension|writeSetterNamed::T*>(#this, value);
|
||||
}
|
||||
static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
|
||||
@@ -159,14 +159,14 @@ static method GenericExtension|genericWriteSetterRequired<T extends core::Object
|
||||
}
|
||||
static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
|
||||
return <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S* value) → dynamic => self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|get#genericWriteSetterRequired::T*, S*>(#this, value);
|
||||
static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this = #C1, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
|
||||
static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
|
||||
self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterOptional::T*>(#this, value);
|
||||
}
|
||||
static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
|
||||
return <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S* value = #C1]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#genericWriteSetterOptional::T*, S*>(#this, value);
|
||||
static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
|
||||
return <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({S* value = #C1}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#genericWriteSetterNamed::T*, S*>(#this, value: value);
|
||||
static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this = #C1, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
|
||||
static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
|
||||
self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterNamed::T*>(#this, value);
|
||||
}
|
||||
static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
|
||||
|
||||
@@ -37,11 +37,11 @@ static method A2|get#method2(final self::A1* #this) → <T extends core::Object*
|
||||
static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this, [self::A2|method3::T* o]) → self::A1*
|
||||
;
|
||||
static method A2|get#method3(final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
|
||||
return <T extends core::Object* = dynamic>([T* o = null]) → self::A1* => self::A2|method3<T*>(#this, o);
|
||||
return <T extends core::Object* = dynamic>([T* o]) → self::A1* => self::A2|method3<T*>(#this, o);
|
||||
static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this, {self::A2|method4::T* o}) → self::A1*
|
||||
;
|
||||
static method A2|get#method4(final self::A1* #this) → <T extends core::Object* = dynamic>({o: T*}) →* self::A1*
|
||||
return <T extends core::Object* = dynamic>({T* o = null}) → self::A1* => self::A2|method4<T*>(#this, o: o);
|
||||
return <T extends core::Object* = dynamic>({T* o}) → self::A1* => self::A2|method4<T*>(#this, o: o);
|
||||
static method B2|method1<T extends core::Object* = dynamic>(final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>*
|
||||
;
|
||||
static method B2|get#method1<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
|
||||
|
||||
@@ -39,13 +39,13 @@ static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #thi
|
||||
}
|
||||
static method A2|get#method2(final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
|
||||
return <T extends core::Object* = dynamic>(T* o) → self::A1* => self::A2|method2<T*>(#this, o);
|
||||
static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this = #C1, [self::A2|method3::T* o = #C1]) → self::A1* {
|
||||
static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this, [self::A2|method3::T* o = #C1]) → self::A1* {
|
||||
core::print(o);
|
||||
return #this;
|
||||
}
|
||||
static method A2|get#method3(final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
|
||||
return <T extends core::Object* = dynamic>([T* o = #C1]) → self::A1* => self::A2|method3<T*>(#this, o);
|
||||
static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this = #C1, {self::A2|method4::T* o = #C1}) → self::A1* {
|
||||
static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this, {self::A2|method4::T* o = #C1}) → self::A1* {
|
||||
core::print(o);
|
||||
return #this;
|
||||
}
|
||||
|
||||
@@ -39,13 +39,13 @@ static method A2|method2<T extends core::Object* = dynamic>(final self::A1* #thi
|
||||
}
|
||||
static method A2|get#method2(final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
|
||||
return <T extends core::Object* = dynamic>(T* o) → self::A1* => self::A2|method2<T*>(#this, o);
|
||||
static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this = #C1, [self::A2|method3::T* o = #C1]) → self::A1* {
|
||||
static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this, [self::A2|method3::T* o = #C1]) → self::A1* {
|
||||
core::print(o);
|
||||
return #this;
|
||||
}
|
||||
static method A2|get#method3(final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
|
||||
return <T extends core::Object* = dynamic>([T* o = #C1]) → self::A1* => self::A2|method3<T*>(#this, o);
|
||||
static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this = #C1, {self::A2|method4::T* o = #C1}) → self::A1* {
|
||||
static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this, {self::A2|method4::T* o = #C1}) → self::A1* {
|
||||
core::print(o);
|
||||
return #this;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ expression/main: TextSerializationFailure # Was: Pass
|
||||
extensions/annotations: TextSerializationFailure
|
||||
extensions/compounds: TextSerializationFailure
|
||||
extensions/conflicts: TextSerializationFailure
|
||||
extensions/default_values: TextSerializationFailure
|
||||
extensions/direct_instance_access: TextSerializationFailure
|
||||
extensions/direct_static_access: TextSerializationFailure
|
||||
extensions/dynamic_invoke: TextSerializationFailure
|
||||
|
||||
@@ -11,6 +11,8 @@ class Class {
|
||||
extension Extension on Class {
|
||||
int method() => this.field;
|
||||
|
||||
int methodWithOptionals([int a = 42]) => a;
|
||||
|
||||
int get property => this.field;
|
||||
|
||||
void set property(int value) {
|
||||
|
||||
@@ -24,10 +24,15 @@ testExplicitAccess(Class c) {
|
||||
|
||||
testImplicitAccess(Class c) {
|
||||
Expect.equals(c.field, c.method());
|
||||
Expect.equals(42, c.methodWithOptionals());
|
||||
Expect.equals(123, c.methodWithOptionals(123));
|
||||
Expect.equals(c.field, c.property);
|
||||
Expect.equals(123, c.property = 123);
|
||||
var f = c.method;
|
||||
Expect.equals(c.field, f());
|
||||
var f2 = c.methodWithOptionals;
|
||||
Expect.equals(42, f2());
|
||||
Expect.equals(87, f2(87));
|
||||
}
|
||||
|
||||
testStaticAccess() {
|
||||
|
||||
Reference in New Issue
Block a user