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

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

Issue 1958193002: optimize self-references in generic type definitions (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 | « no previous file | test/codegen/language/generic_self_reference_test.dart » ('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 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 } 1044 }
1045 1045
1046 void _setBaseClass(ClassElement classElem, JS.Expression className, 1046 void _setBaseClass(ClassElement classElem, JS.Expression className,
1047 List<JS.Statement> body) { 1047 List<JS.Statement> body) {
1048 String jsPeerName = _getJSPeerName(classElem); 1048 String jsPeerName = _getJSPeerName(classElem);
1049 JS.Expression newBaseClass; 1049 JS.Expression newBaseClass;
1050 if (jsPeerName != null && classElem.typeParameters.isNotEmpty) { 1050 if (jsPeerName != null && classElem.typeParameters.isNotEmpty) {
1051 // TODO(jmesserly): we should really just extend Array in the first place. 1051 // TODO(jmesserly): we should really just extend Array in the first place.
1052 newBaseClass = js.call('dart.global.#', [jsPeerName]); 1052 newBaseClass = js.call('dart.global.#', [jsPeerName]);
1053 } else if (_hasDeferredSupertype.contains(classElem)) { 1053 } else if (_hasDeferredSupertype.contains(classElem)) {
1054 newBaseClass = _emitTypeName(classElem.type.superclass); 1054 newBaseClass = _emitTypeName(classElem.type.superclass,
1055 subClass: classElem, className: className);
1055 } 1056 }
1056 if (newBaseClass != null) { 1057 if (newBaseClass != null) {
1057 body.add( 1058 body.add(
1058 js.statement('dart.setBaseClass(#, #);', [className, newBaseClass])); 1059 js.statement('dart.setBaseClass(#, #);', [className, newBaseClass]));
1059 } 1060 }
1060 } 1061 }
1061 1062
1062 void _defineNamedConstructors(List<ConstructorDeclaration> ctors, 1063 void _defineNamedConstructors(List<ConstructorDeclaration> ctors,
1063 List<JS.Statement> body, JS.Expression className) { 1064 List<JS.Statement> body, JS.Expression className) {
1064 for (ConstructorDeclaration member in ctors) { 1065 for (ConstructorDeclaration member in ctors) {
(...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2214 } 2215 }
2215 return typeParts; 2216 return typeParts;
2216 } 2217 }
2217 2218
2218 /// Emits a Dart [type] into code. 2219 /// Emits a Dart [type] into code.
2219 /// 2220 ///
2220 /// If [lowerTypedef] is set, a typedef will be expanded as if it were a 2221 /// If [lowerTypedef] is set, a typedef will be expanded as if it were a
2221 /// function type. Similarly if [lowerGeneric] is set, the `List$()` form 2222 /// function type. Similarly if [lowerGeneric] is set, the `List$()` form
2222 /// will be used instead of `List`. These flags are used when generating 2223 /// will be used instead of `List`. These flags are used when generating
2223 /// the definitions for typedefs and generic types, respectively. 2224 /// the definitions for typedefs and generic types, respectively.
2225 ///
2226 /// If [subClass] is set, then we are setting the base class for the given
2227 /// class and should emit the given [className], which will already be
2228 /// defined.
2224 JS.Expression _emitTypeName(DartType type, 2229 JS.Expression _emitTypeName(DartType type,
2225 {bool lowerTypedef: false, bool lowerGeneric: false}) { 2230 {bool lowerTypedef: false,
2231 bool lowerGeneric: false,
2232 ClassElement subClass,
Harry Terkelsen 2016/05/09 18:04:19 had to add 2 named args just for this one case :(
Jennifer Messerly 2016/05/09 18:16:36 Hmmm. You could pass it down as a function from `(
2233 JS.Expression className}) {
2226 // The void and dynamic types are not defined in core. 2234 // The void and dynamic types are not defined in core.
2227 if (type.isVoid) { 2235 if (type.isVoid) {
2228 return js.call('dart.void'); 2236 return js.call('dart.void');
2229 } else if (type.isDynamic) { 2237 } else if (type.isDynamic) {
2230 return js.call('dart.dynamic'); 2238 return js.call('dart.dynamic');
2231 } else if (type.isBottom) { 2239 } else if (type.isBottom) {
2232 return js.call('dart.bottom'); 2240 return js.call('dart.bottom');
2233 } 2241 }
2234 2242
2235 _loader.declareBeforeUse(type.element); 2243 _loader.declareBeforeUse(type.element);
2236 2244
2237 // TODO(jmesserly): like constants, should we hoist function types out of 2245 // TODO(jmesserly): like constants, should we hoist function types out of
2238 // methods? Similar issue with generic types. For all of these, we may want 2246 // methods? Similar issue with generic types. For all of these, we may want
2239 // to canonicalize them too, at least when inside the same library. 2247 // to canonicalize them too, at least when inside the same library.
2240 var name = type.name; 2248 var name = type.name;
2241 var element = type.element; 2249 var element = type.element;
2242 if (name == '' || name == null || lowerTypedef) { 2250 if (name == '' || name == null || lowerTypedef) {
2243 // TODO(jmesserly): should we change how typedefs work? They currently 2251 // TODO(jmesserly): should we change how typedefs work? They currently
2244 // go through use similar logic as generic classes. This makes them 2252 // go through use similar logic as generic classes. This makes them
2245 // different from universal function types. 2253 // different from universal function types.
2246 var ft = type as FunctionType; 2254 var ft = type as FunctionType;
2247 var parts = _emitFunctionTypeParts(ft, lowerTypedef: lowerTypedef); 2255 var parts = _emitFunctionTypeParts(ft, lowerTypedef: lowerTypedef);
2248 return js.call('dart.functionType(#)', [parts]); 2256 return js.call('dart.functionType(#)', [parts]);
2249 } 2257 }
2250 2258
2251 if (type is TypeParameterType) { 2259 if (type is TypeParameterType) {
2252 return new JS.Identifier(name); 2260 return new JS.Identifier(name);
2253 } 2261 }
2254 2262
2263 if (type == subClass?.type) {
2264 return className;
2265 }
2266
2255 if (type is ParameterizedType) { 2267 if (type is ParameterizedType) {
2256 var args = type.typeArguments; 2268 var args = type.typeArguments;
2257 Iterable jsArgs = null; 2269 Iterable jsArgs = null;
2258 if (args.any((a) => !a.isDynamic)) { 2270 if (args.any((a) => !a.isDynamic)) {
2259 jsArgs = args.map(_emitTypeName); 2271 jsArgs = args.map(
2272 (x) => _emitTypeName(x, subClass: subClass, className: className));
2260 } else if (lowerGeneric) { 2273 } else if (lowerGeneric) {
2261 jsArgs = []; 2274 jsArgs = [];
2262 } 2275 }
2263 if (jsArgs != null) { 2276 if (jsArgs != null) {
2264 var genericName = _emitTopLevelName(element, suffix: '\$'); 2277 var genericName = _emitTopLevelName(element, suffix: '\$');
2265 return js.call('#(#)', [genericName, jsArgs]); 2278 return js.call('#(#)', [genericName, jsArgs]);
2266 } 2279 }
2267 } 2280 }
2268 2281
2269 return _emitTopLevelName(element); 2282 return _emitTopLevelName(element);
(...skipping 2124 matching lines...) Expand 10 before | Expand all | Expand 10 after
4394 } 4407 }
4395 4408
4396 bool isLibraryPrefix(Expression node) => 4409 bool isLibraryPrefix(Expression node) =>
4397 node is SimpleIdentifier && node.staticElement is PrefixElement; 4410 node is SimpleIdentifier && node.staticElement is PrefixElement;
4398 4411
4399 LibraryElement _getLibrary(AnalysisContext c, String uri) => 4412 LibraryElement _getLibrary(AnalysisContext c, String uri) =>
4400 c.computeLibraryElement(c.sourceFactory.forUri(uri)); 4413 c.computeLibraryElement(c.sourceFactory.forUri(uri));
4401 4414
4402 bool _isDartRuntime(LibraryElement l) => 4415 bool _isDartRuntime(LibraryElement l) =>
4403 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; 4416 l.isInSdk && l.source.uri.toString() == 'dart:_runtime';
OLDNEW
« no previous file with comments | « no previous file | test/codegen/language/generic_self_reference_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698