| OLD | NEW |
| 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, SplayTreeSet; | 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; |
| 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 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 | 303 |
| 304 String _jsTypeofName(DartType t) { | 304 String _jsTypeofName(DartType t) { |
| 305 if (rules.isIntType(t) || rules.isDoubleType(t)) return 'number'; | 305 if (rules.isIntType(t) || rules.isDoubleType(t)) return 'number'; |
| 306 if (rules.isStringType(t)) return 'string'; | 306 if (rules.isStringType(t)) return 'string'; |
| 307 if (rules.isBoolType(t)) return 'boolean'; | 307 if (rules.isBoolType(t)) return 'boolean'; |
| 308 return null; | 308 return null; |
| 309 } | 309 } |
| 310 | 310 |
| 311 @override | 311 @override |
| 312 visitFunctionTypeAlias(FunctionTypeAlias node) { | 312 visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 313 // If we've already emitted this class, skip it. | |
| 314 var element = node.element; | 313 var element = node.element; |
| 315 var type = element.type; | 314 var type = element.type; |
| 316 var name = element.name; | 315 var name = element.name; |
| 317 | 316 |
| 318 var fnType = js.statement('let # = dart.typedef(#, () => #);', [ | 317 var fnType = js.statement('let # = dart.typedef(#, () => #);', [ |
| 319 name, | 318 name, |
| 320 js.string(name, "'"), | 319 js.string(name, "'"), |
| 321 _emitTypeName(type, lowerTypedef: true) | 320 _emitTypeName(type, lowerTypedef: true) |
| 322 ]); | 321 ]); |
| 323 | 322 |
| 324 return _finishClassDef(type, fnType); | 323 return _finishClassDef(type, fnType); |
| 325 } | 324 } |
| 326 | 325 |
| 327 @override | 326 @override |
| 328 JS.Expression visitTypeName(TypeName node) => _emitTypeName(node.type); | 327 JS.Expression visitTypeName(TypeName node) => _emitTypeName(node.type); |
| 329 | 328 |
| 330 @override | 329 @override |
| 331 JS.Statement visitClassTypeAlias(ClassTypeAlias node) { | 330 JS.Statement visitClassTypeAlias(ClassTypeAlias node) { |
| 332 // If we've already emitted this class, skip it. | |
| 333 var element = node.element; | 331 var element = node.element; |
| 334 | 332 |
| 333 // Forward all generative constructors from the base class. |
| 334 var body = []; |
| 335 |
| 336 var supertype = element.supertype; |
| 337 if (!supertype.isObject) { |
| 338 for (var ctor in element.constructors) { |
| 339 var parentCtor = supertype.lookUpConstructor(ctor.name, ctor.library); |
| 340 var fun = js.call('function() { super.#(...#); }', [ |
| 341 _constructorName(parentCtor), |
| 342 new JS.Identifier('arguments', allowRename: false) |
| 343 ]); |
| 344 body.add(new JS.Method(_constructorName(ctor), fun)); |
| 345 } |
| 346 } |
| 347 |
| 335 var classDecl = new JS.ClassDeclaration(new JS.ClassExpression( | 348 var classDecl = new JS.ClassDeclaration(new JS.ClassExpression( |
| 336 new JS.Identifier(element.name), _classHeritage(element), [])); | 349 new JS.Identifier(element.name), _classHeritage(element), body)); |
| 337 | 350 |
| 338 return _finishClassDef(element.type, classDecl); | 351 return _finishClassDef(element.type, classDecl); |
| 339 } | 352 } |
| 340 | 353 |
| 341 JS.Statement _emitJsType(String dartClassName, DartObjectImpl jsName) { | 354 JS.Statement _emitJsType(String dartClassName, DartObjectImpl jsName) { |
| 342 var jsTypeName = getConstantField(jsName, 'name', types.stringType); | 355 var jsTypeName = getConstantField(jsName, 'name', types.stringType); |
| 343 | 356 |
| 344 if (jsTypeName != null && jsTypeName != dartClassName) { | 357 if (jsTypeName != null && jsTypeName != dartClassName) { |
| 345 // We export the JS type as if it was a Dart type. For example this allows | 358 // We export the JS type as if it was a Dart type. For example this allows |
| 346 // `dom.InputElement` to actually be HTMLInputElement. | 359 // `dom.InputElement` to actually be HTMLInputElement. |
| 347 // TODO(jmesserly): if we had the JsName on the Element, we could just | 360 // TODO(jmesserly): if we had the JsName on the Element, we could just |
| 348 // generate it correctly when we refer to it. | 361 // generate it correctly when we refer to it. |
| 349 if (isPublic(dartClassName)) _addExport(dartClassName); | 362 if (isPublic(dartClassName)) _addExport(dartClassName); |
| 350 return js.statement('let # = #;', [dartClassName, jsTypeName]); | 363 return js.statement('let # = #;', [dartClassName, jsTypeName]); |
| 351 } | 364 } |
| 352 return null; | 365 return null; |
| 353 } | 366 } |
| 354 | 367 |
| 355 @override | 368 @override |
| 356 JS.Statement visitClassDeclaration(ClassDeclaration node) { | 369 JS.Statement visitClassDeclaration(ClassDeclaration node) { |
| 357 // If we've already emitted this class, skip it. | |
| 358 var classElem = node.element; | 370 var classElem = node.element; |
| 359 var type = classElem.type; | 371 var type = classElem.type; |
| 360 var jsName = findAnnotation(classElem, _isJsNameAnnotation); | 372 var jsName = findAnnotation(classElem, _isJsNameAnnotation); |
| 361 | 373 |
| 362 if (jsName != null) return _emitJsType(node.name.name, jsName); | 374 if (jsName != null) return _emitJsType(node.name.name, jsName); |
| 363 | 375 |
| 364 var ctors = <ConstructorDeclaration>[]; | 376 var ctors = <ConstructorDeclaration>[]; |
| 365 var fields = <FieldDeclaration>[]; | 377 var fields = <FieldDeclaration>[]; |
| 366 var methods = <MethodDeclaration>[]; | 378 var methods = <MethodDeclaration>[]; |
| 367 for (var member in node.members) { | 379 for (var member in node.members) { |
| (...skipping 2422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2790 | 2802 |
| 2791 /// A special kind of element created by the compiler, signifying a temporary | 2803 /// A special kind of element created by the compiler, signifying a temporary |
| 2792 /// variable. These objects use instance equality, and should be shared | 2804 /// variable. These objects use instance equality, and should be shared |
| 2793 /// everywhere in the tree where they are treated as the same variable. | 2805 /// everywhere in the tree where they are treated as the same variable. |
| 2794 class TemporaryVariableElement extends LocalVariableElementImpl { | 2806 class TemporaryVariableElement extends LocalVariableElementImpl { |
| 2795 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 2807 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
| 2796 | 2808 |
| 2797 int get hashCode => identityHashCode(this); | 2809 int get hashCode => identityHashCode(this); |
| 2798 bool operator ==(Object other) => identical(this, other); | 2810 bool operator ==(Object other) => identical(this, other); |
| 2799 } | 2811 } |
| OLD | NEW |