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

Side by Side Diff: frog/gen.dart

Issue 9143001: Fixes 2 tests and a crash (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | frog/member.dart » ('j') | frog/member.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * Top level generator object for writing code and keeping track of 6 * Top level generator object for writing code and keeping track of
7 * dependencies. 7 * dependencies.
8 * 8 *
9 * Should have two compilation models, but only one implemented so far. 9 * Should have two compilation models, but only one implemented so far.
10 * 10 *
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 var lib = toCheck.removeFirst(); 124 var lib = toCheck.removeFirst();
125 if (seen.contains(lib)) continue; 125 if (seen.contains(lib)) continue;
126 seen.add(lib); 126 seen.add(lib);
127 lib.imports.forEach((i) => toCheck.addLast(lib)); 127 lib.imports.forEach((i) => toCheck.addLast(lib));
128 lib.types.getValues().forEach((t) => types.add(t)); 128 lib.types.getValues().forEach((t) => types.add(t));
129 } 129 }
130 } 130 }
131 return types; 131 return types;
132 } 132 }
133 133
134 GlobalValue globalForStaticField(FieldMember field, Value fieldValue, 134 GlobalValue globalForStaticField(FieldMember field, Value exp,
135 List<Value> dependencies) { 135 List<Value> dependencies) {
136 hasStatics = true; 136 hasStatics = true;
137 var fullname = "${field.declaringType.jsname}.${field.jsname}"; 137 var key = "${field.declaringType.jsname}.${field.jsname}";
138 if (!globals.containsKey(fullname)) { 138 var ret = globals[key];
139 globals[fullname] = new GlobalValue.fromStatic( 139 if (ret === null) {
140 field, fieldValue, dependencies); 140 ret = new GlobalValue(exp.type, exp.code, field.isFinal, field, null,
141 exp, exp.span, dependencies);
142 globals[key] = ret;
141 } 143 }
142 return globals[fullname]; 144 return ret;
143 } 145 }
144 146
145 GlobalValue globalForConst(EvaluatedValue exp, List<Value> dependencies) { 147 GlobalValue globalForConst(EvaluatedValue exp, List<Value> dependencies) {
146 // Include type name to ensure unique constants - this matches 148 // Include type name to ensure unique constants - this matches
147 // the code above that includes the type name for static fields. 149 // the code above that includes the type name for static fields.
148 var key = exp.type.jsname + ':' + exp.canonicalCode; 150 var key = exp.type.jsname + ':' + exp.code;
149 if (!globals.containsKey(key)) { 151 var ret = globals[key];
150 globals[key] = 152 if (ret === null) {
151 new GlobalValue.fromConst(globals.length, exp, dependencies); 153 var name = "const\$${globals.length}";
154 ret = new GlobalValue(exp.type, name, true, null, name, exp,
155 exp.span, dependencies);
156 globals[key] = ret;
152 } 157 }
153 assert(globals[key].type == exp.type); 158 assert(ret.type == exp.type);
154 return globals[key]; 159 return ret;
155 } 160 }
156 161
157 writeTypes(Library lib) { 162 writeTypes(Library lib) {
158 if (lib.isWritten) return; 163 if (lib.isWritten) return;
159 164
160 // Do this first to be safe in the face of circular refs. 165 // Do this first to be safe in the face of circular refs.
161 lib.isWritten = true; 166 lib.isWritten = true;
162 167
163 // Ensure all imports have been written. 168 // Ensure all imports have been written.
164 for (var import in lib.imports) { 169 for (var import in lib.imports) {
(...skipping 1763 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 meth.generator.writeDefinition(w, node); 1933 meth.generator.writeDefinition(w, node);
1929 return new Value(meth.functionType, w.text, node.span); 1934 return new Value(meth.functionType, w.text, node.span);
1930 } 1935 }
1931 1936
1932 visitCallExpression(CallExpression node) { 1937 visitCallExpression(CallExpression node) {
1933 var target; 1938 var target;
1934 var position = node.target; 1939 var position = node.target;
1935 var name = ':call'; 1940 var name = ':call';
1936 if (node.target is DotExpression) { 1941 if (node.target is DotExpression) {
1937 DotExpression dot = node.target; 1942 DotExpression dot = node.target;
1938 // ???? 1943 target = dot.self.visit(this);
1939 if (dot.self is LiteralExpression) {
1940 target = (new ParenExpression(dot.self, dot.self.span)).visit(this);
1941 } else {
1942 target = dot.self.visit(this);
1943 }
1944 name = dot.name.name; 1944 name = dot.name.name;
1945 position = dot.name; 1945 position = dot.name;
1946 } else if (node.target is VarExpression) { 1946 } else if (node.target is VarExpression) {
1947 VarExpression varExpr = node.target; 1947 VarExpression varExpr = node.target;
1948 name = varExpr.name.name; 1948 name = varExpr.name.name;
1949 // First check in block scopes. 1949 // First check in block scopes.
1950 target = _scope.lookup(name); 1950 target = _scope.lookup(name);
1951 if (target != null) { 1951 if (target != null) {
1952 return target.invoke(this, ':call', node, _makeArgs(node.arguments)); 1952 return target.invoke(this, ':call', node, _makeArgs(node.arguments));
1953 } 1953 }
(...skipping 17 matching lines...) Expand all
1971 return (e is BinaryExpression || e is ConditionalExpression 1971 return (e is BinaryExpression || e is ConditionalExpression
1972 || e is PostfixExpression || _isUnaryIncrement(e)); 1972 || e is PostfixExpression || _isUnaryIncrement(e));
1973 } 1973 }
1974 1974
1975 visitBinaryExpression(BinaryExpression node, [bool isVoid = false]) { 1975 visitBinaryExpression(BinaryExpression node, [bool isVoid = false]) {
1976 final kind = node.op.kind; 1976 final kind = node.op.kind;
1977 // TODO(jimhug): Ensure these have same semantics as JS! 1977 // TODO(jimhug): Ensure these have same semantics as JS!
1978 if (kind == TokenKind.AND || kind == TokenKind.OR) { 1978 if (kind == TokenKind.AND || kind == TokenKind.OR) {
1979 var x = visitTypedValue(node.x, world.nonNullBool); 1979 var x = visitTypedValue(node.x, world.nonNullBool);
1980 var y = visitTypedValue(node.y, world.nonNullBool); 1980 var y = visitTypedValue(node.y, world.nonNullBool);
1981 final code = '${x.code} ${node.op} ${y.code}'; 1981 return x.binop(kind, y, this, node);
Jennifer Messerly 2012/01/09 19:06:54 so nice!
1982 if (x.isConst && y.isConst) {
1983 var value = (kind == TokenKind.AND)
1984 ? x.actualValue && y.actualValue : x.actualValue || y.actualValue;
1985 return Value.fromBool(value, node.span);
1986 }
1987 return new Value(world.nonNullBool, code, node.span);
1988 } else if (kind == TokenKind.EQ_STRICT || kind == TokenKind.NE_STRICT) { 1982 } else if (kind == TokenKind.EQ_STRICT || kind == TokenKind.NE_STRICT) {
1989 var x = visitValue(node.x); 1983 var x = visitValue(node.x);
1990 var y = visitValue(node.y); 1984 var y = visitValue(node.y);
1991 if (x.isConst && y.isConst) { 1985 return x.binop(kind, y, this, node);
1992 var xVal = x.actualValue;
1993 var yVal = y.actualValue;
1994
1995 // Note: it is ok to use == and not === here since all of these
1996 // constant comparisons are applied to doubles, bool, or strings.
1997 // We need it for the compile-time evaluator because
1998 // (9).toDouble() === 9.0 is false in dartvm.
1999 var value = kind == TokenKind.EQ_STRICT ? xVal == yVal : xVal != yVal;
2000 return Value.fromBool(value, node.span);
2001 }
2002 if (x.code == 'null' || y.code == 'null') {
2003 // Switching to == ensures that null and undefined are interchangable.
2004 final op = node.op.toString().substring(0,2);
2005 return new Value(world.nonNullBool, '${x.code} $op ${y.code}',
2006 node.span);
2007 } else {
2008 // TODO(jimhug): Resolve issue with undefined and null here.
2009 return new Value(world.nonNullBool, '${x.code} ${node.op} ${y.code}',
2010 node.span);
2011 }
2012 } 1986 }
2013 1987
2014 final assignKind = TokenKind.kindFromAssign(node.op.kind); 1988 final assignKind = TokenKind.kindFromAssign(node.op.kind);
2015 if (assignKind == -1) { 1989 if (assignKind == -1) {
2016 final x = visitValue(node.x); 1990 final x = visitValue(node.x);
2017 final y = visitValue(node.y); 1991 final y = visitValue(node.y);
2018 var name = TokenKind.binaryMethodName(node.op.kind); 1992 return x.binop(kind, y, this, node);
2019 if (node.op.kind == TokenKind.NE) {
2020 name = ':ne';
2021 }
2022 if (name == null) {
2023 world.internalError('unimplemented binary op ${node.op}', node.span);
2024 return;
2025 }
2026 return x.invoke(this, name, node, new Arguments(null, [y]));
2027 } else if ((assignKind != 0) && _expressionNeedsParens(node.y)) { 1993 } else if ((assignKind != 0) && _expressionNeedsParens(node.y)) {
2028 return _visitAssign(assignKind, node.x, 1994 return _visitAssign(assignKind, node.x,
2029 new ParenExpression(node.y, node.y.span), node, null, isVoid); 1995 new ParenExpression(node.y, node.y.span), node, null, isVoid);
2030 } else { 1996 } else {
2031 return _visitAssign(assignKind, node.x, node.y, node, null, isVoid); 1997 return _visitAssign(assignKind, node.x, node.y, node, null, isVoid);
2032 } 1998 }
2033 } 1999 }
2034 2000
2035 /** 2001 /**
2036 * Visits an assignment expression. 2002 * Visits an assignment expression.
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2195 this, xn.name.name, xn.name, y); 2161 this, xn.name.name, xn.name, y);
2196 if (tmptarget != target) freeTemp(tmptarget); 2162 if (tmptarget != target) freeTemp(tmptarget);
2197 return ret; 2163 return ret;
2198 } 2164 }
2199 2165
2200 visitUnaryExpression(UnaryExpression node) { 2166 visitUnaryExpression(UnaryExpression node) {
2201 var value = visitValue(node.self); 2167 var value = visitValue(node.self);
2202 switch (node.op.kind) { 2168 switch (node.op.kind) {
2203 case TokenKind.INCR: 2169 case TokenKind.INCR:
2204 case TokenKind.DECR: 2170 case TokenKind.DECR:
2171 // TODO(jimhug): Requires non-null num to be correct.
2205 if (value.type.isNum) { 2172 if (value.type.isNum) {
2206 return new Value(value.type, '${node.op}${value.code}', node.span); 2173 return new Value(value.type, '${node.op}${value.code}', node.span);
2207 } else { 2174 } else {
2208 // ++x becomes x += 1 2175 // ++x becomes x += 1
2209 // --x becomes x -= 1 2176 // --x becomes x -= 1
2210 // TODO(jimhug): Confirm that --x becomes x -= 1 as it is in VM. 2177 // TODO(jimhug): Confirm that --x becomes x -= 1 as it is in VM.
2211 var kind = (TokenKind.INCR == node.op.kind ? 2178 var kind = (TokenKind.INCR == node.op.kind ?
2212 TokenKind.ADD : TokenKind.SUB); 2179 TokenKind.ADD : TokenKind.SUB);
2213 // TODO(jimhug): Shouldn't need a full-expression here. 2180 // TODO(jimhug): Shouldn't need a full-expression here.
2214 var operand = new LiteralExpression(Value.fromInt(1, node.span), 2181 var operand = new LiteralExpression(Value.fromInt(1, node.span),
2215 node.span); 2182 node.span);
2216 2183
2217 var assignValue = _visitAssign(kind, node.self, operand, node, null); 2184 var assignValue = _visitAssign(kind, node.self, operand, node, null);
2218 return new Value(assignValue.type, '(${assignValue.code})', 2185 return new Value(assignValue.type, '(${assignValue.code})',
2219 node.span); 2186 node.span);
2220 } 2187 }
2221 case TokenKind.NOT: 2188 case TokenKind.NOT:
2222 // TODO(jimhug): Issue #359 seeks to clarify this behavior. 2189 // TODO(jimhug): Issue #359 seeks to clarify this behavior.
2223 if (value.type.isBool && value.isConst) { 2190 if (value.type.isBool && value.isConst) {
2224 var newVal = !value.actualValue; 2191 var newVal = !value.actualValue;
2225 return new EvaluatedValue(value.type, newVal, '${newVal}', node.span); 2192 return Value.fromBool(newVal, node.span);
2226 } else { 2193 } else {
2227 var newVal = value.convertTo(this, world.nonNullBool); 2194 var newVal = value.convertTo(this, world.nonNullBool);
2228 return new Value(newVal.type, '!${newVal.code}', node.span); 2195 return new Value(newVal.type, '!${newVal.code}', node.span);
2229 } 2196 }
2230 2197
2231 case TokenKind.ADD: 2198 case TokenKind.ADD:
2232 // TODO(jimhug): Issue #359 seeks to clarify this behavior. 2199 // TODO(jimhug): Issue #359 seeks to clarify this behavior.
2233 return value.convertTo(this, world.numType); 2200 return value.convertTo(this, world.numType);
2234 2201
2235 case TokenKind.SUB: 2202 case TokenKind.SUB:
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2353 2320
2354 // Call the constructor on the type we want to construct. 2321 // Call the constructor on the type we want to construct.
2355 // NOTE: this is important for correct type checking of factories. 2322 // NOTE: this is important for correct type checking of factories.
2356 // If the user calls "new Interface()" we want the result type to be the 2323 // If the user calls "new Interface()" we want the result type to be the
2357 // interface, not the class. 2324 // interface, not the class.
2358 var target = new Value.type(type, typeRef.span); 2325 var target = new Value.type(type, typeRef.span);
2359 return m.invoke(this, node, target, _makeArgs(node.arguments)); 2326 return m.invoke(this, node, target, _makeArgs(node.arguments));
2360 } 2327 }
2361 2328
2362 visitListExpression(ListExpression node) { 2329 visitListExpression(ListExpression node) {
2363 // TODO(jimhug): Use node.type or other type inference here.
2364 var argsCode = [];
2365 var argValues = []; 2330 var argValues = [];
2366 var type = null; 2331 //var listType = node.isConst ? world.immutableListType : world.listType;
Jennifer Messerly 2012/01/09 19:06:54 remove?
jimhug 2012/01/09 21:34:30 Done.
2367 if (node.type != null) { 2332 var listType = world.listType;
2368 // The parser makes node.type a list type, we extract its type argument. 2333 var type = world.varType;
2369 type = method.resolveType(node.type, true).typeArgsInOrder[0]; 2334 if (node.itemType != null) {
2335 type = method.resolveType(node.itemType, true);
2370 if (node.isConst && (type is ParameterType || type.hasTypeParams)) { 2336 if (node.isConst && (type is ParameterType || type.hasTypeParams)) {
2371 world.error('type parameter cannot be used in const list literals'); 2337 world.error('type parameter cannot be used in const list literals');
2372 } 2338 }
2339 listType = listType.getOrMakeConcreteType([type]);
Jennifer Messerly 2012/01/09 19:06:54 correct generic List type, awesome :)
2373 } 2340 }
2374 for (var item in node.values) { 2341 for (var item in node.values) {
2375 var arg = visitTypedValue(item, type); 2342 var arg = visitTypedValue(item, type);
2376 argValues.add(arg); 2343 argValues.add(arg);
2377 if (node.isConst) { 2344 if (node.isConst && !arg.isConst) {
2378 if (!arg.isConst) { 2345 world.error('const list can only contain const values', arg.span);
2379 world.error('const list can only contain const values', item.span);
2380 argsCode.add(arg.code);
2381 } else {
2382 argsCode.add(arg.canonicalCode);
2383 }
2384 } else {
2385 argsCode.add(arg.code);
2386 } 2346 }
2387 } 2347 }
2388 2348
2389 world.listFactoryType.markUsed(); 2349 world.listFactoryType.markUsed();
2390 2350
2391 final code = '[${Strings.join(argsCode, ", ")}]'; 2351 var ret = new ListValue(argValues, node.isConst, listType, node.span);
2392 var value = new Value(world.listType, code, node.span); 2352 if (ret.isConst) return ret.getGlobalValue();
2393 if (node.isConst) { 2353 return ret;
2394 final immutableList = world.immutableListType;
2395 final immutableListCtor = immutableList.getConstructor('from');
2396 final result = immutableListCtor.invoke(this, node,
2397 new Value.type(value.type, node.span), new Arguments(null, [value]));
2398 value = world.gen.globalForConst(
2399 new ConstListValue(immutableList, argValues, 'const $code',
2400 result.code, node.span),
2401 argValues);
2402 }
2403 return value;
2404 } 2354 }
2405 2355
2406 2356
2407 visitMapExpression(MapExpression node) { 2357 visitMapExpression(MapExpression node) {
2408 // Special case the empty non-const map. 2358 // Special case the empty non-const map.
2409 if (node.items.length == 0 && !node.isConst) { 2359 if (node.items.length == 0 && !node.isConst) {
2410 return world.mapType.getConstructor('').invoke(this, node, 2360 return world.mapType.getConstructor('').invoke(this, node,
2411 new Value.type(world.mapType, node.span), Arguments.EMPTY); 2361 new Value.type(world.mapType, node.span), Arguments.EMPTY);
2412 } 2362 }
2413 2363
2414 var argValues = []; 2364 var values = new List<Value>();
Jennifer Messerly 2012/01/09 19:06:54 perhaps: var values = <Value>[]; ?
jimhug 2012/01/09 21:34:30 Done.
2415 var argsCode = []; 2365 var valueType = world.varType, keyType = world.stringType;
2416 var type = null; 2366 var mapType = world.mapType; // TODO(jimhug): immutable type?
2417 if (node.type != null) { 2367 if (node.valueType !== null) {
2418 // node.type is a map type, extract the type argument for the values. 2368 if (node.keyType !== null) {
2419 type = method.resolveType(node.type, true).typeArgsInOrder[1]; 2369 keyType = method.resolveType(node.keyType, true);
2420 if (node.isConst && (type is ParameterType || type.hasTypeParams)) { 2370 // TODO(jimhug): Would be nice to allow arbitrary keys here (this is
2371 // currently not allowed by the spec).
2372 if (!keyType.isString) {
2373 world.error('the key type of a map literal must be "String"',
2374 keyType.span);
2375 }
2376 if (node.isConst && (keyType is ParameterType || keyType.hasTypeParams)) {
Jennifer Messerly 2012/01/09 19:06:54 long line
Jennifer Messerly 2012/01/09 19:06:54 keyType.isUnboundType, or something like that? Whe
jimhug 2012/01/09 21:34:30 Done.
jimhug 2012/01/09 21:34:30 Good idea - for longer-term cleanup. On 2012/01/09
2377 world.error('type parameter cannot be used in const map literals');
2378 }
2379 }
2380
2381 valueType = method.resolveType(node.valueType, true);
2382 if (node.isConst && (valueType is ParameterType || valueType.hasTypeParams )) {
2421 world.error('type parameter cannot be used in const map literals'); 2383 world.error('type parameter cannot be used in const map literals');
2422 } 2384 }
2423 }
2424 for (int i = 0; i < node.items.length; i += 2) {
2425 // TODO(jimhug): Use node.type or other type inference here.
2426 // TODO(jimhug): Would be nice to allow arbitrary keys here (this is
2427 // currently not allowed by the spec).
2428 var key = visitTypedValue(node.items[i], world.stringType);
2429 final valueItem = node.items[i+1];
2430 var value = visitTypedValue(valueItem, type);
2431 argValues.add(key);
2432 argValues.add(value);
2433 2385
2434 if (node.isConst) { 2386 mapType = mapType.getOrMakeConcreteType([keyType, valueType]);
2435 if (!key.isConst || !value.isConst) {
2436 world.error('const map can only contain const values',
2437 valueItem.span);
2438 argsCode.add(key.code);
2439 argsCode.add(value.code);
2440 } else {
2441 argsCode.add(key.canonicalCode);
2442 argsCode.add(value.canonicalCode);
2443 }
2444 } else {
2445 argsCode.add(key.code);
2446 argsCode.add(value.code);
2447 }
2448 } 2387 }
2449 2388
2450 var argList = '[${Strings.join(argsCode, ", ")}]'; 2389 for (int i = 0; i < node.items.length; i += 2) {
2451 var items = new Value(world.listType, argList, node.span); 2390 var key = visitTypedValue(node.items[i], keyType);
2452 var tp = world.corelib.topType; 2391 if (node.isConst && !key.isConst) {
2453 Member f = node.isConst ? tp.getMember('_constMap') : tp.getMember('_map'); 2392 world.error('const map can only contain const keys', key.span);
2454 var value = f.invoke(this, node, new Value.type(tp, null), 2393 }
2455 new Arguments(null, [items])); 2394 values.add(key);
2456 2395
2457 if (node.isConst) { 2396 var value = visitTypedValue(node.items[i+1], valueType);
Jennifer Messerly 2012/01/09 19:06:54 nit: spacing on i + 1
jimhug 2012/01/09 21:34:30 Done.
2458 value = new ConstMapValue(value.type, argValues, value.code, 2397 if (node.isConst && !value.isConst) {
2459 value.code, value.span); 2398 world.error('const map can only contain const values', value.span);
2460 return world.gen.globalForConst(value, argValues); 2399 }
2461 } else { 2400 values.add(value);
2462 return value;
2463 } 2401 }
2402
2403 var ret = new MapValue(values, node.isConst, mapType, node.span);
2404 if (ret.isConst) return ret.getGlobalValue();
2405 return ret;
2464 } 2406 }
2465 2407
2466 visitConditionalExpression(ConditionalExpression node) { 2408 visitConditionalExpression(ConditionalExpression node) {
2467 var test = visitBool(node.test); 2409 var test = visitBool(node.test);
2468 var trueBranch = visitValue(node.trueBranch); 2410 var trueBranch = visitValue(node.trueBranch);
2469 var falseBranch = visitValue(node.falseBranch); 2411 var falseBranch = visitValue(node.falseBranch);
2470 2412
2471 var code = '${test.code} ? ${trueBranch.code} : ${falseBranch.code}'; 2413 var code = '${test.code} ? ${trueBranch.code} : ${falseBranch.code}';
2472 return new Value(Type.union(trueBranch.type, falseBranch.type), code, 2414 return new Value(Type.union(trueBranch.type, falseBranch.type), code,
2473 node.span); 2415 node.span);
2474 } 2416 }
2475 2417
2476 visitIsExpression(IsExpression node) { 2418 visitIsExpression(IsExpression node) {
2477 var value = visitValue(node.x); 2419 var value = visitValue(node.x);
2478 var type = method.resolveType(node.type, false); 2420 var type = method.resolveType(node.type, false);
2479 return value.instanceOf(this, type, node.span, node.isTrue); 2421 return value.instanceOf(this, type, node.span, node.isTrue);
2480 } 2422 }
2481 2423
2482 visitParenExpression(ParenExpression node) { 2424 visitParenExpression(ParenExpression node) {
2483 var body = visitValue(node.body); 2425 var body = visitValue(node.body);
2484 if (body.isConst) { 2426 // Assumption implicit here that const values never need parens...
2485 return new EvaluatedValue(body.type, body.actualValue, 2427 if (body.isConst) return body;
2486 '(${body.canonicalCode})', node.span);
2487 }
2488 return new Value(body.type, '(${body.code})', node.span); 2428 return new Value(body.type, '(${body.code})', node.span);
2489 } 2429 }
2490 2430
2491 visitDotExpression(DotExpression node) { 2431 visitDotExpression(DotExpression node) {
2492 // Types are legal targets of . 2432 // Types are legal targets of .
2493 var target = node.self.visit(this); 2433 var target = node.self.visit(this);
2494 return target.get_(this, node.name.name, node.name); 2434 return target.get_(this, node.name.name, node.name);
2495 } 2435 }
2496 2436
2497 visitVarExpression(VarExpression node) { 2437 visitVarExpression(VarExpression node) {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2669 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); 2609 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false));
2670 } 2610 }
2671 for (int i = bareCount; i < length; i++) { 2611 for (int i = bareCount; i < length; i++) {
2672 var name = getName(i); 2612 var name = getName(i);
2673 if (name == null) name = '\$$i'; 2613 if (name == null) name = '\$$i';
2674 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); 2614 result.add(new Value(world.varType, name, null, /*needsTemp:*/false));
2675 } 2615 }
2676 return new Arguments(nodes, result); 2616 return new Arguments(nodes, result);
2677 } 2617 }
2678 } 2618 }
OLDNEW
« no previous file with comments | « no previous file | frog/member.dart » ('j') | frog/member.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698