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

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

Issue 1979013003: fix #569, cache constants defined in methods (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
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 23 matching lines...) Expand all
34 show BuildUnit, CompilerOptions, JSModuleFile, ModuleFormat; 34 show BuildUnit, CompilerOptions, JSModuleFile, ModuleFormat;
35 import 'element_helpers.dart'; 35 import 'element_helpers.dart';
36 import 'element_loader.dart' show ElementLoader; 36 import 'element_loader.dart' show ElementLoader;
37 import 'extension_types.dart' show ExtensionTypeSet; 37 import 'extension_types.dart' show ExtensionTypeSet;
38 import 'js_field_storage.dart' show checkForPropertyOverride, getSuperclasses; 38 import 'js_field_storage.dart' show checkForPropertyOverride, getSuperclasses;
39 import 'js_interop.dart'; 39 import 'js_interop.dart';
40 import 'js_metalet.dart' as JS; 40 import 'js_metalet.dart' as JS;
41 import 'js_names.dart' as JS; 41 import 'js_names.dart' as JS;
42 import 'js_typeref_codegen.dart' show JsTypeRefCodegen; 42 import 'js_typeref_codegen.dart' show JsTypeRefCodegen;
43 import 'module_builder.dart' 43 import 'module_builder.dart'
44 show LegacyModuleBuilder, NodeModuleBuilder, pathToJSIdentifier; 44 show
45 LegacyModuleBuilder,
46 NodeModuleBuilder,
47 pathToJSIdentifier,
48 toJSIdentifier;
45 import 'nullable_type_inference.dart' show NullableTypeInference; 49 import 'nullable_type_inference.dart' show NullableTypeInference;
46 import 'reify_coercions.dart' show CoercionReifier; 50 import 'reify_coercions.dart' show CoercionReifier;
47 import 'side_effect_analysis.dart' show ConstFieldVisitor, isStateless; 51 import 'side_effect_analysis.dart' show ConstFieldVisitor, isStateless;
48 import 'source_map_printer.dart' show SourceMapPrintingContext; 52 import 'source_map_printer.dart' show SourceMapPrintingContext;
49 53
50 class CodeGenerator extends GeneralizingAstVisitor 54 class CodeGenerator extends GeneralizingAstVisitor
51 with ClosureAnnotator, JsTypeRefCodegen, NullableTypeInference { 55 with ClosureAnnotator, JsTypeRefCodegen, NullableTypeInference {
52 final AnalysisContext context; 56 final AnalysisContext context;
53 final CompilerOptions options; 57 final CompilerOptions options;
54 final rules = new StrongTypeSystemImpl(); 58 final rules = new StrongTypeSystemImpl();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 121
118 BuildUnit _buildUnit; 122 BuildUnit _buildUnit;
119 123
120 String _buildRoot; 124 String _buildRoot;
121 125
122 bool _superAllowed = true; 126 bool _superAllowed = true;
123 127
124 List<JS.TemporaryId> _superHelperSymbols = <JS.TemporaryId>[]; 128 List<JS.TemporaryId> _superHelperSymbols = <JS.TemporaryId>[];
125 List<JS.Method> _superHelpers = <JS.Method>[]; 129 List<JS.Method> _superHelpers = <JS.Method>[];
126 130
131 List<TypeParameterType> _typeParamInConst = null;
132
127 /// Whether we are currently generating code for the body of a `JS()` call. 133 /// Whether we are currently generating code for the body of a `JS()` call.
128 bool _isInForeignJS = false; 134 bool _isInForeignJS = false;
129 135
130 CodeGenerator(AnalysisContext c, this.options, this._extensionTypes) 136 CodeGenerator(AnalysisContext c, this.options, this._extensionTypes)
131 : context = c, 137 : context = c,
132 types = c.typeProvider, 138 types = c.typeProvider,
133 _asyncStreamIterator = 139 _asyncStreamIterator =
134 _getLibrary(c, 'dart:async').getType('StreamIterator').type, 140 _getLibrary(c, 'dart:async').getType('StreamIterator').type,
135 _jsArray = _getLibrary(c, 'dart:_interceptors').getType('JSArray'), 141 _jsArray = _getLibrary(c, 'dart:_interceptors').getType('JSArray'),
136 dartCoreLibrary = _getLibrary(c, 'dart:core'), 142 dartCoreLibrary = _getLibrary(c, 'dart:core'),
(...skipping 2155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2292 if (name == '' || name == null || lowerTypedef) { 2298 if (name == '' || name == null || lowerTypedef) {
2293 // TODO(jmesserly): should we change how typedefs work? They currently 2299 // TODO(jmesserly): should we change how typedefs work? They currently
2294 // go through use similar logic as generic classes. This makes them 2300 // go through use similar logic as generic classes. This makes them
2295 // different from universal function types. 2301 // different from universal function types.
2296 var ft = type as FunctionType; 2302 var ft = type as FunctionType;
2297 var parts = _emitFunctionTypeParts(ft, lowerTypedef: lowerTypedef); 2303 var parts = _emitFunctionTypeParts(ft, lowerTypedef: lowerTypedef);
2298 return js.call('dart.functionType(#)', [parts]); 2304 return js.call('dart.functionType(#)', [parts]);
2299 } 2305 }
2300 2306
2301 if (type is TypeParameterType) { 2307 if (type is TypeParameterType) {
2308 _typeParamInConst?.add(type);
2302 return new JS.Identifier(name); 2309 return new JS.Identifier(name);
2303 } 2310 }
2304 2311
2305 if (type == subClass?.type) { 2312 if (type == subClass?.type) {
2306 return className; 2313 return className;
2307 } 2314 }
2308 2315
2309 if (type is ParameterizedType) { 2316 if (type is ParameterizedType) {
2310 var args = type.typeArguments; 2317 var args = type.typeArguments;
2311 Iterable jsArgs = null; 2318 Iterable jsArgs = null;
(...skipping 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after
3378 variable ??= new JS.TemporaryId(name); 3385 variable ??= new JS.TemporaryId(name);
3379 3386
3380 id.staticElement = new TemporaryVariableElement.forNode(id, variable); 3387 id.staticElement = new TemporaryVariableElement.forNode(id, variable);
3381 id.staticType = type; 3388 id.staticType = type;
3382 DynamicInvoke.set(id, type.isDynamic); 3389 DynamicInvoke.set(id, type.isDynamic);
3383 addTemporaryVariable(id.staticElement, nullable: nullable); 3390 addTemporaryVariable(id.staticElement, nullable: nullable);
3384 return id; 3391 return id;
3385 } 3392 }
3386 3393
3387 JS.Expression _emitConst(JS.Expression expr()) { 3394 JS.Expression _emitConst(JS.Expression expr()) {
3388 // TODO(jmesserly): emit the constants at top level if possible. 3395 var savedTypeParams = _typeParamInConst;
3389 // This wasn't quite working, so disabled for now. 3396 _typeParamInConst = [];
3390 return js.call('dart.const(#)', expr()); 3397
3398 var jsExpr = js.call('dart.const(#)', expr());
3399
3400 bool usesTypeParams = _typeParamInConst.isNotEmpty;
3401 _typeParamInConst = savedTypeParams;
3402
3403 // TODO(jmesserly): if it uses type params we can still hoist it up as far
3404 // as it will go, e.g. at the level the generic class is defined where type
3405 // params are available.
3406 if (_currentFunction == null || usesTypeParams) return jsExpr;
3407
3408 var temp = new JS.TemporaryId('const');
3409 _moduleItems.add(js.statement('let #;', [temp]));
3410 return js.call('# || (# = #)', [temp, temp, jsExpr]);
3391 } 3411 }
3392 3412
3393 /// Returns a new expression, which can be be used safely *once* on the 3413 /// Returns a new expression, which can be be used safely *once* on the
3394 /// left hand side, and *once* on the right side of an assignment. 3414 /// left hand side, and *once* on the right side of an assignment.
3395 /// For example: `expr1[expr2] += y` can be compiled as 3415 /// For example: `expr1[expr2] += y` can be compiled as
3396 /// `expr1[expr2] = expr1[expr2] + y`. 3416 /// `expr1[expr2] = expr1[expr2] + y`.
3397 /// 3417 ///
3398 /// The temporary scope will ensure `expr1` and `expr2` are only evaluated 3418 /// The temporary scope will ensure `expr1` and `expr2` are only evaluated
3399 /// once: `((x1, x2) => x1[x2] = x1[x2] + y)(expr1, expr2)`. 3419 /// once: `((x1, x2) => x1[x2] = x1[x2] + y)(expr1, expr2)`.
3400 /// 3420 ///
(...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after
4464 } 4484 }
4465 4485
4466 bool isLibraryPrefix(Expression node) => 4486 bool isLibraryPrefix(Expression node) =>
4467 node is SimpleIdentifier && node.staticElement is PrefixElement; 4487 node is SimpleIdentifier && node.staticElement is PrefixElement;
4468 4488
4469 LibraryElement _getLibrary(AnalysisContext c, String uri) => 4489 LibraryElement _getLibrary(AnalysisContext c, String uri) =>
4470 c.computeLibraryElement(c.sourceFactory.forUri(uri)); 4490 c.computeLibraryElement(c.sourceFactory.forUri(uri));
4471 4491
4472 bool _isDartRuntime(LibraryElement l) => 4492 bool _isDartRuntime(LibraryElement l) =>
4473 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; 4493 l.isInSdk && l.source.uri.toString() == 'dart:_runtime';
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698