| Index: frog/member.dart
|
| diff --git a/frog/member.dart b/frog/member.dart
|
| index 09fa429ea010d885db68b9459aa93c3c9ddbb4a3..9bab915ac9099d4017ae1682a5018051573f16d8 100644
|
| --- a/frog/member.dart
|
| +++ b/frog/member.dart
|
| @@ -115,6 +115,11 @@ class Member implements Named {
|
| bool get isProperty() => false;
|
| bool get isAbstract() => false;
|
|
|
| + // TODO(jmesserly): these only makes sense on methods, but because of
|
| + // ConcreteMember we need to support them on Member.
|
| + bool get isConst() => false;
|
| + bool get isFactory() => false;
|
| +
|
| bool get prefersPropertySyntax() => true;
|
| bool get requiresFieldSyntax() => false;
|
|
|
| @@ -124,7 +129,12 @@ class Member implements Named {
|
|
|
| void provideFieldSyntax() => world.internalError('can not be field', span);
|
| void providePropertySyntax() =>
|
| - world.internalError('can not be property', span);
|
| + world.internalError('can not be property', span);
|
| +
|
| + Definition get initDelegate() =>
|
| + world.internalError('cannot have initializers', span);
|
| + Definition set initDelegate(ctor) =>
|
| + world.internalError('cannot have initializers', span);
|
|
|
| Definition get definition() => null;
|
|
|
| @@ -169,6 +179,16 @@ class Member implements Named {
|
| return '${prefix}$name\$factory';
|
| }
|
| }
|
| +
|
| + Type resolveType(TypeReference node, bool isRequired) {
|
| + var type = declaringType.resolveType(node, isRequired);
|
| + if (isStatic && type.hasTypeParams) {
|
| + // TODO(jimhug): Is this really so hard?
|
| + world.error('using type parameter in static context',
|
| + node.span);
|
| + }
|
| + return type;
|
| + }
|
| }
|
|
|
|
|
| @@ -189,7 +209,7 @@ class TypeMember extends Member {
|
| bool get isStatic() => true;
|
|
|
| // If this really becomes first class, this should return typeof(Type)
|
| - Type get returnType() => world.isVar;
|
| + Type get returnType() => world.varType;
|
|
|
| bool canInvoke(MethodGenerator context, Arguments args) => false;
|
| bool get canGet() => true;
|
| @@ -366,7 +386,7 @@ class FieldMember extends Member {
|
| }
|
| } else if (target.isConst && isFinal) {
|
| // take advantage of consts and retrieve the value directly if possible
|
| - var constTarget = target is GlobalValue ? target.exp : target;
|
| + var constTarget = target is GlobalValue ? target.dynamic.exp : target;
|
| if (constTarget is ConstObjectValue) {
|
| return constTarget.fields[name];
|
| } else if (constTarget.type == world.stringType && name == 'length') {
|
| @@ -458,12 +478,16 @@ class PropertyMember extends Member {
|
|
|
| addFromParent(Member parentMember) {
|
| // TODO(jimhug): Egregious Hack!
|
| + PropertyMember parent;
|
| if (parentMember is ConcreteMember) {
|
| - parentMember = parentMember.baseMember;
|
| + ConcreteMember c = parentMember;
|
| + parent = c.baseMember;
|
| + } else {
|
| + parent = parentMember;
|
| }
|
|
|
| - if (getter == null) getter = parentMember.getter;
|
| - if (setter == null) setter = parentMember.setter;
|
| + if (getter == null) getter = parent.getter;
|
| + if (setter == null) setter = parent.setter;
|
| }
|
|
|
| resolve(Type inType) {
|
| @@ -500,12 +524,12 @@ class ConcreteMember extends Member {
|
| bool get isStatic() => baseMember.isStatic;
|
| bool get isAbstract() => baseMember.isAbstract;
|
| bool get isConst() => baseMember.isConst;
|
| + bool get isFactory() => baseMember.isFactory;
|
|
|
| String get jsname() => baseMember.jsname;
|
| set jsname(String name) =>
|
| world.internalError('bad set of jsname on ConcreteMember');
|
|
|
| - bool get isFactory() => baseMember.isFactory;
|
|
|
| bool get canGet() => baseMember.canGet;
|
| bool get canSet() => baseMember.canSet;
|
| @@ -616,13 +640,14 @@ class MethodMember extends Member {
|
| SourceSpan get span() => definition == null ? null : definition.span;
|
|
|
| String get constructorName() {
|
| - if (definition.returnType == null) return '';
|
| + NameTypeReference returnType = definition.returnType;
|
| + if (returnType == null) return '';
|
|
|
| // TODO(jmesserly): make this easier?
|
| - if (definition.returnType.names != null) {
|
| - return definition.returnType.names[0].name;
|
| - } else if (definition.returnType.name != null) {
|
| - return definition.returnType.name.name;
|
| + if (returnType.names != null) {
|
| + return returnType.names[0].name;
|
| + } else if (returnType.name != null) {
|
| + return returnType.name.name;
|
| }
|
| world.internalError('no valid constructor name', definition.span);
|
| }
|
| @@ -686,16 +711,6 @@ class MethodMember extends Member {
|
| return -1;
|
| }
|
|
|
| - Type resolveType(TypeReference node, bool isRequired) {
|
| - var type = declaringType.resolveType(node, isRequired);
|
| - if (isStatic && type.hasTypeParams) {
|
| - // TODO(jimhug): Is this really so hard?
|
| - world.error('using type parameter in static context',
|
| - node.span);
|
| - }
|
| - return type;
|
| - }
|
| -
|
| bool get prefersPropertySyntax() => true;
|
| bool get requiresFieldSyntax() => false;
|
|
|
| @@ -910,15 +925,15 @@ class MethodMember extends Member {
|
| // optimize expressions which we know statically their value.
|
| if (target.isConst) {
|
| if (target is GlobalValue) {
|
| - target = target.exp;
|
| + target = target.dynamic.exp; // TODO: an inline "cast" would be nice.
|
| }
|
| if (name == 'get\$length') {
|
| if (target is ConstListValue || target is ConstMapValue) {
|
| - code = '${target.values.length}';
|
| + code = '${target.dynamic.values.length}';
|
| }
|
| } else if (name == 'isEmpty') {
|
| if (target is ConstListValue || target is ConstMapValue) {
|
| - code = '${target.values.isEmpty()}';
|
| + code = '${target.dynamic.values.isEmpty()}';
|
| }
|
| }
|
| }
|
| @@ -931,8 +946,8 @@ class MethodMember extends Member {
|
| return new Value(returnType, code);
|
| }
|
|
|
| - Value _invokeConstructor(MethodGenerator context, Node node, Value target,
|
| - Arguments args, argsString) {
|
| + Value _invokeConstructor(MethodGenerator context, Node node,
|
| + Value target, Arguments args, argsString) {
|
| declaringType.markUsed();
|
|
|
| if (target != null) {
|
| @@ -945,7 +960,8 @@ class MethodMember extends Member {
|
| var code = (constructorName != '')
|
| ? 'new ${declaringType.jsname}.${constructorName}\$ctor($argsString)'
|
| : 'new ${declaringType.jsname}($argsString)';
|
| - if (isConst && node.isConst) {
|
| + // TODO(jmesserly): using the "node" here feels really hacky
|
| + if (isConst && node is NewExpression && node.dynamic.isConst) {
|
| return _invokeConstConstructor(node, code, target, args);
|
| } else {
|
| return new Value(declaringType, code);
|
| @@ -1032,8 +1048,10 @@ class MethodMember extends Member {
|
| }
|
| } else {
|
| // Normal field initializer assignment.
|
| - var fname = init.x.name.name;
|
| - var val = generator.visitValue(init.y);
|
| + BinaryExpression assign = init;
|
| + VarExpression x = assign.x;
|
| + var fname = x.name.name;
|
| + var val = generator.visitValue(assign.y);
|
| fields[fname] = val;
|
| }
|
| }
|
|
|