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

Side by Side Diff: frog/gen.dart

Issue 8799018: Fixed lambdas that have the same name as one of their parameters/locals (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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 | « no previous file | frog/minfrog » ('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 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 Set<String> captures; 674 Set<String> captures;
675 675
676 MethodGenerator(this.method, this.enclosingMethod) 676 MethodGenerator(this.method, this.enclosingMethod)
677 : writer = new CodeWriter(), needsThis = false { 677 : writer = new CodeWriter(), needsThis = false {
678 if (enclosingMethod != null) { 678 if (enclosingMethod != null) {
679 _scope = new BlockScope(this, enclosingMethod._scope); 679 _scope = new BlockScope(this, enclosingMethod._scope);
680 captures = new Set(); 680 captures = new Set();
681 } else { 681 } else {
682 _scope = new BlockScope(this, null); 682 _scope = new BlockScope(this, null);
683 } 683 }
684 // For named lambdas, add the name to this scope so we can call it
685 // recursively.
686 if (enclosingMethod != null && method.name != '') {
687 MethodMember m = method; // lambdas must be MethodMembers
688 _scope.create(m.name, m.functionType, m.definition.span, isFinal:true);
689 }
690 _usedTemps = new Set(); 684 _usedTemps = new Set();
691 _freeTemps = []; 685 _freeTemps = [];
692 } 686 }
693 687
694 Library get library() => method.library; 688 Library get library() => method.library;
695 689
696 // TODO(jimhug): Where does this really belong? 690 // TODO(jimhug): Where does this really belong?
697 MemberSet findMembers(String name) { 691 MemberSet findMembers(String name) {
698 return library._findMembers(name); 692 return library._findMembers(name);
699 } 693 }
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 1134
1141 _popBlock() { 1135 _popBlock() {
1142 _scope = _scope.parent; 1136 _scope = _scope.parent;
1143 } 1137 }
1144 1138
1145 MethodMember _makeLambdaMethod(String name, FunctionDefinition func) { 1139 MethodMember _makeLambdaMethod(String name, FunctionDefinition func) {
1146 var meth = new MethodMember(name, method.declaringType, func); 1140 var meth = new MethodMember(name, method.declaringType, func);
1147 meth.isLambda = true; 1141 meth.isLambda = true;
1148 meth.enclosingElement = method; 1142 meth.enclosingElement = method;
1149 meth.resolve(); 1143 meth.resolve();
1150 world.gen.genMethod(meth, this);
1151 return meth; 1144 return meth;
1152 } 1145 }
1153 1146
1154 visitBool(Expression node) { 1147 visitBool(Expression node) {
1155 // Boolean conversions in if/while/do/for/conditions require non-null bool. 1148 // Boolean conversions in if/while/do/for/conditions require non-null bool.
1156 1149
1157 // TODO(jmesserly): why do we have this rule? It seems inconsistent with 1150 // TODO(jmesserly): why do we have this rule? It seems inconsistent with
1158 // the rest of the type system, and just causes bogus asserts unless all 1151 // the rest of the type system, and just causes bogus asserts unless all
1159 // bools are initialized to false. 1152 // bools are initialized to false.
1160 return visitValue(node).convertTo(this, world.nonNullBool, node); 1153 return visitValue(node).convertTo(this, world.nonNullBool, node);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1229 value = value.convertTo(this, type, node.values[i]); 1222 value = value.convertTo(this, type, node.values[i]);
1230 writer.write('${val.code} = ${value.code}'); 1223 writer.write('${val.code} = ${value.code}');
1231 } 1224 }
1232 } 1225 }
1233 writer.writeln(';'); 1226 writer.writeln(';');
1234 return false; 1227 return false;
1235 1228
1236 } 1229 }
1237 1230
1238 bool visitFunctionDefinition(FunctionDefinition node) { 1231 bool visitFunctionDefinition(FunctionDefinition node) {
1239 var name = world.toJsIdentifier(node.name.name); 1232 var meth = _makeLambdaMethod(node.name.name, node);
Jennifer Messerly 2011/12/05 23:05:11 MethodMember "jsname" handles this now.
1233 var funcValue = _scope.create(meth.name, meth.functionType,
1234 method.definition.span, isFinal:true);
1240 1235
1241 var meth = _makeLambdaMethod(name, node); 1236 world.gen.genMethod(meth, this);
1242
1243 // TODO(jimhug): Pass js name into writeDefinition?
1244 var funcValue = _scope.create(name, meth.functionType,
1245 method.definition.span, isFinal:true);
1246 meth.generator.writeDefinition(writer, null); 1237 meth.generator.writeDefinition(writer, null);
1247 return false; 1238 return false;
1248 } 1239 }
1249 1240
1250 /** 1241 /**
1251 * Returns true indicating that normal control-flow is interrupted by 1242 * Returns true indicating that normal control-flow is interrupted by
1252 * this statement. (This could be a return, break, throw, or continue.) 1243 * this statement. (This could be a return, break, throw, or continue.)
1253 */ 1244 */
1254 bool visitReturnStatement(ReturnStatement node) { 1245 bool visitReturnStatement(ReturnStatement node) {
1255 if (node.value == null) { 1246 if (node.value == null) {
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 node != null ? node.span : null, /*needsTemp:*/false); 1687 node != null ? node.span : null, /*needsTemp:*/false);
1697 } else { 1688 } else {
1698 _checkNonStatic(node); 1689 _checkNonStatic(node);
1699 return new Value(method.declaringType, 'this', node != null ? node.span : null, 1690 return new Value(method.declaringType, 'this', node != null ? node.span : null,
1700 /*needsTemp:*/false); 1691 /*needsTemp:*/false);
1701 } 1692 }
1702 } 1693 }
1703 1694
1704 // ******************* Expressions ******************* 1695 // ******************* Expressions *******************
1705 visitLambdaExpression(LambdaExpression node) { 1696 visitLambdaExpression(LambdaExpression node) {
1706 var name = ''; 1697 var name = (node.func.name != null) ? node.func.name.name : '';
1707 if (node.func.name != null) { 1698
1708 name = world.toJsIdentifier(node.func.name.name); 1699 MethodMember meth = _makeLambdaMethod(name, node.func);
1700 final lambdaGen = new MethodGenerator(meth, this);
1701 if (name != '') {
1702 // Note: we don't want to put this in our enclosing scope because the
1703 // name shouldn't be visible except inside the lambda. We also don't want
1704 // to put the name directly in the lambda's scope because parameters are
1705 // allowed to shadow it. So we create an extra scope for it to go into.
1706 lambdaGen._scope.create(name, meth.functionType, meth.definition.span,
1707 isFinal:true);
1708 lambdaGen._pushBlock();
Jennifer Messerly 2011/12/05 23:05:11 no need to pop the scope, for the same reason we d
1709 } 1709 }
1710 1710 lambdaGen.run();
1711 var meth = _makeLambdaMethod(name, node.func);
1712 1711
1713 var w = new CodeWriter(); 1712 var w = new CodeWriter();
1714 meth.generator.writeDefinition(w, node); 1713 meth.generator.writeDefinition(w, node);
1715
1716 return new Value(meth.functionType, w.text, node.span); 1714 return new Value(meth.functionType, w.text, node.span);
1717 } 1715 }
1718 1716
1719 visitCallExpression(CallExpression node) { 1717 visitCallExpression(CallExpression node) {
1720 var target; 1718 var target;
1721 var position = node.target; 1719 var position = node.target;
1722 var name = ':call'; 1720 var name = ':call';
1723 if (node.target is DotExpression) { 1721 if (node.target is DotExpression) {
1724 DotExpression dot = node.target; 1722 DotExpression dot = node.target;
1725 target = dot.self.visit(this); 1723 target = dot.self.visit(this);
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
2449 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); 2447 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false));
2450 } 2448 }
2451 for (int i = bareCount; i < length; i++) { 2449 for (int i = bareCount; i < length; i++) {
2452 var name = getName(i); 2450 var name = getName(i);
2453 if (name == null) name = '\$$i'; 2451 if (name == null) name = '\$$i';
2454 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); 2452 result.add(new Value(world.varType, name, null, /*needsTemp:*/false));
2455 } 2453 }
2456 return new Arguments(nodes, result); 2454 return new Arguments(nodes, result);
2457 } 2455 }
2458 } 2456 }
OLDNEW
« no previous file with comments | « no previous file | frog/minfrog » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698