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

Unified Diff: frog/member.dart

Issue 9107067: Work in progress: changes to interpretation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: work in progress Created 8 years, 11 months 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/lib/corelib_impl.dart ('k') | frog/type.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 5d34ab7969397e42088dc305f39f985cab6ee4ef..68391fefddf6744c01b8465fe120ef7bb5649ada 100644
--- a/frog/member.dart
+++ b/frog/member.dart
@@ -15,6 +15,8 @@ class Parameter {
Parameter(this.definition, this.method);
+ SourceSpan get span() => definition.span;
+
resolve() {
name = definition.name.name;
if (name.startsWith('this.')) {
@@ -49,13 +51,13 @@ class Parameter {
}
}
- genValue(MethodMember method, MethodGenerator context) {
+ genValue(MethodMember method, [MethodGenerator context]) {
if (definition.value == null || value != null) return;
if (context == null) { // interface method
- context = new MethodGenerator(method, null);
+ context = new MethodGenerator(method);
}
- value = definition.value.visit(context);
+ value = context.evalExpression(definition.value);
if (!value.isConst) {
world.error('default parameter values must be constant', value.span);
}
@@ -84,11 +86,15 @@ class Parameter {
class Member extends Element {
final Type declaringType;
- bool isGenerated;
- MethodGenerator generator;
+ bool isUsed;
+
+ // TODO(jmesserly): this only makes sense if we never specialize functions
+ // for their argument types.
+ MethodGenerator get generator() => specializer.generator;
+ MethodSpecializer specializer;
Member(String name, Type declaringType)
- : isGenerated = false, this.declaringType = declaringType,
+ : isUsed = false, this.declaringType = declaringType,
super(name, declaringType);
abstract bool get isStatic();
@@ -142,24 +148,12 @@ class Member extends Element {
world.internalError('cannot have value', span);
}
- /**
- * The inferred returnType. Right now this is just used to track
- * non-nullable bools.
- */
- Type get inferredResult() {
- var t = returnType;
- if (t.isBool && (library.isCore || library.isCoreImpl)) {
- // We trust our core libraries not to return null from bools.
- // I hope this trust is well placed!
- return world.nonNullBool;
- }
- return t;
- }
-
Definition get definition() => null;
List<Parameter> get parameters() => [];
+ void markUsed() => declaringType.markUsedMethod(this);
+
MemberSet _preciseMemberSet, _potentialMemberSet;
MemberSet get preciseMemberSet() {
@@ -435,8 +429,7 @@ class FieldMember extends Member {
_computing = true;
var finalMethod = new MethodMember('final_context', declaringType, null);
finalMethod.isStatic = true;
- var finalGen = new MethodGenerator(finalMethod, null);
- _computedValue = value.visit(finalGen);
+ _computedValue = new MethodGenerator(finalMethod).evalExpression(value);
if (!_computedValue.isConst) {
if (isStatic) {
world.error(
@@ -711,6 +704,11 @@ class ConcreteMember extends Member {
// TODO(jimhug): Add support for type params.
bool override(Member other) => baseMember.override(other);
+ // TODO(jmesserly): this hack is needed because ConcreteMember is using
+ // baseMember to do the operation, then replacing the type on the Value.
+ // Something else needs to happen.
+ Type get inferredResult() => returnType;
+
Value _get(MethodGenerator context, Node node, Value target,
[bool isDynamic=false]) {
Value ret = baseMember._get(context, node, target, isDynamic);
@@ -721,7 +719,7 @@ class ConcreteMember extends Member {
[bool isDynamic=false]) {
// TODO(jimhug): Check arg types in context of concrete type.
Value ret = baseMember._set(context, node, target, value, isDynamic);
- return new Value(returnType, ret.code, node.span);
+ return new Value(inferredResult, ret.code, node.span);
}
_evalConstConstructor(ObjectValue newObject, Arguments args) {
@@ -744,7 +742,10 @@ class ConcreteMember extends Member {
declaringType.genericType.jsname, declaringType.jsname);
}
if (baseMember is MethodMember) {
- declaringType.genMethod(this);
+ // TODO(jmesserly): we should be filling in the right args here and
+ // using the result type. But the args need to be reordered to match the
+ // call site, like baseMember.invoke does.
+ world.gen.invokeMethod(this, target, null);
}
return new Value(inferredResult, code, node.span);
}
@@ -880,8 +881,11 @@ class MethodMember extends Member {
Value _get(MethodGenerator context, Node node, Value target,
[bool isDynamic=false]) {
- // TODO(jimhug): Would prefer to invoke!
- declaringType.genMethod(this);
+
+ // TODO(jmesserly): if we tracked functions as values, this would be the
+ // place to do it.
+ world.gen.invokeMethod(this);
+
_provideOptionalParamInfo = true;
if (isStatic) {
// ensure the type is generated.
@@ -979,7 +983,7 @@ class MethodMember extends Member {
genParameterValues() {
// Pure lazy?
- for (var p in parameters) p.genValue(this, generator);
+ for (var p in parameters) p.genValue(this);
}
/**
@@ -994,8 +998,6 @@ class MethodMember extends Member {
resolve();
}
- declaringType.genMethod(this);
-
if (isStatic || isFactory) {
// TODO(sigmund): can we avoid generating the entire type, but only what
// we need?
@@ -1013,11 +1015,7 @@ class MethodMember extends Member {
return context.findMembers(name).invokeOnVar(context, node, target, args);
}
- var argsCode = [];
- if (!target.isType && (isConstructor || target.isSuper)) {
- argsCode.add('this');
- }
-
+ final argValues = <Value>[];
int bareCount = args.bareCount;
for (int i = 0; i < bareCount; i++) {
var arg = args.values[i];
@@ -1026,7 +1024,7 @@ class MethodMember extends Member {
return _argError(context, node, target, args, msg, i);
}
arg = arg.convertTo(context, parameters[i].type, isDynamic);
- argsCode.add(arg.code);
+ argValues.add(arg);
}
int namedArgsUsed = 0;
@@ -1046,10 +1044,9 @@ class MethodMember extends Member {
var msg = _argCountMsg(Math.min(i, args.length), i + 1, atLeast:true);
return _argError(context, node, target, args, msg, i);
} else {
- argsCode.add(arg.code);
+ argValues.add(arg);
}
}
- Arguments.removeTrailingNulls(argsCode);
}
if (namedArgsUsed < args.nameCount) {
@@ -1077,7 +1074,19 @@ class MethodMember extends Member {
world.internalError('wrong named arguments calling $name', node.span);
}
- var argsString = Strings.join(argsCode, ', ');
+ // TODO(jmesserly): maybe this should be producing the result Value, and we
+ // just return on this line.
+ Type inferredResult = world.gen.invokeMethod(this, target,
+ new Arguments(null, argValues));
+
+ final argsCode = map(argValues, (v) => v.code);
+ if (!target.isType && (isConstructor || target.isSuper)) {
+ argsCode.insertRange(0, 1, 'this');
+ }
+ if (namedArgsUsed < args.nameCount) {
+ Arguments.removeTrailingNulls(argsCode);
+ }
+ final argsString = Strings.join(argsCode, ', ');
if (isConstructor) {
return _invokeConstructor(context, node, target, args, argsString);
@@ -1090,7 +1099,8 @@ class MethodMember extends Member {
}
if (isOperator) {
- return _invokeBuiltin(context, node, target, args, argsCode, isDynamic);
+ return _invokeBuiltin(context, node, target, args, argsCode, isDynamic,
+ inferredResult);
}
if (isFactory) {
@@ -1155,12 +1165,11 @@ class MethodMember extends Member {
_evalConstConstructor(Value newObject, Arguments args) {
declaringType.markUsed();
- var generator = new MethodGenerator(this, null);
- generator.evalBody(newObject, args);
+ new MethodGenerator(this).evalBody(newObject, args);
}
Value _invokeBuiltin(MethodGenerator context, Node node, Value target,
- Arguments args, argsCode, bool isDynamic) {
+ Arguments args, argsCode, bool isDynamic, Type inferredResult) {
// Handle some fast paths for Number, String, List and DOM.
if (declaringType.isNum) {
// TODO(jimhug): This fails in bad ways when argsCode[1] is not num.
« no previous file with comments | « frog/lib/corelib_impl.dart ('k') | frog/type.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698