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

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

Issue 1160343003: Revert "fixes #173, ability to use native JS indexers" (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 6 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 | « no previous file | lib/src/utils.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 8
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 JS.Program emitLibrary(LibraryUnit library) { 103 JS.Program emitLibrary(LibraryUnit library) {
104 String jsDefaultValue = null; 104 String jsDefaultValue = null;
105 105
106 // Modify the AST to make coercions explicit. 106 // Modify the AST to make coercions explicit.
107 new CoercionReifier(library, compiler).reify(); 107 new CoercionReifier(library, compiler).reify();
108 108
109 var unit = library.library; 109 var unit = library.library;
110 if (unit.directives.isNotEmpty) { 110 if (unit.directives.isNotEmpty) {
111 var libraryDir = unit.directives.first; 111 var libraryDir = unit.directives.first;
112 if (libraryDir is LibraryDirective) { 112 if (libraryDir is LibraryDirective) {
113 var jsName = findNodeAnnotation(libraryDir, _isJsNameAnnotation); 113 var jsName = getAnnotationValue(libraryDir, _isJsNameAnnotation);
114 jsDefaultValue = getConstantField(jsName, 'name', types.stringType); 114 jsDefaultValue = getConstantField(jsName, 'name', types.stringType);
115 } 115 }
116 } 116 }
117 if (jsDefaultValue == null) jsDefaultValue = '{}'; 117 if (jsDefaultValue == null) jsDefaultValue = '{}';
118 118
119 // TODO(jmesserly): visit scriptTag, directives? 119 // TODO(jmesserly): visit scriptTag, directives?
120 120
121 _loader.collectElements(currentLibrary, library.partsThenLibrary); 121 _loader.collectElements(currentLibrary, library.partsThenLibrary);
122 122
123 for (var unit in library.partsThenLibrary) { 123 for (var unit in library.partsThenLibrary) {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 return js.statement('let # = #;', [dartClassName, jsTypeName]); 322 return js.statement('let # = #;', [dartClassName, jsTypeName]);
323 } 323 }
324 return null; 324 return null;
325 } 325 }
326 326
327 @override 327 @override
328 JS.Statement visitClassDeclaration(ClassDeclaration node) { 328 JS.Statement visitClassDeclaration(ClassDeclaration node) {
329 // If we've already emitted this class, skip it. 329 // If we've already emitted this class, skip it.
330 var classElem = node.element; 330 var classElem = node.element;
331 var type = classElem.type; 331 var type = classElem.type;
332 var jsName = findNodeAnnotation(node, _isJsNameAnnotation); 332 var jsName = getAnnotationValue(node, _isJsNameAnnotation);
333 333
334 if (jsName != null) return _emitJsType(node.name.name, jsName); 334 if (jsName != null) return _emitJsType(node.name.name, jsName);
335 335
336 var ctors = <ConstructorDeclaration>[]; 336 var ctors = <ConstructorDeclaration>[];
337 var fields = <FieldDeclaration>[]; 337 var fields = <FieldDeclaration>[];
338 var methods = <MethodDeclaration>[]; 338 var methods = <MethodDeclaration>[];
339 for (var member in node.members) { 339 for (var member in node.members) {
340 if (member is ConstructorDeclaration) { 340 if (member is ConstructorDeclaration) {
341 ctors.add(member); 341 ctors.add(member);
342 } else if (member is FieldDeclaration && !member.isStatic) { 342 } else if (member is FieldDeclaration && !member.isStatic) {
343 fields.add(member); 343 fields.add(member);
344 } else if (member is MethodDeclaration) { 344 } else if (member is MethodDeclaration) {
345 methods.add(member); 345 methods.add(member);
346 } 346 }
347 } 347 }
348 348
349 var classExpr = new JS.ClassExpression(new JS.Identifier(type.name), 349 var classExpr = new JS.ClassExpression(new JS.Identifier(type.name),
350 _classHeritage(classElem), _emitClassMethods(node, ctors, fields)); 350 _classHeritage(classElem), _emitClassMethods(node, ctors, fields));
351 351
352 String jsPeerName; 352 String jsPeerName;
353 var jsPeer = findNodeAnnotation(node, _isJsPeerInterface); 353 var jsPeer = getAnnotationValue(node, _isJsPeerInterface);
354 if (jsPeer != null) { 354 if (jsPeer != null) {
355 jsPeerName = getConstantField(jsPeer, 'name', types.stringType); 355 jsPeerName = getConstantField(jsPeer, 'name', types.stringType);
356 } 356 }
357 357
358 var body = _finishClassMembers( 358 var body = _finishClassMembers(
359 classElem, classExpr, ctors, fields, methods, jsPeerName); 359 classElem, classExpr, ctors, fields, methods, jsPeerName);
360 360
361 var result = _finishClassDef(type, body); 361 var result = _finishClassDef(type, body);
362 362
363 if (jsPeerName != null) { 363 if (jsPeerName != null) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 var type = element.type; 468 var type = element.type;
469 var isObject = type.isObject; 469 var isObject = type.isObject;
470 470
471 // Iff no constructor is specified for a class C, it implicitly has a 471 // Iff no constructor is specified for a class C, it implicitly has a
472 // default constructor `C() : super() {}`, unless C is class Object. 472 // default constructor `C() : super() {}`, unless C is class Object.
473 var jsMethods = <JS.Method>[]; 473 var jsMethods = <JS.Method>[];
474 if (ctors.isEmpty && !isObject) { 474 if (ctors.isEmpty && !isObject) {
475 jsMethods.add(_emitImplicitConstructor(node, fields)); 475 jsMethods.add(_emitImplicitConstructor(node, fields));
476 } 476 }
477 477
478 bool hasJsPeer = findNodeAnnotation(node, _isJsPeerInterface) != null; 478 bool hasJsPeer = getAnnotationValue(node, _isJsPeerInterface) != null;
479 479
480 bool hasIterator = false; 480 bool hasIterator = false;
481 for (var m in node.members) { 481 for (var m in node.members) {
482 if (m is ConstructorDeclaration) { 482 if (m is ConstructorDeclaration) {
483 jsMethods.add(_emitConstructor(m, type, fields, isObject)); 483 jsMethods.add(_emitConstructor(m, type, fields, isObject));
484 } else if (m is MethodDeclaration) { 484 } else if (m is MethodDeclaration) {
485 jsMethods.add(_emitMethodDeclaration(type, m)); 485 jsMethods.add(_emitMethodDeclaration(type, m));
486 486
487 if (!hasJsPeer && m.isGetter && m.name.name == 'iterator') { 487 if (!hasJsPeer && m.isGetter && m.name.name == 'iterator') {
488 hasIterator = true; 488 hasIterator = true;
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 var vars = {}; 1342 var vars = {};
1343 var lhs = _bindLeftHandSide(vars, left, context: context); 1343 var lhs = _bindLeftHandSide(vars, left, context: context);
1344 var inc = AstBuilder.binaryExpression(lhs, op, right); 1344 var inc = AstBuilder.binaryExpression(lhs, op, right);
1345 inc.staticElement = element; 1345 inc.staticElement = element;
1346 inc.staticType = getStaticType(left); 1346 inc.staticType = getStaticType(left);
1347 return new JS.MetaLet(vars, [_emitSet(lhs, inc)]); 1347 return new JS.MetaLet(vars, [_emitSet(lhs, inc)]);
1348 } 1348 }
1349 1349
1350 JS.Expression _emitSet(Expression lhs, Expression rhs) { 1350 JS.Expression _emitSet(Expression lhs, Expression rhs) {
1351 if (lhs is IndexExpression) { 1351 if (lhs is IndexExpression) {
1352 var target = _getTarget(lhs); 1352 return _emitSend(_getTarget(lhs), '[]=', [lhs.index, rhs]);
1353 if (_useNativeJsIndexer(target.staticType)) {
1354 return js.call(
1355 '#[#] = #', [_visit(target), _visit(lhs.index), _visit(rhs)]);
1356 }
1357 return _emitSend(target, '[]=', [lhs.index, rhs]);
1358 } 1353 }
1359 1354
1360 Expression target = null; 1355 Expression target = null;
1361 SimpleIdentifier id; 1356 SimpleIdentifier id;
1362 if (lhs is PropertyAccess) { 1357 if (lhs is PropertyAccess) {
1363 target = _getTarget(lhs); 1358 target = _getTarget(lhs);
1364 id = lhs.propertyName; 1359 id = lhs.propertyName;
1365 } else if (lhs is PrefixedIdentifier) { 1360 } else if (lhs is PrefixedIdentifier) {
1366 target = lhs.prefix; 1361 target = lhs.prefix;
1367 id = lhs.identifier; 1362 id = lhs.identifier;
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
2114 _visitList(args) 2109 _visitList(args)
2115 ]); 2110 ]);
2116 } 2111 }
2117 2112
2118 // Generic dispatch to a statically known method. 2113 // Generic dispatch to a statically known method.
2119 return js.call('#.#(#)', [_visit(target), memberName, _visitList(args)]); 2114 return js.call('#.#(#)', [_visit(target), memberName, _visitList(args)]);
2120 } 2115 }
2121 2116
2122 @override 2117 @override
2123 visitIndexExpression(IndexExpression node) { 2118 visitIndexExpression(IndexExpression node) {
2124 var target = _getTarget(node); 2119 return _emitSend(_getTarget(node), '[]', [node.index]);
2125 if (_useNativeJsIndexer(target.staticType)) {
2126 return new JS.PropertyAccess(_visit(target), _visit(node.index));
2127 }
2128 return _emitSend(target, '[]', [node.index]);
2129 } 2120 }
2130 2121
2131 // TODO(jmesserly): ideally we'd check the method and see if it is marked
2132 // `external`, but that doesn't work because it isn't in the element model.
2133 bool _useNativeJsIndexer(DartType type) =>
2134 findElementAnnotation(type.element, _isJsIndexerAnnotation) != null;
2135
2136 /// Gets the target of a [PropertyAccess] or [IndexExpression]. 2122 /// Gets the target of a [PropertyAccess] or [IndexExpression].
2137 /// Those two nodes are special because they're both allowed on left side of 2123 /// Those two nodes are special because they're both allowed on left side of
2138 /// an assignment expression and cascades. 2124 /// an assignment expression and cascades.
2139 Expression _getTarget(node) { 2125 Expression _getTarget(node) {
2140 assert(node is IndexExpression || node is PropertyAccess); 2126 assert(node is IndexExpression || node is PropertyAccess);
2141 return node.isCascaded ? _cascadeTarget : node.target; 2127 return node.isCascaded ? _cascadeTarget : node.target;
2142 } 2128 }
2143 2129
2144 @override 2130 @override
2145 visitConditionalExpression(ConditionalExpression node) { 2131 visitConditionalExpression(ConditionalExpression node) {
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
2643 assert(uri.scheme == 'package'); 2629 assert(uri.scheme == 'package');
2644 // filepath is good here, we want the output to start with a directory 2630 // filepath is good here, we want the output to start with a directory
2645 // matching the package name. 2631 // matching the package name.
2646 } 2632 }
2647 return filepath; 2633 return filepath;
2648 } 2634 }
2649 2635
2650 // TODO(jmesserly): validate the library. See issue #135. 2636 // TODO(jmesserly): validate the library. See issue #135.
2651 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName'; 2637 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName';
2652 2638
2653 bool _isJsIndexerAnnotation(DartObjectImpl value) =>
2654 value.type.name == 'JsIndexer';
2655
2656 bool _isJsPeerInterface(DartObjectImpl value) => 2639 bool _isJsPeerInterface(DartObjectImpl value) =>
2657 value.type.name == 'JsPeerInterface'; 2640 value.type.name == 'JsPeerInterface';
2658 2641
2659 // TODO(jacobr): we would like to do something like the following 2642 // TODO(jacobr): we would like to do something like the following
2660 // but we don't have summary support yet. 2643 // but we don't have summary support yet.
2661 // bool _supportJsExtensionMethod(AnnotatedNode node) => 2644 // bool _supportJsExtensionMethod(AnnotatedNode node) =>
2662 // _getAnnotation(node, "SupportJsExtensionMethod") != null; 2645 // _getAnnotation(node, "SupportJsExtensionMethod") != null;
2663 2646
2664 /// A special kind of element created by the compiler, signifying a temporary 2647 /// A special kind of element created by the compiler, signifying a temporary
2665 /// variable. These objects use instance equality, and should be shared 2648 /// variable. These objects use instance equality, and should be shared
2666 /// everywhere in the tree where they are treated as the same variable. 2649 /// everywhere in the tree where they are treated as the same variable.
2667 class TemporaryVariableElement extends LocalVariableElementImpl { 2650 class TemporaryVariableElement extends LocalVariableElementImpl {
2668 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 2651 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
2669 2652
2670 int get hashCode => identityHashCode(this); 2653 int get hashCode => identityHashCode(this);
2671 bool operator ==(Object other) => identical(this, other); 2654 bool operator ==(Object other) => identical(this, other);
2672 } 2655 }
OLDNEW
« no previous file with comments | « no previous file | lib/src/utils.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698