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:
rmacnak@google.com 2013-10-09 20:40:11 +00:00
parent afb3cc7f01
commit 6ed9f2c17f
7 changed files with 58 additions and 35 deletions

View file

@ -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);
}

View file

@ -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')];

View file

@ -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_));
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);