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

Side by Side Diff: lib/src/compiler/code_generator.dart

Issue 1976383002: enable top-level @JS() getters (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 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_sdk.js ('k') | test/browser/language_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 import 'dart:collection' show HashMap, HashSet; 5 import 'dart:collection' show HashMap, HashSet;
6 import 'dart:math' show min, max; 6 import 'dart:math' show min, max;
7 7
8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
9 import 'package:analyzer/dart/ast/ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 /// Usually a [SimpleIdentifier], but it can also be other expressions 74 /// Usually a [SimpleIdentifier], but it can also be other expressions
75 /// that are safe to evaluate multiple times, such as `this`. 75 /// that are safe to evaluate multiple times, such as `this`.
76 Expression _cascadeTarget; 76 Expression _cascadeTarget;
77 77
78 /// The variable for the current catch clause 78 /// The variable for the current catch clause
79 SimpleIdentifier _catchParameter; 79 SimpleIdentifier _catchParameter;
80 80
81 /// In an async* function, this represents the stream controller parameter. 81 /// In an async* function, this represents the stream controller parameter.
82 JS.TemporaryId _asyncStarController; 82 JS.TemporaryId _asyncStarController;
83 83
84 /// The top-level reference to 'self' if this is a library tagged with @JS()
85 JS.TemporaryId _self;
86
84 final _privateNames = 87 final _privateNames =
85 new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>(); 88 new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>();
86 final _initializingFormalTemps = 89 final _initializingFormalTemps =
87 new HashMap<ParameterElement, JS.TemporaryId>(); 90 new HashMap<ParameterElement, JS.TemporaryId>();
88 91
89 final _dartxVar = new JS.Identifier('dartx'); 92 final _dartxVar = new JS.Identifier('dartx');
90 final _runtimeLibVar = new JS.Identifier('dart'); 93 final _runtimeLibVar = new JS.Identifier('dart');
91 final namedArgumentTemp = new JS.TemporaryId('opts'); 94 final namedArgumentTemp = new JS.TemporaryId('opts');
92 95
93 final _hasDeferredSupertype = new HashSet<ClassElement>(); 96 final _hasDeferredSupertype = new HashSet<ClassElement>();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 _libraries[library] = libraryTemp; 215 _libraries[library] = libraryTemp;
213 items.add(new JS.ExportDeclaration( 216 items.add(new JS.ExportDeclaration(
214 js.call('const # = Object.create(null)', [libraryTemp]))); 217 js.call('const # = Object.create(null)', [libraryTemp])));
215 218
216 // dart:_runtime has a magic module that holds extenstion method symbols. 219 // dart:_runtime has a magic module that holds extenstion method symbols.
217 // TODO(jmesserly): find a cleaner design for this. 220 // TODO(jmesserly): find a cleaner design for this.
218 if (_isDartRuntime(library)) { 221 if (_isDartRuntime(library)) {
219 items.add(new JS.ExportDeclaration( 222 items.add(new JS.ExportDeclaration(
220 js.call('const # = Object.create(null)', [_dartxVar]))); 223 js.call('const # = Object.create(null)', [_dartxVar])));
221 } 224 }
225
226 if (findAnnotation(library, isPublicJSAnnotation) != null) {
227 _self = new JS.TemporaryId('self');
228 items.add(js.statement('const # = window;', [_self]));
229 }
222 } 230 }
223 231
224 // Collect all Element -> Node mappings, in case we need to forward declare 232 // Collect all Element -> Node mappings, in case we need to forward declare
225 // any nodes. 233 // any nodes.
226 var nodes = new HashMap<Element, AstNode>.identity(); 234 var nodes = new HashMap<Element, AstNode>.identity();
227 var sdkBootstrappingFns = new List<FunctionElement>(); 235 var sdkBootstrappingFns = new List<FunctionElement>();
228 for (var unit in compilationUnits) { 236 for (var unit in compilationUnits) {
229 if (_isDartRuntime(unit.element.library)) { 237 if (_isDartRuntime(unit.element.library)) {
230 sdkBootstrappingFns.addAll(unit.element.functions); 238 sdkBootstrappingFns.addAll(unit.element.functions);
231 } 239 }
(...skipping 2086 matching lines...) Expand 10 before | Expand all | Expand 10 after
2318 if (jsArgs != null) { 2326 if (jsArgs != null) {
2319 var genericName = _emitTopLevelName(element, suffix: '\$'); 2327 var genericName = _emitTopLevelName(element, suffix: '\$');
2320 return js.call('#(#)', [genericName, jsArgs]); 2328 return js.call('#(#)', [genericName, jsArgs]);
2321 } 2329 }
2322 } 2330 }
2323 2331
2324 return _emitTopLevelName(element); 2332 return _emitTopLevelName(element);
2325 } 2333 }
2326 2334
2327 JS.PropertyAccess _emitTopLevelName(Element e, {String suffix: ''}) { 2335 JS.PropertyAccess _emitTopLevelName(Element e, {String suffix: ''}) {
2336 if (e is TopLevelVariableElement &&
2337 e.getter != null &&
2338 findAnnotation(e.getter, isPublicJSAnnotation) != null) {
2339 var annotationName = getAnnotationName(e.getter, isPublicJSAnnotation);
2340 var name = js.string(annotationName ?? e.name);
2341 return new JS.PropertyAccess(_self, name);
2342 }
2328 String name = getJSExportName(e) + suffix; 2343 String name = getJSExportName(e) + suffix;
2329 return new JS.PropertyAccess( 2344 return new JS.PropertyAccess(
2330 emitLibraryName(e.library), _propertyName(name)); 2345 emitLibraryName(e.library), _propertyName(name));
2331 } 2346 }
2332 2347
2333 @override 2348 @override
2334 JS.Expression visitAssignmentExpression(AssignmentExpression node) { 2349 JS.Expression visitAssignmentExpression(AssignmentExpression node) {
2335 var left = node.leftHandSide; 2350 var left = node.leftHandSide;
2336 var right = node.rightHandSide; 2351 var right = node.rightHandSide;
2337 if (node.operator.type == TokenType.EQ) return _emitSet(left, right); 2352 if (node.operator.type == TokenType.EQ) return _emitSet(left, right);
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
2518 MethodInvocation node, 2533 MethodInvocation node,
2519 List<JS.Expression> args, 2534 List<JS.Expression> args,
2520 List<JS.Expression> typeArgs) { 2535 List<JS.Expression> typeArgs) {
2521 var type = getStaticType(target); 2536 var type = getStaticType(target);
2522 var name = node.methodName.name; 2537 var name = node.methodName.name;
2523 var element = node.methodName.staticElement; 2538 var element = node.methodName.staticElement;
2524 bool isStatic = element is ExecutableElement && element.isStatic; 2539 bool isStatic = element is ExecutableElement && element.isStatic;
2525 var memberName = _emitMemberName(name, type: type, isStatic: isStatic); 2540 var memberName = _emitMemberName(name, type: type, isStatic: isStatic);
2526 2541
2527 JS.Expression jsTarget = _visit(target); 2542 JS.Expression jsTarget = _visit(target);
2528 if (DynamicInvoke.get(target)) { 2543 if (DynamicInvoke.get(target) || DynamicInvoke.get(node.methodName)) {
2529 if (typeArgs != null) { 2544 if (typeArgs != null) {
2530 return js.call('dart.dgsend(#, #, #, #)', 2545 return js.call('dart.dgsend(#, #, #, #)',
2531 [jsTarget, new JS.ArrayInitializer(typeArgs), memberName, args]); 2546 [jsTarget, new JS.ArrayInitializer(typeArgs), memberName, args]);
2532 } else { 2547 } else {
2533 return js.call('dart.dsend(#, #, #)', [jsTarget, memberName, args]); 2548 return js.call('dart.dsend(#, #, #)', [jsTarget, memberName, args]);
2534 } 2549 }
2535 } 2550 }
2536 if (_isObjectMemberCall(target, name)) { 2551 if (_isObjectMemberCall(target, name)) {
2537 assert(typeArgs == null); // Object methods don't take type args. 2552 assert(typeArgs == null); // Object methods don't take type args.
2538 return js.call('dart.#(#, #)', [name, jsTarget, args]); 2553 return js.call('dart.#(#, #)', [name, jsTarget, args]);
2539 } 2554 }
2540 2555
2541 jsTarget = new JS.PropertyAccess(jsTarget, memberName); 2556 jsTarget = new JS.PropertyAccess(jsTarget, memberName);
2542
2543 if (typeArgs != null) jsTarget = new JS.Call(jsTarget, typeArgs); 2557 if (typeArgs != null) jsTarget = new JS.Call(jsTarget, typeArgs);
2544 2558
2545 if (DynamicInvoke.get(node.methodName)) {
2546 // This is a dynamic call to a statically known target. For example:
2547 // class Foo { Function bar; }
2548 // new Foo().bar(); // dynamic call
2549 return js.call('dart.dcall(#, #)', [jsTarget, args]);
2550 }
2551
2552 return new JS.Call(jsTarget, args); 2559 return new JS.Call(jsTarget, args);
2553 } 2560 }
2554 2561
2555 /// Emits a function call, to a top-level function, local function, or 2562 /// Emits a function call, to a top-level function, local function, or
2556 /// an expression. 2563 /// an expression.
2557 JS.Expression _emitFunctionCall(InvocationExpression node) { 2564 JS.Expression _emitFunctionCall(InvocationExpression node) {
2558 var fn = _visit(node.function); 2565 var fn = _visit(node.function);
2559 var args = _visit(node.argumentList); 2566 var args = _visit(node.argumentList);
2560 if (DynamicInvoke.get(node.function)) { 2567 if (DynamicInvoke.get(node.function)) {
2561 var typeArgs = _emitInvokeTypeArguments(node); 2568 var typeArgs = _emitInvokeTypeArguments(node);
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
3020 } 3027 }
3021 return null; 3028 return null;
3022 } 3029 }
3023 3030
3024 JS.Expression _emitConstructorName( 3031 JS.Expression _emitConstructorName(
3025 ConstructorElement element, DartType type, SimpleIdentifier name) { 3032 ConstructorElement element, DartType type, SimpleIdentifier name) {
3026 var classElem = element.enclosingElement; 3033 var classElem = element.enclosingElement;
3027 if (findAnnotation(classElem, isPublicJSAnnotation) != null) { 3034 if (findAnnotation(classElem, isPublicJSAnnotation) != null) {
3028 var annotationName = getAnnotationName(classElem, isPublicJSAnnotation); 3035 var annotationName = getAnnotationName(classElem, isPublicJSAnnotation);
3029 var typeName = js.string(annotationName ?? classElem.name); 3036 var typeName = js.string(annotationName ?? classElem.name);
3030 return new JS.PropertyAccess(new JS.Identifier('self'), typeName); 3037 return new JS.PropertyAccess(_self, typeName);
3031 } 3038 }
3032 var typeName = _emitType(type); 3039 var typeName = _emitType(type);
3033 if (name != null || element.isFactory) { 3040 if (name != null || element.isFactory) {
3034 var namedCtor = _constructorName(element); 3041 var namedCtor = _constructorName(element);
3035 return new JS.PropertyAccess(typeName, namedCtor); 3042 return new JS.PropertyAccess(typeName, namedCtor);
3036 } 3043 }
3037 return typeName; 3044 return typeName;
3038 } 3045 }
3039 3046
3040 @override 3047 @override
(...skipping 1423 matching lines...) Expand 10 before | Expand all | Expand 10 after
4464 } 4471 }
4465 4472
4466 bool isLibraryPrefix(Expression node) => 4473 bool isLibraryPrefix(Expression node) =>
4467 node is SimpleIdentifier && node.staticElement is PrefixElement; 4474 node is SimpleIdentifier && node.staticElement is PrefixElement;
4468 4475
4469 LibraryElement _getLibrary(AnalysisContext c, String uri) => 4476 LibraryElement _getLibrary(AnalysisContext c, String uri) =>
4470 c.computeLibraryElement(c.sourceFactory.forUri(uri)); 4477 c.computeLibraryElement(c.sourceFactory.forUri(uri));
4471 4478
4472 bool _isDartRuntime(LibraryElement l) => 4479 bool _isDartRuntime(LibraryElement l) =>
4473 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; 4480 l.isInSdk && l.source.uri.toString() == 'dart:_runtime';
OLDNEW
« no previous file with comments | « lib/runtime/dart_sdk.js ('k') | test/browser/language_tests.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698