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

Side by Side Diff: lib/src/codegen/js_codegen.dart

Issue 1034273003: fix for static methods and names banned in strict mode (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 8 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
« no previous file with comments | « lib/runtime/dart_runtime.js ('k') | lib/src/codegen/js_names.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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 library dev_compiler.src.codegen.js_codegen; 5 library dev_compiler.src.codegen.js_codegen;
6 6
7 import 'dart:collection' show HashSet, HashMap; 7 import 'dart:collection' show HashSet, HashMap;
8 import 'dart:io' show Directory, File; 8 import 'dart:io' show Directory, File;
9 9
10 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 10 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 JS.Statement _finishClassMembers(String name, JS.ClassExpression cls, 549 JS.Statement _finishClassMembers(String name, JS.ClassExpression cls,
550 List<ConstructorDeclaration> ctors, List<FieldDeclaration> staticFields) { 550 List<ConstructorDeclaration> ctors, List<FieldDeclaration> staticFields) {
551 var body = <JS.Statement>[]; 551 var body = <JS.Statement>[];
552 body.add(new JS.ClassDeclaration(cls)); 552 body.add(new JS.ClassDeclaration(cls));
553 553
554 // Named constructors 554 // Named constructors
555 for (ConstructorDeclaration member in ctors) { 555 for (ConstructorDeclaration member in ctors) {
556 if (member.name != null) { 556 if (member.name != null) {
557 body.add(js.statement('dart.defineNamedConstructor(#, #);', [ 557 body.add(js.statement('dart.defineNamedConstructor(#, #);', [
558 name, 558 name,
559 js.string(member.name.name, "'") 559 _jsMemberName(member.name.name, isStatic: true)
560 ])); 560 ]));
561 } 561 }
562 } 562 }
563 563
564 // Static fields 564 // Static fields
565 var lazyStatics = <VariableDeclaration>[]; 565 var lazyStatics = <VariableDeclaration>[];
566 for (FieldDeclaration member in staticFields) { 566 for (FieldDeclaration member in staticFields) {
567 for (VariableDeclaration field in member.fields.variables) { 567 for (VariableDeclaration field in member.fields.variables) {
568 var fieldName = field.name.name; 568 var fieldName = field.name.name;
569 if (field.isConst || _isFieldInitConstant(field)) { 569 if (field.isConst || _isFieldInitConstant(field)) {
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 845
846 @override 846 @override
847 JS.Method visitMethodDeclaration(MethodDeclaration node) { 847 JS.Method visitMethodDeclaration(MethodDeclaration node) {
848 if (node.isAbstract || _externalOrNative(node)) { 848 if (node.isAbstract || _externalOrNative(node)) {
849 return null; 849 return null;
850 } 850 }
851 851
852 var params = _visit(node.parameters); 852 var params = _visit(node.parameters);
853 if (params == null) params = []; 853 if (params == null) params = [];
854 854
855 return new JS.Method( 855 return new JS.Method(_jsMemberName(node.name.name, isStatic: node.isStatic),
856 _jsMemberName(node.name.name), new JS.Fun(params, _visit(node.body)), 856 new JS.Fun(params, _visit(node.body)),
857 isGetter: node.isGetter, 857 isGetter: node.isGetter,
858 isSetter: node.isSetter, 858 isSetter: node.isSetter,
859 isStatic: node.isStatic); 859 isStatic: node.isStatic);
860 } 860 }
861 861
862 @override 862 @override
863 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) { 863 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) {
864 assert(node.parent is CompilationUnit); 864 assert(node.parent is CompilationUnit);
865 865
866 if (_externalOrNative(node)) return null; 866 if (_externalOrNative(node)) return null;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 JS.Expression visitSimpleIdentifier(SimpleIdentifier node) { 935 JS.Expression visitSimpleIdentifier(SimpleIdentifier node) {
936 var e = node.staticElement; 936 var e = node.staticElement;
937 if (e == null) { 937 if (e == null) {
938 return js.commentExpression( 938 return js.commentExpression(
939 'Unimplemented unknown name', new JS.Identifier(node.name)); 939 'Unimplemented unknown name', new JS.Identifier(node.name));
940 } 940 }
941 941
942 var name = node.name; 942 var name = node.name;
943 var variable = e is PropertyAccessorElement ? e.variable : e; 943 var variable = e is PropertyAccessorElement ? e.variable : e;
944 944
945 // library member
945 if (e.enclosingElement is CompilationUnitElement && 946 if (e.enclosingElement is CompilationUnitElement &&
946 (e.library != libraryInfo.library || 947 (e.library != libraryInfo.library ||
947 variable is TopLevelVariableElement && !variable.isConst)) { 948 variable is TopLevelVariableElement && !variable.isConst)) {
948 return js.call('#.#', [_libraryName(e.library), name]); 949 return js.call('#.#', [_libraryName(e.library), name]);
949 } else if (currentClass != null && _needsImplicitThis(e)) { 950 }
951
952 // instance member
953 if (currentClass != null && _needsImplicitThis(e)) {
950 return js.call('this.#', _jsMemberName(name)); 954 return js.call('this.#', _jsMemberName(name));
951 } else if (variable is ConstFieldElementImpl) { 955 }
956
957 // static member
958 if (e is ExecutableElement &&
959 e.isStatic &&
960 variable.enclosingElement is ClassElement) {
952 var className = (variable.enclosingElement as ClassElement).name; 961 var className = (variable.enclosingElement as ClassElement).name;
953 return js.call('#.#', [className, name]); 962 return js.call('#.#', [className, _jsMemberName(name, isStatic: true)]);
954 } else if (e is ParameterElement && e.isInitializingFormal && e.isPrivate) { 963 }
964
965 // initializing formal parameter, e.g. `Point(this.x)`
966 if (e is ParameterElement && e.isInitializingFormal && e.isPrivate) {
955 /// Rename private names so they don't shadow the private field symbol. 967 /// Rename private names so they don't shadow the private field symbol.
956 /// The renamer would handle this, but it would prefer to rename the 968 /// The renamer would handle this, but it would prefer to rename the
957 /// temporary used for the private symbol. Instead rename the parameter. 969 /// temporary used for the private symbol. Instead rename the parameter.
958 return new JSTemporary('${name.substring(1)}'); 970 return new JSTemporary('${name.substring(1)}');
959 } else if (_isTemporary(e)) {
960 return new JSTemporary(e.name);
961 } 971 }
972
973 if (_isTemporary(e)) return new JSTemporary(e.name);
974
962 return new JS.Identifier(name); 975 return new JS.Identifier(name);
963 } 976 }
964 977
965 JS.Expression _emitTypeName(DartType type) { 978 JS.Expression _emitTypeName(DartType type) {
966 var name = type.name; 979 var name = type.name;
967 var element = type.element; 980 var element = type.element;
968 if (name == '') { 981 if (name == '') {
969 // TODO(jmesserly): remove when we're using coercion reifier. 982 // TODO(jmesserly): remove when we're using coercion reifier.
970 return _unimplementedCall('Unimplemented type $type'); 983 return _unimplementedCall('Unimplemented type $type');
971 } 984 }
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 @override 1700 @override
1688 visitPropertyAccess(PropertyAccess node) => 1701 visitPropertyAccess(PropertyAccess node) =>
1689 _visitGet(_getTarget(node), node.propertyName); 1702 _visitGet(_getTarget(node), node.propertyName);
1690 1703
1691 /// Shared code for [PrefixedIdentifier] and [PropertyAccess]. 1704 /// Shared code for [PrefixedIdentifier] and [PropertyAccess].
1692 _visitGet(Expression target, SimpleIdentifier name) { 1705 _visitGet(Expression target, SimpleIdentifier name) {
1693 if (rules.isDynamicTarget(target)) { 1706 if (rules.isDynamicTarget(target)) {
1694 return js.call( 1707 return js.call(
1695 'dart.dload(#, #)', [_visit(target), js.string(name.name, "'")]); 1708 'dart.dload(#, #)', [_visit(target), js.string(name.name, "'")]);
1696 } else { 1709 } else {
1697 return js.call('#.#', [_visit(target), _jsMemberName(name.name)]); 1710 var e = name.staticElement;
1711 return js.call('#.#', [
1712 _visit(target),
1713 _jsMemberName(name.name, isStatic: e is ExecutableElement && e.isStatic)
1714 ]);
1698 } 1715 }
1699 } 1716 }
1700 1717
1701 @override 1718 @override
1702 visitIndexExpression(IndexExpression node) { 1719 visitIndexExpression(IndexExpression node) {
1703 var target = _getTarget(node); 1720 var target = _getTarget(node);
1704 var code; 1721 var code;
1705 if (rules.isDynamicTarget(target)) { 1722 if (rules.isDynamicTarget(target)) {
1706 code = 'dart.dindex(#, #)'; 1723 code = 'dart.dindex(#, #)';
1707 } else { 1724 } else {
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
2087 /// 2104 ///
2088 /// This follows the same pattern as EcmaScript 6 Map: 2105 /// This follows the same pattern as EcmaScript 6 Map:
2089 /// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_ Objects/Map> 2106 /// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_ Objects/Map>
2090 /// 2107 ///
2091 /// Unary minus looks like: `x['unary-']()`. Note that [unary] must be passed 2108 /// Unary minus looks like: `x['unary-']()`. Note that [unary] must be passed
2092 /// for this transformation to happen, otherwise binary minus is assumed. 2109 /// for this transformation to happen, otherwise binary minus is assumed.
2093 /// 2110 ///
2094 /// Equality is a bit special, it is generated via the Dart `equals` runtime 2111 /// Equality is a bit special, it is generated via the Dart `equals` runtime
2095 /// helper, that checks for null. The user defined method is called '=='. 2112 /// helper, that checks for null. The user defined method is called '=='.
2096 /// 2113 ///
2097 JS.Expression _jsMemberName(String name, {bool unary: false}) { 2114 JS.Expression _jsMemberName(String name,
2115 {bool unary: false, bool isStatic: false}) {
2098 if (name.startsWith('_')) { 2116 if (name.startsWith('_')) {
2099 if (_privateNames.add(name)) _pendingPrivateNames.add(name); 2117 if (_privateNames.add(name)) _pendingPrivateNames.add(name);
2100 return new JSTemporary(name); 2118 return new JSTemporary(name);
2101 } 2119 }
2102 if (name == '[]') { 2120 if (name == '[]') {
2103 name = 'get'; 2121 name = 'get';
2104 } else if (name == '[]=') { 2122 } else if (name == '[]=') {
2105 name = 'set'; 2123 name = 'set';
2106 } else if (unary && name == '-') { 2124 } else if (unary && name == '-') {
2107 name = 'unary-'; 2125 name = 'unary-';
2126 } else if (isStatic && invalidJSStaticMethodName(name)) {
2127 // Choose an string name. Use an invalid identifier so it won't conflict
2128 // with any valid member names.
2129 // TODO(jmesserly): this works around the problem, but I'm pretty sure we
2130 // don't need it, as static methods seemed to work. The only concrete
2131 // issue we saw was in the defineNamedConstructor helper function.
2132 name = '$name*';
2108 } 2133 }
2109 return _propertyName(name); 2134 return _propertyName(name);
2110 } 2135 }
2111 2136
2112 bool _externalOrNative(node) => 2137 bool _externalOrNative(node) =>
2113 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody; 2138 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody;
2114 2139
2115 FunctionBody _functionBody(node) => 2140 FunctionBody _functionBody(node) =>
2116 node is FunctionDeclaration ? node.functionExpression.body : node.body; 2141 node is FunctionDeclaration ? node.functionExpression.body : node.body;
2117 2142
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2180 if (parent is Label) return; 2205 if (parent is Label) return;
2181 2206
2182 if (node.inSetterContext() && node.staticElement == _variable) { 2207 if (node.inSetterContext() && node.staticElement == _variable) {
2183 _potentiallyMutated = true; 2208 _potentiallyMutated = true;
2184 } 2209 }
2185 } 2210 }
2186 } 2211 }
2187 2212
2188 /// This is a workaround for V8 arrow function bindings being not yet 2213 /// This is a workaround for V8 arrow function bindings being not yet
2189 /// implemented. See issue #43 2214 /// implemented. See issue #43
2215 // TODO(jmesserly): cleaner to handle this workaround on the JS side.
2190 class _BindThisVisitor extends RecursiveAstVisitor { 2216 class _BindThisVisitor extends RecursiveAstVisitor {
2191 static _BindThisVisitor _instance = new _BindThisVisitor(); 2217 static _BindThisVisitor _instance = new _BindThisVisitor();
2192 bool _bindThis = false; 2218 bool _bindThis = false;
2193 2219
2194 @override 2220 @override
2195 visitSimpleIdentifier(SimpleIdentifier node) { 2221 visitSimpleIdentifier(SimpleIdentifier node) {
2196 if (JSCodegenVisitor._needsImplicitThis(node.staticElement)) { 2222 if (JSCodegenVisitor._needsImplicitThis(node.staticElement)) {
2197 _bindThis = true; 2223 _bindThis = true;
2198 } 2224 }
2199 } 2225 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2329 2355
2330 // TODO(jmesserly): in many cases marking the end will be unncessary. 2356 // TODO(jmesserly): in many cases marking the end will be unncessary.
2331 printer.mark(_location(node.end)); 2357 printer.mark(_location(node.end));
2332 } 2358 }
2333 2359
2334 String _getIdentifier(AstNode node) { 2360 String _getIdentifier(AstNode node) {
2335 if (node is SimpleIdentifier) return node.name; 2361 if (node is SimpleIdentifier) return node.name;
2336 return null; 2362 return null;
2337 } 2363 }
2338 } 2364 }
OLDNEW
« no previous file with comments | « lib/runtime/dart_runtime.js ('k') | lib/src/codegen/js_names.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698