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

Side by Side Diff: frog/gen.dart

Issue 8763001: Fix names with '$' to not conflict with operators or internal helpers (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merged again Created 9 years 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 | « frog/frogsh ('k') | frog/lib/natives.dart » ('j') | no next file with comments »
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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 if (y.span == null) return -1; 487 if (y.span == null) return -1;
488 488
489 // If that fails, compare by name. 489 // If that fails, compare by name.
490 return x.name.compareTo(y.name); 490 return x.name.compareTo(y.name);
491 } 491 }
492 492
493 /** Marks that a map literal is used, e.g. a call to $map. */ 493 /** Marks that a map literal is used, e.g. a call to $map. */
494 Type useMapFactory() { 494 Type useMapFactory() {
495 corejs.useMap = true; 495 corejs.useMap = true;
496 var factType = world.coreimpl.types['HashMapImplementation']; 496 var factType = world.coreimpl.types['HashMapImplementation'];
497 var m = factType.resolveMember('\$setindex'); 497 var m = factType.resolveMember(':setindex');
498 genMethod(m.members[0]); // TODO(jimhug): Clean up initializing. 498 genMethod(m.members[0]); // TODO(jimhug): Clean up initializing.
499 var c = factType.getConstructor(''); 499 var c = factType.getConstructor('');
500 genMethod(c); 500 genMethod(c);
501 return factType; 501 return factType;
502 } 502 }
503 } 503 }
504 504
505 505
506 class BlockScope { 506 class BlockScope {
507 MethodGenerator enclosingMethod; 507 MethodGenerator enclosingMethod;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 if (isMethodScope && _closedOver.contains(name)) return true; 585 if (isMethodScope && _closedOver.contains(name)) return true;
586 586
587 for (var s = parent; s != null; s = s.parent) { 587 for (var s = parent; s != null; s = s.parent) {
588 if (s._vars.containsKey(name)) return true; 588 if (s._vars.containsKey(name)) return true;
589 if (s._jsNames.contains(name)) return true; 589 if (s._jsNames.contains(name)) return true;
590 // Don't reuse a name that's been closed over 590 // Don't reuse a name that's been closed over
591 if (s.isMethodScope && s._closedOver.contains(name)) return true; 591 if (s.isMethodScope && s._closedOver.contains(name)) return true;
592 } 592 }
593 593
594 // Ensure that we don't shadow another name that would've been accessible, 594 // Ensure that we don't shadow another name that would've been accessible,
595 // like to level names. 595 // like top level names.
596 // (This lookup might report errors, which is a bit strange. 596 // (This lookup might report errors, which is a bit strange.
597 // But probably harmless since we have to pay for the lookup anyway.) 597 // But probably harmless since we have to pay for the lookup anyway.)
598 // TODO(jmesserly): does this work right if JS name of the top-level thing
599 // is different from Dart name?
598 final type = enclosingMethod.method.declaringType; 600 final type = enclosingMethod.method.declaringType;
599 if (type.library.lookup(name, null) != null) return true; 601 if (type.library.lookup(name, null) != null) return true;
600 602
601 // Nobody else needs this name. It's safe to reuse. 603 // Nobody else needs this name. It's safe to reuse.
602 return false; 604 return false;
603 } 605 }
604 606
605 607
606 Value create(String name, Type type, SourceSpan span, 608 Value create(String name, Type type, SourceSpan span,
607 [bool isFinal = false, bool isParameter = false]) { 609 [bool isFinal = false, bool isParameter = false]) {
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 if (list.needsTemp) { 1407 if (list.needsTemp) {
1406 listVar = _scope.create('\$list', list.type, null); 1408 listVar = _scope.create('\$list', list.type, null);
1407 writer.writeln('var ${listVar.code} = ${list.code};'); 1409 writer.writeln('var ${listVar.code} = ${list.code};');
1408 } 1410 }
1409 1411
1410 // Special path for list for readability and perf optimization. 1412 // Special path for list for readability and perf optimization.
1411 if (list.type.isList) { 1413 if (list.type.isList) {
1412 var tmpi = _scope.create('\$i', world.numType, null); 1414 var tmpi = _scope.create('\$i', world.numType, null);
1413 writer.enterBlock('for (var ${tmpi.code} = 0;' + 1415 writer.enterBlock('for (var ${tmpi.code} = 0;' +
1414 '${tmpi.code} < ${listVar.code}.length; ${tmpi.code}++) {'); 1416 '${tmpi.code} < ${listVar.code}.length; ${tmpi.code}++) {');
1415 var value = listVar.invoke(this, '\$index', node.list, 1417 var value = listVar.invoke(this, ':index', node.list,
1416 new Arguments(null, [tmpi])); 1418 new Arguments(null, [tmpi]));
1417 writer.writeln('var ${item.code} = ${value.code};'); 1419 writer.writeln('var ${item.code} = ${value.code};');
1418 } else { 1420 } else {
1419 _pushBlock(); 1421 _pushBlock();
1420 var iterator = list.invoke(this, 'iterator', node.list, Arguments.EMPTY); 1422 var iterator = list.invoke(this, 'iterator', node.list, Arguments.EMPTY);
1421 var tmpi = _scope.create('\$i', iterator.type, null); 1423 var tmpi = _scope.create('\$i', iterator.type, null);
1422 1424
1423 var hasNext = tmpi.invoke(this, 'hasNext', node.list, Arguments.EMPTY); 1425 var hasNext = tmpi.invoke(this, 'hasNext', node.list, Arguments.EMPTY);
1424 var next = tmpi.invoke(this, 'next', node.list, Arguments.EMPTY); 1426 var next = tmpi.invoke(this, 'next', node.list, Arguments.EMPTY);
1425 1427
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 1703
1702 var w = new CodeWriter(); 1704 var w = new CodeWriter();
1703 meth.generator.writeDefinition(w, node); 1705 meth.generator.writeDefinition(w, node);
1704 1706
1705 return new Value(meth.functionType, w.text, node.span); 1707 return new Value(meth.functionType, w.text, node.span);
1706 } 1708 }
1707 1709
1708 visitCallExpression(CallExpression node) { 1710 visitCallExpression(CallExpression node) {
1709 var target; 1711 var target;
1710 var position = node.target; 1712 var position = node.target;
1711 var name = '\$call'; 1713 var name = ':call';
1712 if (node.target is DotExpression) { 1714 if (node.target is DotExpression) {
1713 DotExpression dot = node.target; 1715 DotExpression dot = node.target;
1714 target = dot.self.visit(this); 1716 target = dot.self.visit(this);
1715 name = dot.name.name; 1717 name = dot.name.name;
1716 position = dot.name; 1718 position = dot.name;
1717 } else if (node.target is VarExpression) { 1719 } else if (node.target is VarExpression) {
1718 VarExpression varExpr = node.target; 1720 VarExpression varExpr = node.target;
1719 name = varExpr.name.name; 1721 name = varExpr.name.name;
1720 // First check in block scopes. 1722 // First check in block scopes.
1721 target = _scope.lookup(name); 1723 target = _scope.lookup(name);
1722 if (target != null) { 1724 if (target != null) {
1723 return target.invoke(this, '\$call', node, _makeArgs(node.arguments)); 1725 return target.invoke(this, ':call', node, _makeArgs(node.arguments));
1724 } 1726 }
1725 1727
1726 target = _makeThisOrType(varExpr.span); 1728 target = _makeThisOrType(varExpr.span);
1727 return target.invoke(this, name, node, _makeArgs(node.arguments)); 1729 return target.invoke(this, name, node, _makeArgs(node.arguments));
1728 } else { 1730 } else {
1729 target = node.target.visit(this); 1731 target = node.target.visit(this);
1730 } 1732 }
1731 1733
1732 return target.invoke(this, name, position, _makeArgs(node.arguments)); 1734 return target.invoke(this, name, position, _makeArgs(node.arguments));
1733 } 1735 }
1734 1736
1735 visitIndexExpression(IndexExpression node) { 1737 visitIndexExpression(IndexExpression node) {
1736 var target = visitValue(node.target); 1738 var target = visitValue(node.target);
1737 var index = visitValue(node.index); 1739 var index = visitValue(node.index);
1738 return target.invoke(this, '\$index', node, new Arguments(null, [index])); 1740 return target.invoke(this, ':index', node, new Arguments(null, [index]));
1739 } 1741 }
1740 1742
1741 visitBinaryExpression(BinaryExpression node) { 1743 visitBinaryExpression(BinaryExpression node) {
1742 final kind = node.op.kind; 1744 final kind = node.op.kind;
1743 // TODO(jimhug): Ensure these have same semantics as JS! 1745 // TODO(jimhug): Ensure these have same semantics as JS!
1744 if (kind == TokenKind.AND || kind == TokenKind.OR) { 1746 if (kind == TokenKind.AND || kind == TokenKind.OR) {
1745 var x = visitTypedValue(node.x, world.nonNullBool); 1747 var x = visitTypedValue(node.x, world.nonNullBool);
1746 var y = visitTypedValue(node.y, world.nonNullBool); 1748 var y = visitTypedValue(node.y, world.nonNullBool);
1747 final code = '${x.code} ${node.op} ${y.code}'; 1749 final code = '${x.code} ${node.op} ${y.code}';
1748 if (x.isConst && y.isConst) { 1750 if (x.isConst && y.isConst) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 node.span); 1792 node.span);
1791 } 1793 }
1792 } 1794 }
1793 1795
1794 final assignKind = TokenKind.kindFromAssign(node.op.kind); 1796 final assignKind = TokenKind.kindFromAssign(node.op.kind);
1795 if (assignKind == -1) { 1797 if (assignKind == -1) {
1796 final x = visitValue(node.x); 1798 final x = visitValue(node.x);
1797 final y = visitValue(node.y); 1799 final y = visitValue(node.y);
1798 var name = TokenKind.binaryMethodName(node.op.kind); 1800 var name = TokenKind.binaryMethodName(node.op.kind);
1799 if (node.op.kind == TokenKind.NE) { 1801 if (node.op.kind == TokenKind.NE) {
1800 name = '\$ne'; 1802 name = ':ne';
1801 } 1803 }
1802 if (name == null) { 1804 if (name == null) {
1803 world.internalError('unimplemented binary op ${node.op}', node.span); 1805 world.internalError('unimplemented binary op ${node.op}', node.span);
1804 return; 1806 return;
1805 } 1807 }
1806 return x.invoke(this, name, node, new Arguments(null, [y])); 1808 return x.invoke(this, name, node, new Arguments(null, [y]));
1807 } else { 1809 } else {
1808 return _visitAssign(assignKind, node.x, node.y, node, null); 1810 return _visitAssign(assignKind, node.x, node.y, node, null);
1809 } 1811 }
1810 } 1812 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1918 var target = visitValue(xn.target); 1920 var target = visitValue(xn.target);
1919 var index = visitValue(xn.index); 1921 var index = visitValue(xn.index);
1920 var y = visitValue(yn); 1922 var y = visitValue(yn);
1921 1923
1922 var tmptarget = target; 1924 var tmptarget = target;
1923 var tmpindex = index; 1925 var tmpindex = index;
1924 if (kind != 0) { 1926 if (kind != 0) {
1925 tmptarget = getTemp(target); 1927 tmptarget = getTemp(target);
1926 tmpindex = getTemp(index); 1928 tmpindex = getTemp(index);
1927 index = assignTemp(tmpindex, index); 1929 index = assignTemp(tmpindex, index);
1928 var right = tmptarget.invoke(this, '\$index', 1930 var right = tmptarget.invoke(this, ':index',
1929 position, new Arguments(null, [tmpindex])); 1931 position, new Arguments(null, [tmpindex]));
1930 right = captureOriginal(right); 1932 right = captureOriginal(right);
1931 y = right.invoke(this, TokenKind.binaryMethodName(kind), 1933 y = right.invoke(this, TokenKind.binaryMethodName(kind),
1932 position, new Arguments(null, [y])); 1934 position, new Arguments(null, [y]));
1933 } 1935 }
1934 var ret = assignTemp(tmptarget, target).invoke(this, '\$setindex', 1936 var ret = assignTemp(tmptarget, target).invoke(this, ':setindex',
1935 position, new Arguments(null, [index, y])); 1937 position, new Arguments(null, [index, y]));
1936 if (tmptarget != target) freeTemp(tmptarget); 1938 if (tmptarget != target) freeTemp(tmptarget);
1937 if (tmpindex != index) freeTemp(tmpindex); 1939 if (tmpindex != index) freeTemp(tmpindex);
1938 return ret; 1940 return ret;
1939 } 1941 }
1940 1942
1941 _visitDotAssign(int kind, DotExpression xn, Expression yn, Node position, 1943 _visitDotAssign(int kind, DotExpression xn, Expression yn, Node position,
1942 Value captureOriginal(Value right)) { 1944 Value captureOriginal(Value right)) {
1943 1945
1944 // This is not visitValue because types are assignable through . 1946 // This is not visitValue because types are assignable through .
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1987 return new Value(newVal.type, '!${newVal.code}', node.span); 1989 return new Value(newVal.type, '!${newVal.code}', node.span);
1988 } 1990 }
1989 1991
1990 case TokenKind.ADD: 1992 case TokenKind.ADD:
1991 // TODO(jimhug): Issue #359 seeks to clarify this behavior. 1993 // TODO(jimhug): Issue #359 seeks to clarify this behavior.
1992 return value.convertTo(this, world.numType, node); 1994 return value.convertTo(this, world.numType, node);
1993 1995
1994 case TokenKind.SUB: 1996 case TokenKind.SUB:
1995 case TokenKind.BIT_NOT: 1997 case TokenKind.BIT_NOT:
1996 if (node.op.kind == TokenKind.BIT_NOT) { 1998 if (node.op.kind == TokenKind.BIT_NOT) {
1997 return value.invoke(this, '\$bit_not', node, Arguments.EMPTY); 1999 return value.invoke(this, ':bit_not', node, Arguments.EMPTY);
1998 } else if (node.op.kind == TokenKind.SUB) { 2000 } else if (node.op.kind == TokenKind.SUB) {
1999 return value.invoke(this, '\$negate', node, Arguments.EMPTY); 2001 return value.invoke(this, ':negate', node, Arguments.EMPTY);
2000 } else { 2002 } else {
2001 world.internalError('unimplemented: unary ${node.op}', 2003 world.internalError('unimplemented: unary ${node.op}',
2002 node.span); 2004 node.span);
2003 } 2005 }
2004 default: 2006 default:
2005 world.internalError('unimplemented: ${node.op}', node.span); 2007 world.internalError('unimplemented: ${node.op}', node.span);
2006 } 2008 }
2007 } 2009 }
2008 2010
2009 visitAwaitExpression(AwaitExpression node) { 2011 visitAwaitExpression(AwaitExpression node) {
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
2429 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); 2431 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false));
2430 } 2432 }
2431 for (int i = bareCount; i < length; i++) { 2433 for (int i = bareCount; i < length; i++) {
2432 var name = getName(i); 2434 var name = getName(i);
2433 if (name == null) name = '\$$i'; 2435 if (name == null) name = '\$$i';
2434 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); 2436 result.add(new Value(world.varType, name, null, /*needsTemp:*/false));
2435 } 2437 }
2436 return new Arguments(nodes, result); 2438 return new Arguments(nodes, result);
2437 } 2439 }
2438 } 2440 }
OLDNEW
« no previous file with comments | « frog/frogsh ('k') | frog/lib/natives.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698