| 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 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 if (hide != null) { | 286 if (hide != null) { |
| 287 hiddenNames.addAll(hide.hiddenNames.map((i) => js.string(i.name, "'"))); | 287 hiddenNames.addAll(hide.hiddenNames.map((i) => js.string(i.name, "'"))); |
| 288 } | 288 } |
| 289 args.add(new JS.ArrayInitializer(shownNames)); | 289 args.add(new JS.ArrayInitializer(shownNames)); |
| 290 args.add(new JS.ArrayInitializer(hiddenNames)); | 290 args.add(new JS.ArrayInitializer(hiddenNames)); |
| 291 } | 291 } |
| 292 _moduleItems.add(js.statement('dart.export(#);', [args])); | 292 _moduleItems.add(js.statement('dart.export(#);', [args])); |
| 293 } | 293 } |
| 294 | 294 |
| 295 JS.Identifier _initSymbol(JS.Identifier id) { | 295 JS.Identifier _initSymbol(JS.Identifier id) { |
| 296 var s = js.statement('let # = $_SYMBOL(#);', [id, js.string(id.name, "'")]); | 296 var s = |
| 297 js.statement('const # = $_SYMBOL(#);', [id, js.string(id.name, "'")]); |
| 297 _moduleItems.add(s); | 298 _moduleItems.add(s); |
| 298 return id; | 299 return id; |
| 299 } | 300 } |
| 300 | 301 |
| 301 // TODO(jmesserly): this is a temporary workaround for `Symbol` in core, | 302 // TODO(jmesserly): this is a temporary workaround for `Symbol` in core, |
| 302 // until we have better name tracking. | 303 // until we have better name tracking. |
| 303 String get _SYMBOL { | 304 String get _SYMBOL { |
| 304 var name = currentLibrary.name; | 305 var name = currentLibrary.name; |
| 305 if (name == 'dart.core' || name == 'dart._internal') return 'dart.JsSymbol'; | 306 if (name == 'dart.core' || name == 'dart._internal') return 'dart.JsSymbol'; |
| 306 return 'Symbol'; | 307 return 'Symbol'; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 return null; | 360 return null; |
| 360 } | 361 } |
| 361 | 362 |
| 362 @override | 363 @override |
| 363 visitFunctionTypeAlias(FunctionTypeAlias node) { | 364 visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 364 var element = node.element; | 365 var element = node.element; |
| 365 var type = element.type; | 366 var type = element.type; |
| 366 var name = element.name; | 367 var name = element.name; |
| 367 | 368 |
| 368 var fnType = annotateTypeDef( | 369 var fnType = annotateTypeDef( |
| 369 js.statement('let # = dart.typedef(#, () => #);', [ | 370 js.statement('const # = dart.typedef(#, () => #);', [ |
| 370 name, | 371 name, |
| 371 js.string(name, "'"), | 372 js.string(name, "'"), |
| 372 _emitTypeName(type, lowerTypedef: true) | 373 _emitTypeName(type, lowerTypedef: true) |
| 373 ]), | 374 ]), |
| 374 node.element); | 375 node.element); |
| 375 | 376 |
| 376 return _finishClassDef(type, fnType); | 377 return _finishClassDef(type, fnType); |
| 377 } | 378 } |
| 378 | 379 |
| 379 @override | 380 @override |
| (...skipping 25 matching lines...) Expand all Loading... |
| 405 JS.Statement _emitJsType(String dartClassName, DartObject jsName) { | 406 JS.Statement _emitJsType(String dartClassName, DartObject jsName) { |
| 406 var jsTypeName = | 407 var jsTypeName = |
| 407 getConstantField(jsName, 'name', types.stringType)?.toStringValue(); | 408 getConstantField(jsName, 'name', types.stringType)?.toStringValue(); |
| 408 | 409 |
| 409 if (jsTypeName != null && jsTypeName != dartClassName) { | 410 if (jsTypeName != null && jsTypeName != dartClassName) { |
| 410 // We export the JS type as if it was a Dart type. For example this allows | 411 // We export the JS type as if it was a Dart type. For example this allows |
| 411 // `dom.InputElement` to actually be HTMLInputElement. | 412 // `dom.InputElement` to actually be HTMLInputElement. |
| 412 // TODO(jmesserly): if we had the JS name on the Element, we could just | 413 // TODO(jmesserly): if we had the JS name on the Element, we could just |
| 413 // generate it correctly when we refer to it. | 414 // generate it correctly when we refer to it. |
| 414 if (isPublic(dartClassName)) _addExport(dartClassName); | 415 if (isPublic(dartClassName)) _addExport(dartClassName); |
| 415 return js.statement('let # = #;', [dartClassName, jsTypeName]); | 416 return js.statement('const # = #;', [dartClassName, jsTypeName]); |
| 416 } | 417 } |
| 417 return null; | 418 return null; |
| 418 } | 419 } |
| 419 | 420 |
| 420 @override | 421 @override |
| 421 JS.Statement visitClassDeclaration(ClassDeclaration node) { | 422 JS.Statement visitClassDeclaration(ClassDeclaration node) { |
| 422 var classElem = node.element; | 423 var classElem = node.element; |
| 423 var type = classElem.type; | 424 var type = classElem.type; |
| 424 var jsName = findAnnotation(classElem, isJSAnnotation); | 425 var jsName = findAnnotation(classElem, isJSAnnotation); |
| 425 | 426 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 return js.statement('{ #; let # = #; }', [genericDef, name, genericInst]); | 556 return js.statement('{ #; let # = #; }', [genericDef, name, genericInst]); |
| 556 } | 557 } |
| 557 return body; | 558 return body; |
| 558 } | 559 } |
| 559 | 560 |
| 560 JS.Statement _emitGenericClassDef(ParameterizedType type, JS.Statement body) { | 561 JS.Statement _emitGenericClassDef(ParameterizedType type, JS.Statement body) { |
| 561 var name = type.name; | 562 var name = type.name; |
| 562 var genericName = '$name\$'; | 563 var genericName = '$name\$'; |
| 563 var typeParams = type.typeParameters.map((p) => p.name); | 564 var typeParams = type.typeParameters.map((p) => p.name); |
| 564 if (isPublic(name)) _exports.add(genericName); | 565 if (isPublic(name)) _exports.add(genericName); |
| 565 return js.statement('let # = dart.generic(function(#) { #; return #; });', | 566 return js.statement('const # = dart.generic(function(#) { #; return #; });', |
| 566 [genericName, typeParams, body, name]); | 567 [genericName, typeParams, body, name]); |
| 567 } | 568 } |
| 568 | 569 |
| 569 final _hasDeferredSupertype = new HashSet<ClassElement>(); | 570 final _hasDeferredSupertype = new HashSet<ClassElement>(); |
| 570 | 571 |
| 571 bool _deferIfNeeded(DartType type, ClassElement current) { | 572 bool _deferIfNeeded(DartType type, ClassElement current) { |
| 572 if (type is ParameterizedType) { | 573 if (type is ParameterizedType) { |
| 573 var typeArguments = type.typeArguments; | 574 var typeArguments = type.typeArguments; |
| 574 for (var typeArg in typeArguments) { | 575 for (var typeArg in typeArguments) { |
| 575 var typeElement = typeArg.element; | 576 var typeElement = typeArg.element; |
| (...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 var func = node.functionDeclaration; | 1454 var func = node.functionDeclaration; |
| 1454 if (func.isGetter || func.isSetter) { | 1455 if (func.isGetter || func.isSetter) { |
| 1455 return js.comment('Unimplemented function get/set statement: $node'); | 1456 return js.comment('Unimplemented function get/set statement: $node'); |
| 1456 } | 1457 } |
| 1457 | 1458 |
| 1458 var fn = _visit(func.functionExpression); | 1459 var fn = _visit(func.functionExpression); |
| 1459 | 1460 |
| 1460 var name = new JS.Identifier(func.name.name); | 1461 var name = new JS.Identifier(func.name.name); |
| 1461 JS.Statement declareFn; | 1462 JS.Statement declareFn; |
| 1462 if (JS.This.foundIn(fn)) { | 1463 if (JS.This.foundIn(fn)) { |
| 1463 declareFn = js.statement('let # = #.bind(this);', [name, fn]); | 1464 declareFn = js.statement('const # = #.bind(this);', [name, fn]); |
| 1464 } else { | 1465 } else { |
| 1465 declareFn = new JS.FunctionDeclaration(name, fn); | 1466 declareFn = new JS.FunctionDeclaration(name, fn); |
| 1466 } | 1467 } |
| 1467 declareFn = annotate(declareFn, node.functionDeclaration.element); | 1468 declareFn = annotate(declareFn, node.functionDeclaration.element); |
| 1468 | 1469 |
| 1469 return new JS.Block([ | 1470 return new JS.Block([ |
| 1470 declareFn, | 1471 declareFn, |
| 1471 _emitFunctionTagged(name, func.element.type).toStatement() | 1472 _emitFunctionTagged(name, func.element.type).toStatement() |
| 1472 ]); | 1473 ]); |
| 1473 } | 1474 } |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2040 eagerInit = false; | 2041 eagerInit = false; |
| 2041 } | 2042 } |
| 2042 | 2043 |
| 2043 var fieldName = field.name.name; | 2044 var fieldName = field.name.name; |
| 2044 if (field.isConst && eagerInit && element is TopLevelVariableElement) { | 2045 if (field.isConst && eagerInit && element is TopLevelVariableElement) { |
| 2045 // constant fields don't change, so we can generate them as `let` | 2046 // constant fields don't change, so we can generate them as `let` |
| 2046 // but add them to the module's exports. However, make sure we generate | 2047 // but add them to the module's exports. However, make sure we generate |
| 2047 // anything they depend on first. | 2048 // anything they depend on first. |
| 2048 | 2049 |
| 2049 if (isPublic(fieldName)) _addExport(fieldName); | 2050 if (isPublic(fieldName)) _addExport(fieldName); |
| 2051 var declKeyword = field.isConst || field.isFinal ? 'const' : 'let'; |
| 2050 return annotateVariable( | 2052 return annotateVariable( |
| 2051 js.statement('let # = #;', [new JS.Identifier(fieldName), jsInit]), | 2053 js.statement( |
| 2054 '$declKeyword # = #;', [new JS.Identifier(fieldName), jsInit]), |
| 2052 field.element); | 2055 field.element); |
| 2053 } | 2056 } |
| 2054 | 2057 |
| 2055 if (eagerInit && !JS.invalidStaticFieldName(fieldName)) { | 2058 if (eagerInit && !JS.invalidStaticFieldName(fieldName)) { |
| 2056 return annotateVariable( | 2059 return annotateVariable( |
| 2057 js.statement('# = #;', [_visit(field.name), jsInit]), field.element); | 2060 js.statement('# = #;', [_visit(field.name), jsInit]), field.element); |
| 2058 } | 2061 } |
| 2059 | 2062 |
| 2060 var body = <JS.Statement>[]; | 2063 var body = <JS.Statement>[]; |
| 2061 if (_lazyFields.isNotEmpty) { | 2064 if (_lazyFields.isNotEmpty) { |
| (...skipping 1285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3347 | 3350 |
| 3348 /// A special kind of element created by the compiler, signifying a temporary | 3351 /// A special kind of element created by the compiler, signifying a temporary |
| 3349 /// variable. These objects use instance equality, and should be shared | 3352 /// variable. These objects use instance equality, and should be shared |
| 3350 /// everywhere in the tree where they are treated as the same variable. | 3353 /// everywhere in the tree where they are treated as the same variable. |
| 3351 class TemporaryVariableElement extends LocalVariableElementImpl { | 3354 class TemporaryVariableElement extends LocalVariableElementImpl { |
| 3352 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 3355 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
| 3353 | 3356 |
| 3354 int get hashCode => identityHashCode(this); | 3357 int get hashCode => identityHashCode(this); |
| 3355 bool operator ==(Object other) => identical(this, other); | 3358 bool operator ==(Object other) => identical(this, other); |
| 3356 } | 3359 } |
| OLD | NEW |