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

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

Issue 1368153002: [js] simplify qualified names (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 2 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 | tool/sdk_expected_errors.txt » ('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, 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;
11 import 'package:analyzer/src/generated/constant.dart'; 11 import 'package:analyzer/src/generated/constant.dart';
12 import 'package:analyzer/src/generated/element.dart'; 12 import 'package:analyzer/src/generated/element.dart';
13 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; 13 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
14 import 'package:analyzer/src/generated/scanner.dart' 14 import 'package:analyzer/src/generated/scanner.dart'
15 show StringToken, Token, TokenType; 15 show StringToken, Token, TokenType;
16 import 'package:analyzer/src/task/dart.dart' show PublicNamespaceBuilder; 16 import 'package:analyzer/src/task/dart.dart' show PublicNamespaceBuilder;
17 17
18 import 'ast_builder.dart' show AstBuilder; 18 import 'ast_builder.dart' show AstBuilder;
19 import 'reify_coercions.dart' show CoercionReifier; 19 import 'reify_coercions.dart' show CoercionReifier, Tuple2;
20 20
21 // TODO(jmesserly): import from its own package 21 // TODO(jmesserly): import from its own package
22 import '../js/js_ast.dart' as JS; 22 import '../js/js_ast.dart' as JS;
23 import '../js/js_ast.dart' show js; 23 import '../js/js_ast.dart' show js;
24 24
25 import '../closure/closure_annotator.dart' show ClosureAnnotator; 25 import '../closure/closure_annotator.dart' show ClosureAnnotator;
26 import '../compiler.dart' show AbstractCompiler; 26 import '../compiler.dart' show AbstractCompiler;
27 import '../checker/rules.dart'; 27 import '../checker/rules.dart';
28 import '../info.dart'; 28 import '../info.dart';
29 import '../options.dart' show CodegenOptions; 29 import '../options.dart' show CodegenOptions;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 JS.TemporaryId _asyncStarController; 75 JS.TemporaryId _asyncStarController;
76 76
77 /// Imported libraries, and the temporaries used to refer to them. 77 /// Imported libraries, and the temporaries used to refer to them.
78 final _imports = new Map<LibraryElement, JS.TemporaryId>(); 78 final _imports = new Map<LibraryElement, JS.TemporaryId>();
79 final _exports = new Set<String>(); 79 final _exports = new Set<String>();
80 final _lazyFields = <VariableDeclaration>[]; 80 final _lazyFields = <VariableDeclaration>[];
81 final _properties = <FunctionDeclaration>[]; 81 final _properties = <FunctionDeclaration>[];
82 final _privateNames = new HashMap<String, JS.TemporaryId>(); 82 final _privateNames = new HashMap<String, JS.TemporaryId>();
83 final _moduleItems = <JS.Statement>[]; 83 final _moduleItems = <JS.Statement>[];
84 final _temps = new HashMap<Element, JS.TemporaryId>(); 84 final _temps = new HashMap<Element, JS.TemporaryId>();
85 final _qualifiedIds = new HashMap<Element, JS.MaybeQualifiedId>(); 85 final _qualifiedIds = new List<Tuple2<Element, JS.MaybeQualifiedId>>();
86 final _qualifiedGenericIds = new HashMap<Element, JS.MaybeQualifiedId>();
87 86
88 /// The name for the library's exports inside itself. 87 /// The name for the library's exports inside itself.
89 /// `exports` was chosen as the most similar to ES module patterns. 88 /// `exports` was chosen as the most similar to ES module patterns.
90 final _dartxVar = new JS.Identifier('dartx'); 89 final _dartxVar = new JS.Identifier('dartx');
91 final _exportsVar = new JS.TemporaryId('exports'); 90 final _exportsVar = new JS.TemporaryId('exports');
92 final _runtimeLibVar = new JS.Identifier('dart'); 91 final _runtimeLibVar = new JS.Identifier('dart');
93 final _namedArgTemp = new JS.TemporaryId('opts'); 92 final _namedArgTemp = new JS.TemporaryId('opts');
94 93
95 ConstFieldVisitor _constField; 94 ConstFieldVisitor _constField;
96 95
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 } 161 }
163 } 162 }
164 } 163 }
165 164
166 // Flush any unwritten fields/properties. 165 // Flush any unwritten fields/properties.
167 _flushLazyFields(_moduleItems); 166 _flushLazyFields(_moduleItems);
168 _flushLibraryProperties(_moduleItems); 167 _flushLibraryProperties(_moduleItems);
169 168
170 // Mark all qualified names as qualified or not, depending on if they need 169 // Mark all qualified names as qualified or not, depending on if they need
171 // to be loaded lazily or not. 170 // to be loaded lazily or not.
172 unqualifyIfNeeded(Element e, JS.MaybeQualifiedId id) { 171 for (var elementIdPairs in _qualifiedIds) {
173 id.setQualified(!_loader.isLoaded(e)); 172 var element = elementIdPairs.e0;
173 var id = elementIdPairs.e1;
174 id.setQualified(!_loader.isLoaded(element));
174 } 175 }
175 _qualifiedIds.forEach(unqualifyIfNeeded);
176 _qualifiedGenericIds.forEach(unqualifyIfNeeded);
177 176
178 if (_exports.isNotEmpty) _moduleItems.add(js.comment('Exports:')); 177 if (_exports.isNotEmpty) _moduleItems.add(js.comment('Exports:'));
179 178
180 // TODO(jmesserly): make these immutable in JS? 179 // TODO(jmesserly): make these immutable in JS?
181 for (var name in _exports) { 180 for (var name in _exports) {
182 _moduleItems.add(js.statement('#.# = #;', [_exportsVar, name, name])); 181 _moduleItems.add(js.statement('#.# = #;', [_exportsVar, name, name]));
183 } 182 }
184 183
185 var jsPath = compiler.getModuleName(currentLibrary.source.uri); 184 var jsPath = compiler.getModuleName(currentLibrary.source.uri);
186 185
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 // type literal 1472 // type literal
1474 if (element is ClassElement || 1473 if (element is ClassElement ||
1475 element is DynamicElementImpl || 1474 element is DynamicElementImpl ||
1476 element is FunctionTypeAliasElement) { 1475 element is FunctionTypeAliasElement) {
1477 return _emitTypeName( 1476 return _emitTypeName(
1478 fillDynamicTypeArgs((element as dynamic).type, types)); 1477 fillDynamicTypeArgs((element as dynamic).type, types));
1479 } 1478 }
1480 1479
1481 // library member 1480 // library member
1482 if (element.enclosingElement is CompilationUnitElement) { 1481 if (element.enclosingElement is CompilationUnitElement) {
1483 return _maybeQualifiedName( 1482 return _maybeQualifiedName(element);
1484 element, _emitMemberName(name, isStatic: true));
1485 } 1483 }
1486 1484
1487 // Unqualified class member. This could mean implicit-this, or implicit 1485 // Unqualified class member. This could mean implicit-this, or implicit
1488 // call to a static from the same class. 1486 // call to a static from the same class.
1489 if (element is ClassMemberElement && element is! ConstructorElement) { 1487 if (element is ClassMemberElement && element is! ConstructorElement) {
1490 bool isStatic = element.isStatic; 1488 bool isStatic = element.isStatic;
1491 var type = element.enclosingElement.type; 1489 var type = element.enclosingElement.type;
1492 var member = _emitMemberName(name, isStatic: isStatic, type: type); 1490 var member = _emitMemberName(name, isStatic: isStatic, type: type);
1493 1491
1494 // For static methods, we add the raw type name, without generics or 1492 // For static methods, we add the raw type name, without generics or
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 Iterable jsArgs = null; 1632 Iterable jsArgs = null;
1635 if (args.any((a) => a != types.dynamicType)) { 1633 if (args.any((a) => a != types.dynamicType)) {
1636 jsArgs = args.map(_emitTypeName); 1634 jsArgs = args.map(_emitTypeName);
1637 } else if (lowerGeneric || isCurrentClass) { 1635 } else if (lowerGeneric || isCurrentClass) {
1638 // When creating a `new S<dynamic>` we try and use the raw form 1636 // When creating a `new S<dynamic>` we try and use the raw form
1639 // `new S()`, but this does not work if we're inside the same class, 1637 // `new S()`, but this does not work if we're inside the same class,
1640 // because `S` refers to the current S<T> we are generating. 1638 // because `S` refers to the current S<T> we are generating.
1641 jsArgs = []; 1639 jsArgs = [];
1642 } 1640 }
1643 if (jsArgs != null) { 1641 if (jsArgs != null) {
1644 var genericName = _maybeQualifiedName( 1642 var genericName = _maybeQualifiedName(element, '$name\$');
1645 element, _propertyName('$name\$'), _qualifiedGenericIds);
1646 return js.call('#(#)', [genericName, jsArgs]); 1643 return js.call('#(#)', [genericName, jsArgs]);
1647 } 1644 }
1648 } 1645 }
1649 1646
1650 return _maybeQualifiedName(element, _propertyName(name)); 1647 return _maybeQualifiedName(element);
1651 } 1648 }
1652 1649
1653 JS.Expression _maybeQualifiedName(Element e, JS.Expression name, 1650 JS.Expression _maybeQualifiedName(Element e, [String name]) {
1654 [Map<Element, JS.MaybeQualifiedId> idTable]) {
1655 var libName = _libraryName(e.library); 1651 var libName = _libraryName(e.library);
1656 if (idTable == null) idTable = _qualifiedIds; 1652 var nameExpr = _propertyName(name ?? e.name);
1657 1653
1658 // Mutable top-level fields should always be qualified. 1654 // Always qualify:
1655 // * mutable top-level fields
1656 // * elements from other libraries
1659 bool mutableTopLevel = e is TopLevelVariableElement && !e.isConst; 1657 bool mutableTopLevel = e is TopLevelVariableElement && !e.isConst;
1660 if (e.library != currentLibrary || mutableTopLevel) { 1658 bool fromAnotherLibrary = e.library != currentLibrary;
1661 return new JS.PropertyAccess(libName, name); 1659 if (mutableTopLevel || fromAnotherLibrary) {
1660 return new JS.PropertyAccess(libName, nameExpr);
1662 } 1661 }
1663 1662
1664 return idTable.putIfAbsent(e, () => new JS.MaybeQualifiedId(libName, name)); 1663 var id = new JS.MaybeQualifiedId(libName, nameExpr);
1664 _qualifiedIds.add(new Tuple2(e, id));
1665 return id;
1665 } 1666 }
1666 1667
1667 @override 1668 @override
1668 JS.Expression visitAssignmentExpression(AssignmentExpression node) { 1669 JS.Expression visitAssignmentExpression(AssignmentExpression node) {
1669 var left = node.leftHandSide; 1670 var left = node.leftHandSide;
1670 var right = node.rightHandSide; 1671 var right = node.rightHandSide;
1671 if (node.operator.type == TokenType.EQ) return _emitSet(left, right); 1672 if (node.operator.type == TokenType.EQ) return _emitSet(left, right);
1672 var op = node.operator.lexeme; 1673 var op = node.operator.lexeme;
1673 assert(op.endsWith('=')); 1674 assert(op.endsWith('='));
1674 op = op.substring(0, op.length - 1); // remove trailing '=' 1675 op = op.substring(0, op.length - 1); // remove trailing '='
(...skipping 1646 matching lines...) Expand 10 before | Expand all | Expand 10 after
3321 3322
3322 /// A special kind of element created by the compiler, signifying a temporary 3323 /// A special kind of element created by the compiler, signifying a temporary
3323 /// variable. These objects use instance equality, and should be shared 3324 /// variable. These objects use instance equality, and should be shared
3324 /// everywhere in the tree where they are treated as the same variable. 3325 /// everywhere in the tree where they are treated as the same variable.
3325 class TemporaryVariableElement extends LocalVariableElementImpl { 3326 class TemporaryVariableElement extends LocalVariableElementImpl {
3326 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 3327 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
3327 3328
3328 int get hashCode => identityHashCode(this); 3329 int get hashCode => identityHashCode(this);
3329 bool operator ==(Object other) => identical(this, other); 3330 bool operator ==(Object other) => identical(this, other);
3330 } 3331 }
OLDNEW
« no previous file with comments | « no previous file | tool/sdk_expected_errors.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698