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

Unified Diff: frog/value.dart

Issue 8523012: first stage of Value cleanups (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebased 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
Index: frog/value.dart
diff --git a/frog/value.dart b/frog/value.dart
index 79d2eee608bc93d8fa25d90ca465d32ce19c0c49..e370fda36f36f7933c05f2bf12bfc5a9f896b3ea 100644
--- a/frog/value.dart
+++ b/frog/value.dart
@@ -12,6 +12,9 @@ class Value {
/** The code to generate this value. */
String code;
+ /** The source location that created this value for error messages. */
+ SourceSpan span;
Jennifer Messerly 2011/11/10 22:50:39 this makes me happy. I bet we can start slowly rat
+
/** Is this a reference to super? */
bool isSuper;
@@ -21,7 +24,7 @@ class Value {
/** If we reference this value multiple times, do we need a temp? */
bool needsTemp;
- Value(this.type, this.code,
+ Value(this.type, this.code, this.span,
// TODO(sigmund): reorder, so that needsTemp comes first.
[this.isSuper = false, this.needsTemp = true, this.isType = false]) {
if (type == null) type = world.varType;
@@ -30,36 +33,32 @@ class Value {
/** Is this value a constant expression? */
bool get isConst() => false;
- // TODO(jimhug): These three methods are still a little too similar for me.
- get_(MethodGenerator context, String name, Node node) {
- var member = _resolveMember(context, name, node);
- if (member != null) {
- member = member.get_(context, node, this);
- }
- // member.get_ returns null if no signatures match the given node.
+ // TODO(jimhug): Fix these names once get/set are truly pseudo-keywords.
+ // See issue #379.
+ Value get_(MethodGenerator context, String name, Node node) {
+ final member = _resolveMember(context, name, node);
if (member != null) {
- return member;
+ return member._get(context, node, this);
} else {
return invokeNoSuchMethod(context, 'get:$name', node);
}
}
- set_(MethodGenerator context, String name, Node node, Value value,
+ Value set_(MethodGenerator context, String name, Node node, Value value,
[bool isDynamic=false]) {
- var member = _resolveMember(context, name, node, isDynamic);
- if (member != null) {
- member = member.set_(context, node, this, value, isDynamic);
- }
- // member.set_ returns null if no signatures match the given node.
+
+ final member = _resolveMember(context, name, node, isDynamic);
if (member != null) {
- return member;
+ return member._set(context, node, this, value, isDynamic);
} else {
return invokeNoSuchMethod(context, 'set:$name', node,
new Arguments(null, [value]));
}
}
- invoke(MethodGenerator context, String name, Node node, Arguments args,
+
+
+ Value invoke(MethodGenerator context, String name, Node node, Arguments args,
[bool isDynamic=false]) {
// TODO(jimhug): The != method is weird - understand it better.
if (type.isVar && name == '\$ne') {
@@ -67,7 +66,7 @@ class Value {
world.warning('wrong number of arguments for !=', node.span);
}
world.gen.corejs.useOperator('\$ne');
- return new Value(null, '\$ne($code, ${args.values[0].code})');
+ return new Value(null, '\$ne($code, ${args.values[0].code})', node.span);
}
// TODO(jmesserly): it'd be nice to remove these special cases
@@ -124,6 +123,14 @@ class Value {
}
}
+ _tryResolveMember(MethodGenerator context, String name) {
Jennifer Messerly 2011/11/10 22:50:39 funny! I had it factored this way at one point, bu
+ if (isSuper) {
+ return type.getMember(name);
+ } else {
+ return type.resolveMember(name);
+ }
+ }
+
// TODO(jimhug): Better type here - currently is union(Member, MemberSet)
_resolveMember(MethodGenerator context, String name, Node node,
[bool isDynamic=false]) {
@@ -132,11 +139,7 @@ class Value {
// ParameterType as "var".
var member;
if (!type.isVar && type is! ParameterType) {
- if (isSuper) {
- member = type.getMember(name);
- } else {
- member = type.resolveMember(name);
- }
+ member = _tryResolveMember(context, name);
if (member != null && isType && !member.isStatic) {
if (!isDynamic) {
@@ -180,7 +183,7 @@ class Value {
// which normally happen on the caller side, or in the generated stub for
// dynamic method calls. What should we do?
var stub = world.functionType.getCallStub(args);
- return new Value(null, '$code.${stub.name}(${args.getCode()})');
+ return new Value(null, '$code.${stub.name}(${args.getCode()})', span);
}
/** True if convertTo would generate a conversion. */
@@ -228,7 +231,7 @@ class Value {
var myCall = type.getCallMethod();
if (myCall == null || myCall.parameters.length != arity) {
final stub = world.functionType.getCallStub(new Arguments.bare(arity));
- var val = new Value(toType, 'to\$${stub.name}($code)');
+ var val = new Value(toType, 'to\$${stub.name}($code)', node.span);
return _isDomCallback(toType) && !_isDomCallback(type) ?
val._wrapDomCallback(toType, arity) : val;
} else if (_isDomCallback(toType) && !_isDomCallback(type)) {
@@ -285,7 +288,7 @@ class Value {
return this;
} else {
world.gen.corejs.useNotNullBool = true;
- return new Value(world.boolType, '\$notnull_bool($code)');
+ return new Value(world.boolType, '\$notnull_bool($code)', span);
}
}
}
@@ -296,7 +299,7 @@ class Value {
}
Value _wrapDomCallback(Type toType, int arity) {
- return new Value(toType, '\$wrap_call\$$arity($code)');
+ return new Value(toType, '\$wrap_call\$$arity($code)', span);
}
/**
@@ -344,7 +347,7 @@ function \$assert_${toType.name}(x) {
if (this != temp) context.freeTemp(temp);
}
- return new Value(toType, check);
+ return new Value(toType, check, span);
}
/**
@@ -401,7 +404,7 @@ function \$assert_${toType.name}(x) {
}
if (this != temp) context.freeTemp(temp);
}
- return new Value(world.boolType, testCode);
+ return new Value(world.boolType, testCode, span);
}
void convertWarning(Type toType, Node node) {
@@ -421,8 +424,8 @@ function \$assert_${toType.name}(x) {
pos = Strings.join(argsCode, ", "); // don't remove trailing nulls
}
final noSuchArgs = [
- new Value(world.stringType, '"$name"'),
- new Value(world.listType, '[$pos]')];
+ new Value(world.stringType, '"$name"', node.span),
+ new Value(world.listType, '[$pos]', node.span)];
// TODO(jmesserly): should be passing names but that breaks tests. Oh well.
/*if (args != null && args.hasNames) {
@@ -451,11 +454,11 @@ function \$assert_${toType.name}(x) {
// Most operator calls need to be emitted as function calls, so we don't
// box numbers accidentally. Indexing is the exception.
if (name == '\$index' || name == '\$setindex') {
- return new Value(returnType, '$code.$name($argsString)');
+ return new Value(returnType, '$code.$name($argsString)', span);
} else {
if (argsString.length > 0) argsString = ', $argsString';
world.gen.corejs.useOperator(name);
- return new Value(returnType, '$name($code$argsString)');
+ return new Value(returnType, '$name($code$argsString)', span);
}
}
}
@@ -476,21 +479,19 @@ class EvaluatedValue extends Value {
*/
String canonicalCode;
- /** Original span where this evaluated expression came from. */
- SourceSpan original;
-
- factory EvaluatedValue(type, actualValue, canonicalCode, original) {
+ factory EvaluatedValue(Type type, actualValue, String canonicalCode,
+ SourceSpan span) {
return new EvaluatedValue._internal(type, actualValue,
- canonicalCode, original, codeWithComments(canonicalCode, original));
+ canonicalCode, span, codeWithComments(canonicalCode, span));
}
- EvaluatedValue._internal(
- type, this.actualValue, this.canonicalCode, this.original, code)
- : super(type, code, false, false, false);
+ EvaluatedValue._internal(Type type, this.actualValue, this.canonicalCode,
+ SourceSpan span, String code)
+ : super(type, code, span, false, false, false);
- static String codeWithComments(String canonicalCode, SourceSpan original) {
- return (original != null && original.text != canonicalCode)
- ? '$canonicalCode/*${original.text}*/' : canonicalCode;
+ static String codeWithComments(String canonicalCode, SourceSpan span) {
+ return (span != null && span.text != canonicalCode)
+ ? '$canonicalCode/*${span.text}*/' : canonicalCode;
}
}
@@ -499,14 +500,14 @@ class ConstListValue extends EvaluatedValue {
List<EvaluatedValue> values;
factory ConstListValue(Type type, List<EvaluatedValue> values,
- String actualValue, String canonicalCode, SourceSpan original) {
+ String actualValue, String canonicalCode, SourceSpan span) {
return new ConstListValue._internal(type, values, actualValue,
- canonicalCode, original, codeWithComments(canonicalCode, original));
+ canonicalCode, span, codeWithComments(canonicalCode, span));
}
ConstListValue._internal(type, this.values,
- actualValue, canonicalCode, original, code) :
- super._internal(type, actualValue, canonicalCode, original, code);
+ actualValue, canonicalCode, span, code) :
+ super._internal(type, actualValue, canonicalCode, span, code);
}
/** An evaluated constant map expression. */
@@ -514,18 +515,18 @@ class ConstMapValue extends EvaluatedValue {
Map<String, EvaluatedValue> values;
factory ConstMapValue(Type type, List<EvaluatedValue> keyValuePairs,
- String actualValue, String canonicalCode, SourceSpan original) {
+ String actualValue, String canonicalCode, SourceSpan span) {
final values = new Map<String, EvaluatedValue>();
for (int i = 0; i < keyValuePairs.length; i += 2) {
values[keyValuePairs[i].actualValue] = keyValuePairs[i + 1];
}
return new ConstMapValue._internal(type, values, actualValue,
- canonicalCode, original, codeWithComments(canonicalCode, original));
+ canonicalCode, span, codeWithComments(canonicalCode, span));
}
ConstMapValue._internal(type, this.values,
- actualValue, canonicalCode, original, code) :
- super._internal(type, actualValue, canonicalCode, original, code);
+ actualValue, canonicalCode, span, code) :
+ super._internal(type, actualValue, canonicalCode, span, code);
}
/** An evaluated constant object expression. */
@@ -534,7 +535,7 @@ class ConstObjectValue extends EvaluatedValue {
factory ConstObjectValue(
Type type, Map<String, EvaluatedValue> fields,
- String canonicalCode, SourceSpan original) {
+ String canonicalCode, SourceSpan span) {
// compute a unique-string form used to index this value in the global const
// map. This is used to ensure that multiple const object values are
// equivalent if they have the same type name and values on each field.
@@ -546,12 +547,12 @@ class ConstObjectValue extends EvaluatedValue {
final actualValue = 'const ${type.jsname} ['
+ Strings.join(fieldValues, ',') + ']';
return new ConstObjectValue._internal(type, fields, actualValue,
- canonicalCode, original, codeWithComments(canonicalCode, original));
+ canonicalCode, span, codeWithComments(canonicalCode, span));
}
ConstObjectValue._internal(type, this.fields,
- actualValue, canonicalCode, original, code) :
- super._internal(type, actualValue, canonicalCode, original, code);
+ actualValue, canonicalCode, span, code) :
+ super._internal(type, actualValue, canonicalCode, span, code);
}
@@ -578,9 +579,6 @@ class GlobalValue extends Value implements Comparable {
*/
String canonicalCode;
- /** Original span where this value came from. */
- SourceSpan original;
-
/** True for either cont expressions or a final static field. */
bool get isConst() => exp.isConst && (field == null || field.isFinal);
@@ -590,27 +588,27 @@ class GlobalValue extends Value implements Comparable {
/** Other globals that should be defined before this global. */
List<GlobalValue> dependencies;
- factory GlobalValue.fromStatic(field, exp, dependencies) {
+ factory GlobalValue.fromStatic(field, Value exp, dependencies) {
var code = (exp.isConst ? exp.canonicalCode : exp.code);
var codeWithComment = '$code/*${field.declaringType.name}.${field.name}*/';
return new GlobalValue(
exp.type, codeWithComment, field.isFinal, field, null, exp,
- code, null, dependencies.filter((d) => d is GlobalValue));
+ code, exp.span, dependencies.filter((d) => d is GlobalValue));
}
- factory GlobalValue.fromConst(uniqueId, exp, dependencies) {
+ factory GlobalValue.fromConst(uniqueId, Value exp, dependencies) {
var name = "const\$$uniqueId";
- var codeWithComment = "$name/*${exp.original.text}*/";
+ var codeWithComment = "$name/*${exp.span.text}*/";
return new GlobalValue(
exp.type, codeWithComment, true, null, name, exp, name,
- exp.original,
+ exp.span,
dependencies.filter((d) => d is GlobalValue));
}
- GlobalValue(type, code, isConst,
+ GlobalValue(Type type, String code, bool isConst,
this.field, this.name, this.exp, this.canonicalCode,
- this.original, this.dependencies)
- : super(type, code, false, !isConst, false);
+ SourceSpan span, this.dependencies)
+ : super(type, code, span, false, !isConst, false);
int compareTo(GlobalValue other) {
// order by dependencies, o.w. by name
@@ -635,3 +633,41 @@ class GlobalValue extends Value implements Comparable {
}
}
}
+
+/**
+ * Represents the hidden or implicit value in a bare reference like 'a'.
+ * This could be this, the current type, or the current library for purposes
+ * of resolving members.
+ */
+class BareValue extends Value {
Jennifer Messerly 2011/11/10 22:50:39 +1
+ MethodGenerator home;
+
+ BareValue(this.home, MethodGenerator outermost, SourceSpan span):
+ super(outermost.method.declaringType, null, span, false, false,
+ outermost.isStatic);
+
+ _tryResolveMember(MethodGenerator context, String name) {
+ assert(context == home);
+
+ // First look for members directly defined on my type.
+ var member = type.resolveMember(name);
+ if (member != null) {
+ assert(code == null);
+ // TODO(jimhug): Lazy initialization here is weird!
+ if (isType) {
+ code = type.jsname;
+ } else {
+ code = home._makeThisCode();
+ }
+ return member;
+ }
+
+ // Then look for members in my library.
+ member = home.library.lookup(name, span);
+ if (member != null) {
+ return member;
+ }
+
+ return null;
+ }
+}
« frog/member.dart ('K') | « frog/member.dart ('k') | frog/var_member.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698