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

Side by Side Diff: frog/gen.dart

Issue 9110027: Some cleanups to Frog to avoid looking up its builtin types too much (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: removed dead files 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
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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 var filename = basename(file.filename); 177 var filename = basename(file.filename);
178 writer.comment('// ********** Natives $filename **************'); 178 writer.comment('// ********** Natives $filename **************');
179 writer.writeln(file.text); 179 writer.writeln(file.text);
180 } 180 }
181 lib.topType.markUsed(); // TODO(jimhug): EGREGIOUS HACK 181 lib.topType.markUsed(); // TODO(jimhug): EGREGIOUS HACK
182 182
183 for (var type in _orderValues(lib.types)) { 183 for (var type in _orderValues(lib.types)) {
184 // TODO(jmesserly): we can't accurately track if DOM types are 184 // TODO(jmesserly): we can't accurately track if DOM types are
185 // created or not, so we need to prepare to handle them. 185 // created or not, so we need to prepare to handle them.
186 // This should be fixed by tightening up the return types in DOM. 186 // This should be fixed by tightening up the return types in DOM.
187 if ((type.isUsed || type.library == world.dom 187 if ((type.isUsed || type.library.isDom
188 || type.isHiddenNativeType) && type.isClass) { 188 || type.isHiddenNativeType) && type.isClass) {
189 writeType(type); 189 writeType(type);
190 190
191 if (type.isGeneric) { 191 if (type.isGeneric) {
192 for (var ct in _orderValues(type._concreteTypes)) { 192 for (var ct in _orderValues(type._concreteTypes)) {
193 writeType(ct); 193 writeType(ct);
194 } 194 }
195 } 195 }
196 } else if (type.isFunction && type.varStubs.length > 0) { 196 } else if (type.isFunction && type.varStubs.length > 0) {
197 // Emit stubs on "Function" or hidden types if needed 197 // Emit stubs on "Function" or hidden types if needed
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 } 233 }
234 234
235 if (checkType.isChecked) { 235 if (checkType.isChecked) {
236 String body = 'return this'; 236 String body = 'return this';
237 String checkName = 'assert\$${checkType.jsname}'; 237 String checkName = 'assert\$${checkType.jsname}';
238 if (!isSubtype) { 238 if (!isSubtype) {
239 // Get the code to throw a TypeError. 239 // Get the code to throw a TypeError.
240 // TODO(jmesserly): it'd be nice not to duplicate this code, and instead 240 // TODO(jmesserly): it'd be nice not to duplicate this code, and instead
241 // be able to refer to the JS function. 241 // be able to refer to the JS function.
242 body = world.objectType.varStubs[checkName].body; 242 body = world.objectType.varStubs[checkName].body;
243 } else if (onType.name == 'StringImplementation' || 243 } else if (onType == world.stringImplType
244 onType.name == 'NumImplementation') { 244 || onType == world.numImplType) {
245 body = 'return ${onType.nativeType.name}(this)'; 245 body = 'return ${onType.nativeType.name}(this)';
246 } 246 }
247 writer.writeln(_prototypeOf(onType, checkName) + ' = function(){$body};'); 247 writer.writeln(_prototypeOf(onType, checkName) + ' = function(){$body};');
248 } 248 }
249 } 249 }
250 250
251 writeType(Type type) { 251 writeType(Type type) {
252 if (type.isWritten) return; 252 if (type.isWritten) return;
253 253
254 type.isWritten = true; 254 type.isWritten = true;
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 549
550 _usedDynamicDispatchOnType(Type type) { 550 _usedDynamicDispatchOnType(Type type) {
551 if (typesWithDynamicDispatch == null) typesWithDynamicDispatch = new Set(); 551 if (typesWithDynamicDispatch == null) typesWithDynamicDispatch = new Set();
552 typesWithDynamicDispatch.add(type); 552 typesWithDynamicDispatch.add(type);
553 } 553 }
554 554
555 writeDynamicDispatchMetadata() { 555 writeDynamicDispatchMetadata() {
556 if (typesWithDynamicDispatch == null) return; 556 if (typesWithDynamicDispatch == null) return;
557 writer.comment('// ${typesWithDynamicDispatch.length} dynamic types.'); 557 writer.comment('// ${typesWithDynamicDispatch.length} dynamic types.');
558 558
559 typeTag(type) => type.definition.nativeType.name;
560
561 // Build a pre-order traversal over all the types and their subtypes. 559 // Build a pre-order traversal over all the types and their subtypes.
562 var seen = new Set(); 560 var seen = new Set();
563 var types = []; 561 var types = [];
564 visit(type) { 562 visit(type) {
565 if (seen.contains(type)) return; 563 if (seen.contains(type)) return;
566 seen.add(type); 564 seen.add(type);
567 for (final subtype in _orderCollectionValues(type.directSubtypes)) { 565 for (final subtype in _orderCollectionValues(type.directSubtypes)) {
568 visit(subtype); 566 visit(subtype);
569 } 567 }
570 types.add(type); 568 types.add(type);
(...skipping 22 matching lines...) Expand all
593 // Dart objects could be easily excluded, then we might be able to simplify 591 // Dart objects could be easily excluded, then we might be able to simplify
594 // the test, replacing dozens of HTMLxxxElement types with the regexp 592 // the test, replacing dozens of HTMLxxxElement types with the regexp
595 // /HTML.*Element/. 593 // /HTML.*Element/.
596 594
597 var varNames = []; // temporary variables for common substrings. 595 var varNames = []; // temporary variables for common substrings.
598 var varDefns = {}; // var -> expression 596 var varDefns = {}; // var -> expression
599 var tagDefns = {}; // tag -> expression (a string or a variable) 597 var tagDefns = {}; // tag -> expression (a string or a variable)
600 598
601 makeExpression(type) { 599 makeExpression(type) {
602 var expressions = []; // expression fragments for this set of type keys. 600 var expressions = []; // expression fragments for this set of type keys.
603 var subtags = [typeTag(type)]; // TODO: Remove if type is abstract. 601 var subtags = [type.nativeName]; // TODO: Remove if type is abstract.
604 walk(type) { 602 walk(type) {
605 for (final subtype in _orderCollectionValues(type.directSubtypes)) { 603 for (final subtype in _orderCollectionValues(type.directSubtypes)) {
606 var tag = typeTag(subtype); 604 var tag = subtype.nativeName;
607 var existing = tagDefns[tag]; 605 var existing = tagDefns[tag];
608 if (existing == null) { 606 if (existing == null) {
609 subtags.add(tag); 607 subtags.add(tag);
610 walk(subtype); 608 walk(subtype);
611 } else { 609 } else {
612 if (varDefns.containsKey(existing)) { 610 if (varDefns.containsKey(existing)) {
613 expressions.add(existing); 611 expressions.add(existing);
614 } else { 612 } else {
615 var varName = 'v${varNames.length}/*${tag}*/'; 613 var varName = 'v${varNames.length}/*${tag}*/';
616 varNames.add(varName); 614 varNames.add(varName);
(...skipping 10 matching lines...) Expand all
627 var expression; 625 var expression;
628 if (expressions.length == 1) { 626 if (expressions.length == 1) {
629 expression = expressions[0]; 627 expression = expressions[0];
630 } else { 628 } else {
631 expression = "[${Strings.join(expressions, ',')}].join('|')"; 629 expression = "[${Strings.join(expressions, ',')}].join('|')";
632 } 630 }
633 return expression; 631 return expression;
634 } 632 }
635 633
636 for (final type in dispatchTypes) { 634 for (final type in dispatchTypes) {
637 tagDefns[typeTag(type)] = makeExpression(type); 635 tagDefns[type.nativeName] = makeExpression(type);
638 } 636 }
639 637
640 // Write out a thunk that builds the metadata. 638 // Write out a thunk that builds the metadata.
641 639
642 if (!tagDefns.isEmpty()) { 640 if (!tagDefns.isEmpty()) {
643 writer.enterBlock('(function(){'); 641 writer.enterBlock('(function(){');
644 642
645 for (final varName in varNames) { 643 for (final varName in varNames) {
646 writer.writeln('var ${varName} = ${varDefns[varName]};'); 644 writer.writeln('var ${varName} = ${varDefns[varName]};');
647 } 645 }
648 646
649 writer.enterBlock('var table = ['); 647 writer.enterBlock('var table = [');
650 writer.comment( 648 writer.comment(
651 '// [dynamic-dispatch-tag, ' 649 '// [dynamic-dispatch-tag, '
652 + 'tags of classes implementing dynamic-dispatch-tag]'); 650 + 'tags of classes implementing dynamic-dispatch-tag]');
653 for (final type in dispatchTypes) { 651 for (final type in dispatchTypes) {
654 writer.writeln("['${typeTag(type)}', ${tagDefns[typeTag(type)]}],"); 652 writer.writeln("['${type.nativeName}', ${tagDefns[type.nativeName]}],");
655 } 653 }
656 writer.exitBlock('];'); 654 writer.exitBlock('];');
657 writer.writeln('\$dynamicSetMetadata(table);'); 655 writer.writeln('\$dynamicSetMetadata(table);');
658 656
659 writer.exitBlock('})();'); 657 writer.exitBlock('})();');
660 } 658 }
661 } 659 }
662 660
663 /** Order a list of values in a Map by SourceSpan, then by name. */ 661 /** Order a list of values in a Map by SourceSpan, then by name. */
664 List _orderValues(Map map) { 662 List _orderValues(Map map) {
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 meth.resolve(); 1342 meth.resolve();
1345 return meth; 1343 return meth;
1346 } 1344 }
1347 1345
1348 visitBool(Expression node) { 1346 visitBool(Expression node) {
1349 // Boolean conversions in if/while/do/for/conditions require non-null bool. 1347 // Boolean conversions in if/while/do/for/conditions require non-null bool.
1350 1348
1351 // TODO(jmesserly): why do we have this rule? It seems inconsistent with 1349 // TODO(jmesserly): why do we have this rule? It seems inconsistent with
1352 // the rest of the type system, and just causes bogus asserts unless all 1350 // the rest of the type system, and just causes bogus asserts unless all
1353 // bools are initialized to false. 1351 // bools are initialized to false.
1354 return visitValue(node).convertTo(this, world.nonNullBool, node); 1352 return visitValue(node).convertTo(this, world.nonNullBool);
1355 } 1353 }
1356 1354
1357 visitValue(Expression node) { 1355 visitValue(Expression node) {
1358 if (node == null) return null; 1356 if (node == null) return null;
1359 1357
1360 var value = node.visit(this); 1358 var value = node.visit(this);
1361 value.checkFirstClass(node.span); 1359 value.checkFirstClass(node.span);
1362 return value; 1360 return value;
1363 } 1361 }
1364 1362
1365 /** 1363 /**
1366 * Visit [node] and ensure statically or with an runtime check that it has the 1364 * Visit [node] and ensure statically or with an runtime check that it has the
1367 * expected type (if specified). 1365 * expected type (if specified).
1368 */ 1366 */
1369 visitTypedValue(Expression node, Type expectedType) { 1367 visitTypedValue(Expression node, Type expectedType) {
1370 final val = visitValue(node); 1368 final val = visitValue(node);
1371 return expectedType == null ? val : val.convertTo(this, expectedType, node); 1369 return expectedType == null ? val : val.convertTo(this, expectedType);
1372 } 1370 }
1373 1371
1374 visitVoid(Expression node) { 1372 visitVoid(Expression node) {
1375 // TODO(jmesserly): should we generalize this? 1373 // TODO(jmesserly): should we generalize this?
1376 if (node is PostfixExpression) { 1374 if (node is PostfixExpression) {
1377 var value = visitPostfixExpression(node, isVoid: true); 1375 var value = visitPostfixExpression(node, isVoid: true);
1378 value.checkFirstClass(node.span); 1376 value.checkFirstClass(node.span);
1379 return value; 1377 return value;
1380 } else if (node is BinaryExpression) { 1378 } else if (node is BinaryExpression) {
1381 var value = visitBinaryExpression(node, isVoid: true); 1379 var value = visitBinaryExpression(node, isVoid: true);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 1420
1423 if (value == null) { 1421 if (value == null) {
1424 if (_scope.reentrant) { 1422 if (_scope.reentrant) {
1425 // To preserve block scoping, we need to ensure the variable is 1423 // To preserve block scoping, we need to ensure the variable is
1426 // reinitialized each time the block is entered. 1424 // reinitialized each time the block is entered.
1427 writer.write('${val.code} = null'); 1425 writer.write('${val.code} = null');
1428 } else { 1426 } else {
1429 writer.write('${val.code}'); 1427 writer.write('${val.code}');
1430 } 1428 }
1431 } else { 1429 } else {
1432 value = value.convertTo(this, type, node.values[i]); 1430 value = value.convertTo(this, type);
1433 writer.write('${val.code} = ${value.code}'); 1431 writer.write('${val.code} = ${value.code}');
1434 } 1432 }
1435 } 1433 }
1436 writer.writeln(';'); 1434 writer.writeln(';');
1437 return false; 1435 return false;
1438 1436
1439 } 1437 }
1440 1438
1441 bool visitFunctionDefinition(FunctionDefinition node) { 1439 bool visitFunctionDefinition(FunctionDefinition node) {
1442 var meth = _makeLambdaMethod(node.name.name, node); 1440 var meth = _makeLambdaMethod(node.name.name, node);
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
2126 2124
2127 // Otherwise treat it as a field. 2125 // Otherwise treat it as a field.
2128 // This makes for nicer code in the $op= case 2126 // This makes for nicer code in the $op= case
2129 } 2127 }
2130 2128
2131 if (x.isFinal) { 2129 if (x.isFinal) {
2132 world.error('final variable "${x.code}" is not assignable', 2130 world.error('final variable "${x.code}" is not assignable',
2133 position.span); 2131 position.span);
2134 } 2132 }
2135 2133
2136 y = y.convertTo(this, x.type, yn); 2134 y = y.convertTo(this, x.type);
2137 2135
2138 if (kind == 0) { 2136 if (kind == 0) {
2139 x = captureOriginal(x); 2137 x = captureOriginal(x);
2140 return new Value(y.type, '${x.code} = ${y.code}', position.span); 2138 return new Value(y.type, '${x.code} = ${y.code}', position.span);
2141 } else if (x.type.isNum && y.type.isNum && (kind != TokenKind.TRUNCDIV)) { 2139 } else if (x.type.isNum && y.type.isNum && (kind != TokenKind.TRUNCDIV)) {
2142 // Process everything but ~/ , which has no equivalent JS operator 2140 // Process everything but ~/ , which has no equivalent JS operator
2143 x = captureOriginal(x); 2141 x = captureOriginal(x);
2144 // Very localized optimization for numbers! 2142 // Very localized optimization for numbers!
2145 final op = TokenKind.kindToString(kind); 2143 final op = TokenKind.kindToString(kind);
2146 return new Value(y.type, '${x.code} $op= ${y.code}', position.span); 2144 return new Value(y.type, '${x.code} $op= ${y.code}', position.span);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2230 var assignValue = _visitAssign(kind, node.self, operand, node, null); 2228 var assignValue = _visitAssign(kind, node.self, operand, node, null);
2231 return new Value(assignValue.type, '(${assignValue.code})', 2229 return new Value(assignValue.type, '(${assignValue.code})',
2232 node.span); 2230 node.span);
2233 } 2231 }
2234 case TokenKind.NOT: 2232 case TokenKind.NOT:
2235 // TODO(jimhug): Issue #359 seeks to clarify this behavior. 2233 // TODO(jimhug): Issue #359 seeks to clarify this behavior.
2236 if (value.type.isBool && value.isConst) { 2234 if (value.type.isBool && value.isConst) {
2237 var newVal = !value.actualValue; 2235 var newVal = !value.actualValue;
2238 return new EvaluatedValue(value.type, newVal, '${newVal}', node.span); 2236 return new EvaluatedValue(value.type, newVal, '${newVal}', node.span);
2239 } else { 2237 } else {
2240 var newVal = value.convertTo(this, world.nonNullBool, node); 2238 var newVal = value.convertTo(this, world.nonNullBool);
2241 return new Value(newVal.type, '!${newVal.code}', node.span); 2239 return new Value(newVal.type, '!${newVal.code}', node.span);
2242 } 2240 }
2243 2241
2244 case TokenKind.ADD: 2242 case TokenKind.ADD:
2245 // TODO(jimhug): Issue #359 seeks to clarify this behavior. 2243 // TODO(jimhug): Issue #359 seeks to clarify this behavior.
2246 return value.convertTo(this, world.numType, node); 2244 return value.convertTo(this, world.numType);
2247 2245
2248 case TokenKind.SUB: 2246 case TokenKind.SUB:
2249 case TokenKind.BIT_NOT: 2247 case TokenKind.BIT_NOT:
2250 if (node.op.kind == TokenKind.BIT_NOT) { 2248 if (node.op.kind == TokenKind.BIT_NOT) {
2251 return value.invoke(this, ':bit_not', node, Arguments.EMPTY); 2249 return value.invoke(this, ':bit_not', node, Arguments.EMPTY);
2252 } else if (node.op.kind == TokenKind.SUB) { 2250 } else if (node.op.kind == TokenKind.SUB) {
2253 return value.invoke(this, ':negate', node, Arguments.EMPTY); 2251 return value.invoke(this, ':negate', node, Arguments.EMPTY);
2254 } else { 2252 } else {
2255 world.internalError('unimplemented: unary ${node.op}', 2253 world.internalError('unimplemented: unary ${node.op}',
2256 node.span); 2254 node.span);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2357 world.error('can\'t use const on a non-const constructor', node.span); 2355 world.error('can\'t use const on a non-const constructor', node.span);
2358 } 2356 }
2359 for (var arg in node.arguments) { 2357 for (var arg in node.arguments) {
2360 if (!visitValue(arg.value).isConst) { 2358 if (!visitValue(arg.value).isConst) {
2361 world.error('const constructor expects const arguments', arg.span); 2359 world.error('const constructor expects const arguments', arg.span);
2362 } 2360 }
2363 } 2361 }
2364 } 2362 }
2365 2363
2366 // Call the constructor on the type we want to construct. 2364 // Call the constructor on the type we want to construct.
2367 // NOTE: this is important for correct checking of factories. 2365 // NOTE: this is important for correct type checking of factories.
2368 // If the user calls "new Interface()" we want the result type to be the 2366 // If the user calls "new Interface()" we want the result type to be the
2369 // interface, not the class. 2367 // interface, not the class.
2370 var target = new Value.type(type, typeRef.span); 2368 var target = new Value.type(type, typeRef.span);
2371 return m.invoke(this, node, target, _makeArgs(node.arguments)); 2369 return m.invoke(this, node, target, _makeArgs(node.arguments));
2372 } 2370 }
2373 2371
2374 visitListExpression(ListExpression node) { 2372 visitListExpression(ListExpression node) {
2375 // TODO(jimhug): Use node.type or other type inference here. 2373 // TODO(jimhug): Use node.type or other type inference here.
2376 var argsCode = []; 2374 var argsCode = [];
2377 var argValues = []; 2375 var argValues = [];
(...skipping 13 matching lines...) Expand all
2391 world.error('const list can only contain const values', item.span); 2389 world.error('const list can only contain const values', item.span);
2392 argsCode.add(arg.code); 2390 argsCode.add(arg.code);
2393 } else { 2391 } else {
2394 argsCode.add(arg.canonicalCode); 2392 argsCode.add(arg.canonicalCode);
2395 } 2393 }
2396 } else { 2394 } else {
2397 argsCode.add(arg.code); 2395 argsCode.add(arg.code);
2398 } 2396 }
2399 } 2397 }
2400 2398
2401 world.coreimpl.types['ListFactory'].markUsed(); 2399 world.listFactoryType.markUsed();
2402 2400
2403 final code = '[${Strings.join(argsCode, ", ")}]'; 2401 final code = '[${Strings.join(argsCode, ", ")}]';
2404 var value = new Value(world.listType, code, node.span); 2402 var value = new Value(world.listType, code, node.span);
2405 if (node.isConst) { 2403 if (node.isConst) {
2406 final immutableList = world.coreimpl.types['ImmutableList']; 2404 final immutableList = world.immutableListType;
2407 final immutableListCtor = immutableList.getConstructor('from'); 2405 final immutableListCtor = immutableList.getConstructor('from');
2408 final result = immutableListCtor.invoke(this, node, 2406 final result = immutableListCtor.invoke(this, node,
2409 new Value.type(value.type, node.span), new Arguments(null, [value])); 2407 new Value.type(value.type, node.span), new Arguments(null, [value]));
2410 value = world.gen.globalForConst( 2408 value = world.gen.globalForConst(
2411 new ConstListValue(immutableList, argValues, 'const $code', 2409 new ConstListValue(immutableList, argValues, 'const $code',
2412 result.code, node.span), 2410 result.code, node.span),
2413 argValues); 2411 argValues);
2414 } 2412 }
2415 return value; 2413 return value;
2416 } 2414 }
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 } 2566 }
2569 // No need to concat empty strings except the first. 2567 // No need to concat empty strings except the first.
2570 if (items.length == 0 || (code != "''" && code != '""')) { 2568 if (items.length == 0 || (code != "''" && code != '""')) {
2571 items.add(code); 2569 items.add(code);
2572 } 2570 }
2573 } 2571 }
2574 return new Value(type, '(${Strings.join(items, " + ")})', node.span); 2572 return new Value(type, '(${Strings.join(items, " + ")})', node.span);
2575 } 2573 }
2576 2574
2577 if (node.value is num) { 2575 if (node.value is num) {
2578 world.coreimpl.types['NumImplementation'].markUsed(); 2576 world.numImplType.markUsed();
2579 } 2577 }
2580 2578
2581 var text = node.text; 2579 var text = node.text;
2582 // TODO(jimhug): Confirm that only strings need possible translation 2580 // TODO(jimhug): Confirm that only strings need possible translation
2583 if (type.isString) { 2581 if (type.isString) {
2584 world.coreimpl.types['StringImplementation'].markUsed(); 2582 world.stringImplType.markUsed();
2585 2583
2586 if (text.startsWith('@')) { 2584 if (text.startsWith('@')) {
2587 text = _escapeString(parseStringLiteral(text)); 2585 text = _escapeString(parseStringLiteral(text));
2588 text = '"$text"'; 2586 text = '"$text"';
2589 } else if (isMultilineString(text)) { 2587 } else if (isMultilineString(text)) {
2590 // convert multi-line strings into single-line 2588 // convert multi-line strings into single-line
2591 text = parseStringLiteral(text); 2589 text = parseStringLiteral(text);
2592 // TODO(jimhug): What about \r? 2590 // TODO(jimhug): What about \r?
2593 text = text.replaceAll('\n', '\\n'); 2591 text = text.replaceAll('\n', '\\n');
2594 text = toDoubleQuote(text); 2592 text = toDoubleQuote(text);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2718 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); 2716 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false));
2719 } 2717 }
2720 for (int i = bareCount; i < length; i++) { 2718 for (int i = bareCount; i < length; i++) {
2721 var name = getName(i); 2719 var name = getName(i);
2722 if (name == null) name = '\$$i'; 2720 if (name == null) name = '\$$i';
2723 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); 2721 result.add(new Value(world.varType, name, null, /*needsTemp:*/false));
2724 } 2722 }
2725 return new Arguments(nodes, result); 2723 return new Arguments(nodes, result);
2726 } 2724 }
2727 } 2725 }
OLDNEW
« no previous file with comments | « frog/element.dart ('k') | frog/library.dart » ('j') | frog/member.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698