Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Unified Diff: frog/member.dart

Issue 8681027: Fix bug 578 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: prereviewed Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « frog/library.dart ('k') | frog/parser.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/member.dart
diff --git a/frog/member.dart b/frog/member.dart
index 22214b10cdeed3f01b83099815478d533adb1342..3c5b04317a7bcc1a37045d84467587b6135dd582 100644
--- a/frog/member.dart
+++ b/frog/member.dart
@@ -5,6 +5,7 @@
/** A formal parameter to a [Method]. */
class Parameter {
FormalNode definition;
+ Member method;
String name;
Type type;
@@ -12,18 +13,18 @@ class Parameter {
Value value;
- Parameter(this.definition);
+ Parameter(this.definition, this.method);
- resolve(Member method, Type inType) {
+ resolve() {
name = definition.name.name;
if (name.startsWith('this.')) {
name = name.substring(5);
isInitializer = true;
}
- type = inType.resolveType(definition.type, false);
+ type = method.resolveType(definition.type, false);
- if (method.isStatic && type.hasTypeParams) {
+ if (method.isStatic && method.typeParameters === null && type.hasTypeParams) {
world.error('using type parameter in static context', definition.span);
}
@@ -62,8 +63,8 @@ class Parameter {
value = value.convertTo(context, type, definition.value);
}
- Parameter copyWithNewType(Type newType) {
- var ret = new Parameter(definition);
+ Parameter copyWithNewType(Member newMethod, Type newType) {
+ var ret = new Parameter(definition, newMethod);
ret.type = newType;
ret.name = name;
ret.isInitializer = isInitializer;
@@ -74,28 +75,15 @@ class Parameter {
}
-interface Named {
- String get name();
- Library get library();
- bool get isNative();
- String get jsname();
- set jsname(String name);
-
- SourceSpan get span();
-}
-
-class Member implements Named {
- final String name;
+class Member extends Element {
final Type declaringType;
- String _jsname;
-
bool isGenerated;
MethodGenerator generator;
- Member(this.name, this.declaringType): isGenerated = false;
-
- abstract SourceSpan get span();
+ Member(String name, Type declaringType)
+ : isGenerated = false, this.declaringType = declaringType,
+ super(name, declaringType);
abstract bool get isStatic();
abstract Type get returnType();
@@ -103,12 +91,6 @@ class Member implements Named {
abstract bool get canGet();
abstract bool get canSet();
- abstract void resolve(Type inType);
-
- String get jsname() => _jsname == null ? name : _jsname;
-
- set jsname(String name) => _jsname = name;
-
Library get library() => declaringType.library;
bool get isPrivate() => name.startsWith('_');
@@ -211,16 +193,6 @@ class Member implements Named {
}
}
- 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;
- }
-
int hashCode() => (declaringType.hashCode() << 4) ^ name.hashCode();
}
@@ -248,8 +220,6 @@ class TypeMember extends Member {
bool get canGet() => true;
bool get canSet() => false;
- void resolve(Type inType) {}
-
Value _get(MethodGenerator context, Node node, Value target,
[bool isDynamic=false]) {
return new Value.type(type, node.span);
@@ -327,7 +297,7 @@ class FieldMember extends Member {
bool get isField() => true;
- resolve(Type inType) {
+ resolve() {
isStatic = declaringType.isTop;
isFinal = false;
if (definition.modifiers != null) {
@@ -347,7 +317,7 @@ class FieldMember extends Member {
}
}
}
- type = inType.resolveType(definition.type, false);
+ type = resolveType(definition.type, false);
if (isStatic && type.hasTypeParams) {
world.error('using type parameter in static context',
definition.type.span);
@@ -534,9 +504,9 @@ class PropertyMember extends Member {
if (setter == null) setter = parent.setter;
}
- resolve(Type inType) {
- if (getter != null) getter.resolve(inType);
- if (setter != null) setter.resolve(inType);
+ resolve() {
+ if (getter != null) getter.resolve();
+ if (setter != null) setter.resolve();
library._addMember(this);
}
@@ -552,11 +522,11 @@ class ConcreteMember extends Member {
: super(name, declaringType) {
parameters = [];
returnType = baseMember.returnType.resolveTypeParams(declaringType);
- // TODO(jimhug): Optimize not creating new array if new param types.
+ // TODO(jimhug): Optimize not creating new array if no new param types.
for (var p in baseMember.parameters) {
var newType = p.type.resolveTypeParams(declaringType);
if (newType != p.type) {
- parameters.add(p.copyWithNewType(newType));
+ parameters.add(p.copyWithNewType(this, newType));
} else {
parameters.add(p);
}
@@ -648,6 +618,10 @@ class MethodMember extends Member {
Type returnType;
List<Parameter> parameters;
+ // Could support generic methods in general. Right now only used for
+ // strange corner case of factory methods for generic types.
+ List<ParameterType> typeParameters;
+
Type _functionType;
bool isStatic = false;
@@ -689,8 +663,11 @@ class MethodMember extends Member {
SourceSpan get span() => definition == null ? null : definition.span;
String get constructorName() {
- NameTypeReference returnType = definition.returnType;
+ var returnType = definition.returnType;
if (returnType == null) return '';
+ if (returnType is GenericTypeReference) {
+ return '';
+ }
// TODO(jmesserly): make this easier?
if (returnType.names != null) {
@@ -703,11 +680,10 @@ class MethodMember extends Member {
Type get functionType() {
if (_functionType == null) {
- _functionType = library.getOrAddFunctionType(name,
- definition, declaringType);
+ _functionType = library.getOrAddFunctionType(declaringType, name, definition);
// TODO(jimhug): Better resolution checks.
if (parameters == null) {
- resolve(declaringType);
+ resolve();
}
}
return _functionType;
@@ -860,7 +836,7 @@ class MethodMember extends Member {
// TODO(jimhug): Fix this hack for ensuring a method is resolved.
if (parameters == null) {
world.info('surprised to need to resolve: ${declaringType.name}.$name');
- this.resolve(declaringType);
+ resolve();
}
declaringType.genMethod(this);
@@ -1215,7 +1191,7 @@ class MethodMember extends Member {
return new Value(declaringType, '${target.code} + ${argsCode[0]}',
node.span);
}
- } else if (declaringType.isNativeType) {
+ } else if (declaringType.isNative) {
if (name == '\$index') {
// Note: this could technically propagate constness, but that's not
// specified explicitly and the VM doesn't do that.
@@ -1274,9 +1250,9 @@ class MethodMember extends Member {
}
- resolve(Type inType) {
+ resolve() {
// TODO(jimhug): cut-and-paste-and-edit from Field.resolve
- isStatic = inType.isTop;
+ isStatic = declaringType.isTop;
isConst = false;
isFactory = false;
isAbstract = !declaringType.isClass;
@@ -1317,6 +1293,20 @@ class MethodMember extends Member {
isStatic = true;
}
+ if (definition.typeParameters != null) {
+ if (!isFactory) {
+ world.error(
+ 'Only factories are allowed to have explicit type parameters',
+ definition.typeParameters[0].span);
+ } else {
+ typeParameters = definition.typeParameters;
+ for (var tp in definition.typeParameters) {
+ tp.enclosingElement = this;
+ tp.resolve();
+ }
+ }
+ }
+
// TODO(jimhug): need a better annotation for being an operator method
if (isOperator && isStatic && !isCallMethod) {
world.error('operator method may not be static "${name}"', span);
@@ -1339,22 +1329,16 @@ class MethodMember extends Member {
}
}
- if (isConstructor) {
+ if (isConstructor && !isFactory) {
returnType = declaringType;
} else {
- // TODO(jimhug): Unify this check and the below with method's
- // resolveType method - requires cleaning up inType stuff.
- returnType = inType.resolveType(definition.returnType, false);
-
- if (isStatic && returnType.hasTypeParams) {
- world.error('using type parameter in static context',
- definition.returnType.span);
- }
+ returnType = resolveType(definition.returnType, false);
}
parameters = [];
for (var formal in definition.formals) {
- var param = new Parameter(formal);
- param.resolve(this, inType);
+ // TODO(jimhug): Clean up construction of Parameters.
+ var param = new Parameter(formal, this);
+ param.resolve();
parameters.add(param);
}
@@ -1362,38 +1346,6 @@ class MethodMember extends Member {
library._addMember(this);
}
}
-
- Type findTypeVariable(TypeReference node, bool isRequired) {
- if (!this.isFactory || node is! NameTypeReference) {
- return super.resolveType(node, isRequired);
- } else {
- // TODO(ahe): We cannot find any type variables as they aren't
- // recorded. So we turn this in to a warning instead.
- return super.resolveType(node, false);
- }
- }
-
- Type resolveType(TypeReference node, bool isRequired) {
- if (node !== null && this.isFactory && isRequired) {
- if (node is GenericTypeReference) {
- // TODO(ahe): This is bascially a copy of code in
- // DefinedType.resolveType. More checks should be performed,
- // such as bounds check, but the code is structured in a way
- // that makes this hard.
- GenericTypeReference genericReference = node;
- var baseType = super.resolveType(genericReference.baseType, isRequired);
- var typeArguments = [];
- for (TypeReference ref in genericReference.typeArguments) {
- // TODO(ahe): This let us ignore T in new Foo<T>, but not in
- // new Foo<Foo<T>>.
- typeArguments.add(findTypeVariable(ref, isRequired));
- }
- node.type = baseType.getOrMakeConcreteType(typeArguments);
- return node.type;
- }
- }
- return super.resolveType(node, isRequired);
- }
}
« no previous file with comments | « frog/library.dart ('k') | frog/parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698