mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 20:51:50 +00:00
Implement constructor kinds in the VM mirrors.
BUG=http://dartbug.com/13798 R=asiva@google.com, hausner@google.com Review URL: https://codereview.chromium.org//26436004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@28416 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
afb3cc7f01
commit
6ed9f2c17f
|
@ -261,12 +261,14 @@ static RawInstance* CreateMethodMirror(const Function& func,
|
|||
args.SetAt(4, Bool::Get(func.is_abstract()));
|
||||
args.SetAt(5, Bool::Get(func.IsGetterFunction()));
|
||||
args.SetAt(6, Bool::Get(func.IsSetterFunction()));
|
||||
args.SetAt(7, Bool::Get(func.kind() == RawFunction::kConstructor));
|
||||
// TODO(mlippautz): Implement different constructor kinds.
|
||||
args.SetAt(8, Bool::False());
|
||||
args.SetAt(9, Bool::False());
|
||||
args.SetAt(10, Bool::False());
|
||||
args.SetAt(11, Bool::False());
|
||||
|
||||
bool isConstructor = (func.kind() == RawFunction::kConstructor);
|
||||
args.SetAt(7, Bool::Get(isConstructor));
|
||||
args.SetAt(8, Bool::Get(isConstructor && func.is_const()));
|
||||
args.SetAt(9, Bool::Get(isConstructor && func.IsConstructor()));
|
||||
args.SetAt(10, Bool::Get(isConstructor && func.is_redirecting()));
|
||||
args.SetAt(11, Bool::Get(isConstructor && func.IsFactory()));
|
||||
|
||||
return CreateMirror(Symbols::_LocalMethodMirrorImpl(), args);
|
||||
}
|
||||
|
||||
|
|
|
@ -252,11 +252,12 @@ void testRootLibraryMirror(LibraryMirror lib_mirror) {
|
|||
|
||||
func = cls_mirror.constructors[const Symbol('MyClass')];
|
||||
Expect.isTrue(func is MethodMirror);
|
||||
Expect.equals('MyClass return(MyClass) constructor', buildMethodString(func));
|
||||
Expect.equals('MyClass return(MyClass) constructor generative',
|
||||
buildMethodString(func));
|
||||
|
||||
func = cls_mirror.constructors[const Symbol('MyClass.named')];
|
||||
Expect.isTrue(func is MethodMirror);
|
||||
Expect.equals('MyClass.named return(MyClass) constructor',
|
||||
Expect.equals('MyClass.named return(MyClass) constructor generative',
|
||||
buildMethodString(func));
|
||||
|
||||
func = generic_cls_mirror.members[const Symbol('method')];
|
||||
|
|
|
@ -4197,6 +4197,11 @@ void Function::set_is_recognized(bool value) const {
|
|||
}
|
||||
|
||||
|
||||
void Function::set_is_redirecting(bool value) const {
|
||||
set_kind_tag(RedirectingBit::update(value, raw_ptr()->kind_tag_));
|
||||
}
|
||||
|
||||
|
||||
void Function::set_is_static(bool value) const {
|
||||
set_kind_tag(StaticBit::update(value, raw_ptr()->kind_tag_));
|
||||
}
|
||||
|
|
|
@ -1699,6 +1699,11 @@ class Function : public Object {
|
|||
}
|
||||
void set_is_recognized(bool value) const;
|
||||
|
||||
bool is_redirecting() const {
|
||||
return RedirectingBit::decode(raw_ptr()->kind_tag_);
|
||||
}
|
||||
void set_is_redirecting(bool value) const;
|
||||
|
||||
bool HasOptimizedCode() const;
|
||||
|
||||
// Returns true if the argument counts are valid for calling this function.
|
||||
|
@ -1858,7 +1863,8 @@ class Function : public Object {
|
|||
kVisibleBit = 8,
|
||||
kIntrinsicBit = 9,
|
||||
kRecognizedBit = 10,
|
||||
kKindTagBit = 11,
|
||||
kRedirectingBit = 11,
|
||||
kKindTagBit = 12,
|
||||
kKindTagSize = 4,
|
||||
};
|
||||
class StaticBit : public BitField<bool, kStaticBit, 1> {};
|
||||
|
@ -1872,6 +1878,7 @@ class Function : public Object {
|
|||
class VisibleBit : public BitField<bool, kVisibleBit, 1> {};
|
||||
class IntrinsicBit : public BitField<bool, kIntrinsicBit, 1> {};
|
||||
class RecognizedBit : public BitField<bool, kRecognizedBit, 1> {};
|
||||
class RedirectingBit : public BitField<bool, kRedirectingBit, 1> {};
|
||||
class KindBits :
|
||||
public BitField<RawFunction::Kind, kKindTagBit, kKindTagSize> {}; // NOLINT
|
||||
|
||||
|
|
|
@ -3121,9 +3121,11 @@ void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
|
|||
// Parse redirecting factory constructor.
|
||||
Type& redirection_type = Type::Handle();
|
||||
String& redirection_identifier = String::Handle();
|
||||
bool is_redirecting = false;
|
||||
if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) {
|
||||
ConsumeToken();
|
||||
const intptr_t type_pos = TokenPos();
|
||||
is_redirecting = true;
|
||||
const AbstractType& type = AbstractType::Handle(
|
||||
ParseType(ClassFinalizer::kResolveTypeParameters));
|
||||
if (!type.IsMalformed() && type.IsTypeParameter()) {
|
||||
|
@ -3153,6 +3155,7 @@ void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
|
|||
((LookaheadToken(2) == Token::kLPAREN) ||
|
||||
LookaheadToken(4) == Token::kLPAREN)) {
|
||||
// Redirected constructor: either this(...) or this.xxx(...).
|
||||
is_redirecting = true;
|
||||
if (method->params.has_field_initializer) {
|
||||
// Constructors that redirect to another constructor must not
|
||||
// initialize any fields using field initializer parameters.
|
||||
|
@ -3287,6 +3290,7 @@ void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
|
|||
method->decl_begin_pos));
|
||||
func.set_result_type(*method->type);
|
||||
func.set_end_token_pos(method_end_pos);
|
||||
func.set_is_redirecting(is_redirecting);
|
||||
if (method->metadata_pos > 0) {
|
||||
library_.AddFunctionMetadata(func, method->metadata_pos);
|
||||
}
|
||||
|
|
|
@ -155,7 +155,6 @@ mirrors/mixin_test/01: Fail, OK # TODO(ahe): Slight broken test to ensure test c
|
|||
mirrors/typedef_test/01: Fail, OK # Incorrect dart2js behavior.
|
||||
mirrors/closures_test/01: Fail, OK # Incorrect dart2js behavior.
|
||||
|
||||
mirrors/constructor_kinds_test: RuntimeError # Issue 13798
|
||||
mirrors/generics_substitution_test: RuntimeError # Issue 13808
|
||||
mirrors/generic_function_typedef_test: RuntimeError # Issue 12282
|
||||
mirrors/generic_mixin_applications_test: RuntimeError # Issue 12282
|
||||
|
@ -209,7 +208,6 @@ mirrors/local_isolate_test: Fail # Issue 13719: Please triage this failure.
|
|||
mirrors/mixin_test/01: Fail # Issue 13719: Please triage this failure.
|
||||
mirrors/typedef_test/01: Fail # Issue 13719: Please triage this failure.
|
||||
|
||||
mirrors/constructor_kinds_test: RuntimeError # Issue 13798
|
||||
mirrors/generics_substitution_test: RuntimeError # Issue 13808
|
||||
mirrors/generic_function_typedef_test: RuntimeError # Issue 12282
|
||||
mirrors/generic_mixin_applications_test: RuntimeError # Issue 12282
|
||||
|
|
|
@ -10,29 +10,36 @@ import 'package:expect/expect.dart';
|
|||
class ClassWithDefaultConstructor {}
|
||||
|
||||
class Class {
|
||||
Class.generative();
|
||||
Class.redirectingGenerative() : this.generative();
|
||||
factory Class.faktory () => new Class.generative();
|
||||
factory Class.redirectingFactory() = Class.faktory;
|
||||
Class.generativeConstructor();
|
||||
Class.redirectingGenerativeConstructor() : this.generativeConstructor();
|
||||
factory Class.factoryConstructor() => new Class.generativeConstructor();
|
||||
factory Class.redirectingFactoryConstructor() = Class.factoryConstructor;
|
||||
|
||||
const Class.constGenerative();
|
||||
const Class.constRedirectingGenerative() : this.constGenerative();
|
||||
const Class.constGenerativeConstructor();
|
||||
const Class.constRedirectingGenerativeConstructor()
|
||||
: this.constGenerativeConstructor();
|
||||
// Not legal.
|
||||
// const factory Class.constFaktory () => const Class.constGenerative();
|
||||
const factory Class.constRedirectingFactory() = Class.constGenerative;
|
||||
// const factory Class.constFactoryConstructor() => ...
|
||||
const factory Class.constRedirectingFactoryConstructor()
|
||||
= Class.constGenerativeConstructor;
|
||||
}
|
||||
|
||||
main() {
|
||||
ClassMirror cm;
|
||||
MethodMirror mm;
|
||||
|
||||
new Class.generative();
|
||||
new Class.redirectingGenerative();
|
||||
new Class.faktory();
|
||||
new Class.redirectingFactory();
|
||||
const Class.constGenerative();
|
||||
const Class.constRedirectingGenerative();
|
||||
const Class.constRedirectingFactory();
|
||||
// Multitest with and without constructor calls. On the VM, we want to check
|
||||
// that constructor properties are correctly set even if the constructor
|
||||
// hasn't been fully compiled. On dart2js, we want to check that constructors
|
||||
// are retain even if there are no base-level calls.
|
||||
new ClassWithDefaultConstructor(); /// 01: ok
|
||||
new Class.generativeConstructor(); /// 01: ok
|
||||
new Class.redirectingGenerativeConstructor(); /// 01: ok
|
||||
new Class.factoryConstructor(); /// 01: ok
|
||||
new Class.redirectingFactoryConstructor(); /// 01: ok
|
||||
const Class.constGenerativeConstructor(); /// 01: ok
|
||||
const Class.constRedirectingGenerativeConstructor(); /// 01: ok
|
||||
const Class.constRedirectingFactoryConstructor(); /// 01: ok
|
||||
|
||||
cm = reflectClass(ClassWithDefaultConstructor);
|
||||
mm = cm.constructors.values.single;
|
||||
|
@ -42,45 +49,44 @@ main() {
|
|||
Expect.isFalse(mm.isRedirectingConstructor);
|
||||
Expect.isFalse(mm.isConstConstructor);
|
||||
|
||||
|
||||
cm = reflectClass(Class);
|
||||
|
||||
mm = cm.constructors[#generative];
|
||||
mm = cm.constructors[#Class.generativeConstructor];
|
||||
Expect.isTrue(mm.isConstructor);
|
||||
Expect.isTrue(mm.isGenerativeConstructor);
|
||||
Expect.isFalse(mm.isFactoryConstructor);
|
||||
Expect.isFalse(mm.isRedirectingConstructor);
|
||||
Expect.isFalse(mm.isConstConstructor);
|
||||
|
||||
mm = cm.constructors[#redirectingGenerative];
|
||||
mm = cm.constructors[#Class.redirectingGenerativeConstructor];
|
||||
Expect.isTrue(mm.isConstructor);
|
||||
Expect.isTrue(mm.isGenerativeConstructor);
|
||||
Expect.isFalse(mm.isFactoryConstructor);
|
||||
Expect.isTrue(mm.isRedirectingConstructor);
|
||||
Expect.isFalse(mm.isConstConstructor);
|
||||
|
||||
mm = cm.constructors[#faktory];
|
||||
mm = cm.constructors[#Class.factoryConstructor];
|
||||
Expect.isTrue(mm.isConstructor);
|
||||
Expect.isFalse(mm.isGenerativeConstructor);
|
||||
Expect.isTrue(mm.isFactoryConstructor);
|
||||
Expect.isFalse(mm.isRedirectingConstructor);
|
||||
Expect.isFalse(mm.isConstConstructor);
|
||||
|
||||
mm = cm.constructors[#redirectingFactory];
|
||||
mm = cm.constructors[#Class.redirectingFactoryConstructor];
|
||||
Expect.isTrue(mm.isConstructor);
|
||||
Expect.isFalse(mm.isGenerativeConstructor);
|
||||
Expect.isTrue(mm.isFactoryConstructor);
|
||||
Expect.isTrue(mm.isRedirectingConstructor);
|
||||
Expect.isFalse(mm.isConstConstructor);
|
||||
|
||||
mm = cm.constructors[#constGenerative];
|
||||
mm = cm.constructors[#Class.constGenerativeConstructor];
|
||||
Expect.isTrue(mm.isConstructor);
|
||||
Expect.isTrue(mm.isGenerativeConstructor);
|
||||
Expect.isFalse(mm.isFactoryConstructor);
|
||||
Expect.isFalse(mm.isRedirectingConstructor);
|
||||
Expect.isTrue(mm.isConstConstructor);
|
||||
|
||||
mm = cm.constructors[#constRedirectingGenerative];
|
||||
mm = cm.constructors[#Class.constRedirectingGenerativeConstructor];
|
||||
Expect.isTrue(mm.isConstructor);
|
||||
Expect.isTrue(mm.isGenerativeConstructor);
|
||||
Expect.isFalse(mm.isFactoryConstructor);
|
||||
|
@ -88,14 +94,14 @@ main() {
|
|||
Expect.isTrue(mm.isConstConstructor);
|
||||
|
||||
// Not legal.
|
||||
// mm = cm.constructors[#constFaktory];
|
||||
// mm = cm.constructors[#Class.constFactoryConstructor];
|
||||
// Expect.isTrue(mm.isConstructor);
|
||||
// Expect.isFalse(mm.isGenerativeConstructor);
|
||||
// Expect.isTrue(mm.isFactoryConstructor);
|
||||
// Expect.isFalse(mm.isRedirectingConstructor);
|
||||
// Expect.isTrue(mm.isConstConstructor);
|
||||
|
||||
mm = cm.constructors[#constRedirectingFactory];
|
||||
mm = cm.constructors[#Class.constRedirectingFactoryConstructor];
|
||||
Expect.isTrue(mm.isConstructor);
|
||||
Expect.isFalse(mm.isGenerativeConstructor);
|
||||
Expect.isTrue(mm.isFactoryConstructor);
|
||||
|
|
Loading…
Reference in a new issue