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

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

Issue 1135543003: Fixes #178 (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Minor fixes + tests Created 5 years, 7 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/math.js ('k') | test/browser/runtime_tests.js » ('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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 final HashSet<FieldElement> _fieldsNeedingStorage; 61 final HashSet<FieldElement> _fieldsNeedingStorage;
62 62
63 /// The variable for the target of the current `..` cascade expression. 63 /// The variable for the target of the current `..` cascade expression.
64 SimpleIdentifier _cascadeTarget; 64 SimpleIdentifier _cascadeTarget;
65 65
66 /// The variable for the current catch clause 66 /// The variable for the current catch clause
67 SimpleIdentifier _catchParameter; 67 SimpleIdentifier _catchParameter;
68 68
69 ConstantEvaluator _constEvaluator; 69 ConstantEvaluator _constEvaluator;
70 70
71 ClassElement _currentClassElement = null;
72
71 /// Imported libraries, and the temporaries used to refer to them. 73 /// Imported libraries, and the temporaries used to refer to them.
72 final _imports = new Map<LibraryElement, JS.TemporaryId>(); 74 final _imports = new Map<LibraryElement, JS.TemporaryId>();
73 final _exports = new Set<String>(); 75 final _exports = new Set<String>();
74 final _lazyFields = <VariableDeclaration>[]; 76 final _lazyFields = <VariableDeclaration>[];
75 final _properties = <FunctionDeclaration>[]; 77 final _properties = <FunctionDeclaration>[];
76 final _privateNames = new HashMap<String, JS.TemporaryId>(); 78 final _privateNames = new HashMap<String, JS.TemporaryId>();
77 final _extensionMethodNames = new HashSet<String>(); 79 final _extensionMethodNames = new HashSet<String>();
78 final _pendingStatements = <JS.Statement>[]; 80 final _pendingStatements = <JS.Statement>[];
79 final _temps = new HashMap<Element, JS.TemporaryId>(); 81 final _temps = new HashMap<Element, JS.TemporaryId>();
80 82
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 JS.Statement visitClassDeclaration(ClassDeclaration node) { 327 JS.Statement visitClassDeclaration(ClassDeclaration node) {
326 // If we've already emitted this class, skip it. 328 // If we've already emitted this class, skip it.
327 var classElem = node.element; 329 var classElem = node.element;
328 var type = classElem.type; 330 var type = classElem.type;
329 if (_pendingClasses.remove(classElem) == null) return null; 331 if (_pendingClasses.remove(classElem) == null) return null;
330 332
331 var jsName = getAnnotationValue(node, _isJsNameAnnotation); 333 var jsName = getAnnotationValue(node, _isJsNameAnnotation);
332 334
333 if (jsName != null) return _emitJsType(node.name.name, jsName); 335 if (jsName != null) return _emitJsType(node.name.name, jsName);
334 336
337 // Set current class
338 assert(_currentClassElement == null);
339 _currentClassElement = classElem;
340
335 var ctors = <ConstructorDeclaration>[]; 341 var ctors = <ConstructorDeclaration>[];
336 var fields = <FieldDeclaration>[]; 342 var fields = <FieldDeclaration>[];
337 var staticFields = <FieldDeclaration>[]; 343 var staticFields = <FieldDeclaration>[];
338 for (var member in node.members) { 344 for (var member in node.members) {
339 if (member is ConstructorDeclaration) { 345 if (member is ConstructorDeclaration) {
340 ctors.add(member); 346 ctors.add(member);
341 } else if (member is FieldDeclaration) { 347 } else if (member is FieldDeclaration) {
342 (member.isStatic ? staticFields : fields).add(member); 348 (member.isStatic ? staticFields : fields).add(member);
343 } 349 }
344 } 350 }
345 351
346 var classExpr = new JS.ClassExpression(new JS.Identifier(type.name), 352 var classExpr = new JS.ClassExpression(new JS.Identifier(type.name),
347 _classHeritage(node), _emitClassMethods(node, ctors, fields)); 353 _classHeritage(node), _emitClassMethods(node, ctors, fields));
348 354
349 String jsPeerName; 355 String jsPeerName;
350 var jsPeer = getAnnotationValue(node, _isJsPeerInterface); 356 var jsPeer = getAnnotationValue(node, _isJsPeerInterface);
351 if (jsPeer != null) { 357 if (jsPeer != null) {
352 jsPeerName = getConstantField(jsPeer, 'name', types.stringType); 358 jsPeerName = getConstantField(jsPeer, 'name', types.stringType);
353 } 359 }
354 360
355 var body = _finishClassMembers( 361 var body = _finishClassMembers(
356 classElem, classExpr, ctors, fields, staticFields, jsPeerName); 362 classElem, classExpr, ctors, fields, staticFields, jsPeerName);
357 363
364 // Unset current class
365 assert(_currentClassElement == classElem);
366 _currentClassElement = null;
367
358 var result = _finishClassDef(type, body); 368 var result = _finishClassDef(type, body);
359 369
360 if (jsPeerName != null) { 370 if (jsPeerName != null) {
361 // This class isn't allowed to be lazy, because we need to set up 371 // This class isn't allowed to be lazy, because we need to set up
362 // the native JS type eagerly at this point. 372 // the native JS type eagerly at this point.
363 // If we wanted to support laziness, we could defer the hookup until 373 // If we wanted to support laziness, we could defer the hookup until
364 // the end of the Dart library cycle load. 374 // the end of the Dart library cycle load.
365 assert(!_lazyClass(type)); 375 assert(!_lazyClass(type));
366 376
367 // TODO(jmesserly): this copies the dynamic members. 377 // TODO(jmesserly): this copies the dynamic members.
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 ]); 1238 ]);
1229 } 1239 }
1230 } 1240 }
1231 // TODO(jmesserly): remove when we're using coercion reifier. 1241 // TODO(jmesserly): remove when we're using coercion reifier.
1232 return _unimplementedCall('Unimplemented type $type'); 1242 return _unimplementedCall('Unimplemented type $type');
1233 } 1243 }
1234 1244
1235 var typeArgs = null; 1245 var typeArgs = null;
1236 if (type is ParameterizedType) { 1246 if (type is ParameterizedType) {
1237 var args = type.typeArguments; 1247 var args = type.typeArguments;
1248 var isCurrentClass =
1249 type is InterfaceType ? type.element == _currentClassElement : false;
1238 if (args.any((a) => a != types.dynamicType)) { 1250 if (args.any((a) => a != types.dynamicType)) {
1239 name = '$name\$'; 1251 name = '$name\$';
1240 typeArgs = args.map(_emitTypeName); 1252 typeArgs = args.map(_emitTypeName);
1253 } else if (args.isNotEmpty && isCurrentClass) {
1254 // When creating a `new S<dynamic>` we try and use the raw form `new S() `,
Jennifer Messerly 2015/05/11 17:52:56 maybe a long line?
vsm 2015/05/11 17:56:03 Done.
1255 // but this does not work if we're inside the same class, because `S` re fers
1256 // to the current S<T> we are generating.
1257 name = '$name\$';
1258 typeArgs = [];
1241 } 1259 }
1242 } 1260 }
1243 1261
1244 JS.Expression result; 1262 JS.Expression result;
1245 if (_needQualifiedName(element)) { 1263 if (_needQualifiedName(element)) {
1246 result = js.call('#.#', [_libraryName(element.library), name]); 1264 result = js.call('#.#', [_libraryName(element.library), name]);
1247 } else { 1265 } else {
1248 result = new JS.Identifier(name); 1266 result = new JS.Identifier(name);
1249 } 1267 }
1250 1268
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after
2594 // TODO(jmesserly): validate the library. See issue #135. 2612 // TODO(jmesserly): validate the library. See issue #135.
2595 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName'; 2613 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName';
2596 2614
2597 bool _isJsPeerInterface(DartObjectImpl value) => 2615 bool _isJsPeerInterface(DartObjectImpl value) =>
2598 value.type.name == 'JsPeerInterface'; 2616 value.type.name == 'JsPeerInterface';
2599 2617
2600 // TODO(jacobr): we would like to do something like the following 2618 // TODO(jacobr): we would like to do something like the following
2601 // but we don't have summary support yet. 2619 // but we don't have summary support yet.
2602 // bool _supportJsExtensionMethod(AnnotatedNode node) => 2620 // bool _supportJsExtensionMethod(AnnotatedNode node) =>
2603 // _getAnnotation(node, "SupportJsExtensionMethod") != null; 2621 // _getAnnotation(node, "SupportJsExtensionMethod") != null;
OLDNEW
« no previous file with comments | « lib/runtime/dart/math.js ('k') | test/browser/runtime_tests.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698