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

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

Issue 1530563003: Generate all runtime files from dart. (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: merged master Created 4 years, 11 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/typed_data.js ('k') | lib/src/compiler.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 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 21 matching lines...) Expand all
32 32
33 import 'code_generator.dart'; 33 import 'code_generator.dart';
34 import 'js_field_storage.dart'; 34 import 'js_field_storage.dart';
35 import 'js_interop.dart'; 35 import 'js_interop.dart';
36 import 'js_names.dart' as JS; 36 import 'js_names.dart' as JS;
37 import 'js_metalet.dart' as JS; 37 import 'js_metalet.dart' as JS;
38 import 'js_module_item_order.dart'; 38 import 'js_module_item_order.dart';
39 import 'js_names.dart'; 39 import 'js_names.dart';
40 import 'js_printer.dart' show writeJsLibrary; 40 import 'js_printer.dart' show writeJsLibrary;
41 import 'side_effect_analysis.dart'; 41 import 'side_effect_analysis.dart';
42 import 'package:collection/equality.dart';
43 42
44 // Various dynamic helpers we call. 43 // Various dynamic helpers we call.
45 // If renaming these, make sure to check other places like the 44 // If renaming these, make sure to check other places like the
46 // _runtime.js file and comments. 45 // _runtime.js file and comments.
47 // TODO(jmesserly): ideally we'd have a "dynamic call" dart library we can 46 // TODO(jmesserly): ideally we'd have a "dynamic call" dart library we can
48 // import and generate calls to, rather than dart_runtime.js 47 // import and generate calls to, rather than dart_runtime.js
49 const DPUT = 'dput'; 48 const DPUT = 'dput';
50 const DLOAD = 'dload'; 49 const DLOAD = 'dload';
51 const DINDEX = 'dindex'; 50 const DINDEX = 'dindex';
52 const DSETINDEX = 'dsetindex'; 51 const DSETINDEX = 'dsetindex';
53 const DCALL = 'dcall'; 52 const DCALL = 'dcall';
54 const DSEND = 'dsend'; 53 const DSEND = 'dsend';
55 54
56 const ListEquality _listEquality = const ListEquality();
57
58 class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { 55 class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
59 final AbstractCompiler compiler; 56 final AbstractCompiler compiler;
60 final CodegenOptions options; 57 final CodegenOptions options;
61 final LibraryElement currentLibrary; 58 final LibraryElement currentLibrary;
62 final StrongTypeSystemImpl rules; 59 final StrongTypeSystemImpl rules;
63 60
64 /// The global extension type table. 61 /// The global extension type table.
65 final HashSet<ClassElement> _extensionTypes; 62 final HashSet<ClassElement> _extensionTypes;
66 63
67 /// Information that is precomputed for this library, indicates which fields 64 /// Information that is precomputed for this library, indicates which fields
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 ConstFieldVisitor _constField; 99 ConstFieldVisitor _constField;
103 100
104 ModuleItemLoadOrder _loader; 101 ModuleItemLoadOrder _loader;
105 102
106 /// _interceptors.JSArray<E>, used for List literals. 103 /// _interceptors.JSArray<E>, used for List literals.
107 ClassElement _jsArray; 104 ClassElement _jsArray;
108 105
109 /// The default value of the module object. See [visitLibraryDirective]. 106 /// The default value of the module object. See [visitLibraryDirective].
110 String _jsModuleValue; 107 String _jsModuleValue;
111 108
112 bool _isDartUtils; 109 bool _isDartRuntime;
113 110
114 JSCodegenVisitor(AbstractCompiler compiler, this.rules, this.currentLibrary, 111 JSCodegenVisitor(AbstractCompiler compiler, this.rules, this.currentLibrary,
115 this._extensionTypes, this._fieldsNeedingStorage) 112 this._extensionTypes, this._fieldsNeedingStorage)
116 : compiler = compiler, 113 : compiler = compiler,
117 options = compiler.options.codegenOptions, 114 options = compiler.options.codegenOptions,
118 _types = compiler.context.typeProvider { 115 _types = compiler.context.typeProvider {
119 _loader = new ModuleItemLoadOrder(_emitModuleItem); 116 _loader = new ModuleItemLoadOrder(_emitModuleItem);
120 117
121 var context = compiler.context; 118 var context = compiler.context;
122 var src = context.sourceFactory.forUri('dart:_interceptors'); 119 var src = context.sourceFactory.forUri('dart:_interceptors');
123 var interceptors = context.computeLibraryElement(src); 120 var interceptors = context.computeLibraryElement(src);
124 _jsArray = interceptors.getType('JSArray'); 121 _jsArray = interceptors.getType('JSArray');
125 _isDartUtils = currentLibrary.source.uri.toString() == 'dart:_utils'; 122 _isDartRuntime = currentLibrary.source.uri.toString() == 'dart:_runtime';
126 } 123 }
127 124
128 TypeProvider get types => _types; 125 TypeProvider get types => _types;
129 126
130 JS.Program emitLibrary(LibraryUnit library) { 127 JS.Program emitLibrary(LibraryUnit library) {
131 // Modify the AST to make coercions explicit. 128 // Modify the AST to make coercions explicit.
132 new CoercionReifier(library, rules).reify(); 129 new CoercionReifier(library, rules).reify();
133 130
134 // Build the public namespace for this library. This allows us to do 131 // Build the public namespace for this library. This allows us to do
135 // constant time lookups (contrast with `Element.getChild(name)`). 132 // constant time lookups (contrast with `Element.getChild(name)`).
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 // TODO(jmesserly): make these immutable in JS? 183 // TODO(jmesserly): make these immutable in JS?
187 for (var name in _exports) { 184 for (var name in _exports) {
188 _moduleItems.add(js.statement('#.# = #;', [_exportsVar, name, name])); 185 _moduleItems.add(js.statement('#.# = #;', [_exportsVar, name, name]));
189 } 186 }
190 187
191 var jsPath = compiler.getModuleName(currentLibrary.source.uri); 188 var jsPath = compiler.getModuleName(currentLibrary.source.uri);
192 189
193 // TODO(jmesserly): it would be great to run the renamer on the body, 190 // TODO(jmesserly): it would be great to run the renamer on the body,
194 // then figure out if we really need each of these parameters. 191 // then figure out if we really need each of these parameters.
195 // See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34 192 // See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34
196 var params = [_exportsVar, _runtimeLibVar]; 193 var params = [_exportsVar];
197 var processImport = 194 var lazyParams = [];
198 (LibraryElement library, JS.TemporaryId temp, List list) {
199 params.add(temp);
200 list.add(js.string(compiler.getModuleName(library.source.uri), "'"));
201 };
202
203 var needsDartRuntime = !_isDartUtils;
204 195
205 var imports = <JS.Expression>[]; 196 var imports = <JS.Expression>[];
197 var lazyImports = <JS.Expression>[];
206 var moduleStatements = <JS.Statement>[]; 198 var moduleStatements = <JS.Statement>[];
207 if (needsDartRuntime) { 199
208 imports.add(js.string('dart/_runtime')); 200 addImport(String name, JS.Expression libVar, {bool lazy: false}) {
201 (lazy ? lazyImports : imports).add(js.string(name, "'"));
202 (lazy ? lazyParams : params).add(libVar);
203 }
204
205 if (!_isDartRuntime) {
206 addImport('dart/_runtime', _runtimeLibVar);
209 207
210 var dartxImport = 208 var dartxImport =
211 js.statement("let # = #.dartx;", [_dartxVar, _runtimeLibVar]); 209 js.statement("let # = #.dartx;", [_dartxVar, _runtimeLibVar]);
212 moduleStatements.add(dartxImport); 210 moduleStatements.add(dartxImport);
213 } 211 }
212 _imports.forEach((LibraryElement lib, JS.TemporaryId temp) {
213 addImport(compiler.getModuleName(lib.source.uri), temp,
214 lazy: _isDartRuntime || !_loader.libraryIsLoaded(lib));
215 });
216 params.addAll(lazyParams);
217
214 moduleStatements.addAll(_moduleItems); 218 moduleStatements.addAll(_moduleItems);
215 219
216 _imports.forEach((library, temp) {
217 if (_loader.libraryIsLoaded(library)) {
218 processImport(library, temp, imports);
219 }
220 });
221
222 var lazyImports = <JS.Expression>[];
223 _imports.forEach((library, temp) {
224 if (!_loader.libraryIsLoaded(library)) {
225 processImport(library, temp, lazyImports);
226 }
227 });
228
229 var module = 220 var module =
230 js.call("function(#) { 'use strict'; #; }", [params, moduleStatements]); 221 js.call("function(#) { 'use strict'; #; }", [params, moduleStatements]);
231 222
232 var moduleDef = js.statement("dart_library.library(#, #, #, #, #)", [ 223 var moduleDef = js.statement("dart_library.library(#, #, #, #, #)", [
233 js.string(jsPath, "'"), 224 js.string(jsPath, "'"),
234 _jsModuleValue ?? new JS.LiteralNull(), 225 _jsModuleValue ?? new JS.LiteralNull(),
235 js.commentExpression( 226 js.commentExpression(
236 "Imports", new JS.ArrayInitializer(imports, multiline: true)), 227 "Imports", new JS.ArrayInitializer(imports, multiline: true)),
237 js.commentExpression("Lazy imports", 228 js.commentExpression("Lazy imports",
238 new JS.ArrayInitializer(lazyImports, multiline: true)), 229 new JS.ArrayInitializer(lazyImports, multiline: true)),
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 .map((i) => i.name) 286 .map((i) => i.name)
296 .where((s) => !currentLibNames.containsKey(s)) 287 .where((s) => !currentLibNames.containsKey(s))
297 .map((s) => js.string(s, "'"))); 288 .map((s) => js.string(s, "'")));
298 } 289 }
299 if (hide != null) { 290 if (hide != null) {
300 hiddenNames.addAll(hide.hiddenNames.map((i) => js.string(i.name, "'"))); 291 hiddenNames.addAll(hide.hiddenNames.map((i) => js.string(i.name, "'")));
301 } 292 }
302 args.add(new JS.ArrayInitializer(shownNames)); 293 args.add(new JS.ArrayInitializer(shownNames));
303 args.add(new JS.ArrayInitializer(hiddenNames)); 294 args.add(new JS.ArrayInitializer(hiddenNames));
304 } 295 }
305 _moduleItems.add(js.statement('dart.export_(#);', [args])); 296
297 // When we compile _runtime.js, we need to source export_ from _utils.js:
298 _moduleItems.add(js.statement('dart.export(#);', [args]));
306 } 299 }
307 300
308 JS.Identifier _initSymbol(JS.Identifier id) { 301 JS.Identifier _initSymbol(JS.Identifier id) {
309 var s = 302 var s =
310 js.statement('const # = $_SYMBOL(#);', [id, js.string(id.name, "'")]); 303 js.statement('const # = $_SYMBOL(#);', [id, js.string(id.name, "'")]);
311 _moduleItems.add(s); 304 _moduleItems.add(s);
312 return id; 305 return id;
313 } 306 }
314 307
315 // TODO(jmesserly): this is a temporary workaround for `Symbol` in core, 308 // TODO(jmesserly): this is a temporary workaround for `Symbol` in core,
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 isGetter: node.isGetter, 1284 isGetter: node.isGetter,
1292 isSetter: node.isSetter, 1285 isSetter: node.isSetter,
1293 isStatic: node.isStatic), 1286 isStatic: node.isStatic),
1294 node.element); 1287 node.element);
1295 } 1288 }
1296 1289
1297 /// Returns the name value of the `JSExportName` annotation (when compiling 1290 /// Returns the name value of the `JSExportName` annotation (when compiling
1298 /// the SDK), or `null` if there's none. This is used to control the name 1291 /// the SDK), or `null` if there's none. This is used to control the name
1299 /// under which functions are compiled and exported. 1292 /// under which functions are compiled and exported.
1300 String _getJSExportName(Element e) { 1293 String _getJSExportName(Element e) {
1301 if (e is! FunctionElement || !currentLibrary.source.isInSystemLibrary) { 1294 if (!currentLibrary.source.isInSystemLibrary) {
1302 return null; 1295 return null;
1303 } 1296 }
1304 var jsName = findAnnotation(e, isJSExportNameAnnotation); 1297 var jsName = findAnnotation(e, isJSExportNameAnnotation);
1305 return getConstantField(jsName, 'name', types.stringType)?.toStringValue(); 1298 return getConstantField(jsName, 'name', types.stringType)?.toStringValue();
1306 } 1299 }
1307 1300
1308 @override 1301 @override
1309 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) { 1302 JS.Statement visitFunctionDeclaration(FunctionDeclaration node) {
1310 assert(node.parent is CompilationUnit); 1303 assert(node.parent is CompilationUnit);
1311 1304
1312 if (_externalOrNative(node)) return null; 1305 if (_externalOrNative(node)) return null;
1313 1306
1314 if (node.isGetter || node.isSetter) { 1307 if (node.isGetter || node.isSetter) {
1315 // Add these later so we can use getter/setter syntax. 1308 // Add these later so we can use getter/setter syntax.
1316 _properties.add(node); 1309 _properties.add(node);
1317 return null; 1310 return null;
1318 } 1311 }
1319 1312
1320 var body = <JS.Statement>[]; 1313 var body = <JS.Statement>[];
1321 _flushLibraryProperties(body); 1314 _flushLibraryProperties(body);
1322 1315
1323 var name = _getJSExportName(node.element) ?? node.name.name; 1316 var name = _getJSExportName(node.element) ?? node.name.name;
1324 1317
1325 var fn = _visit(node.functionExpression); 1318 var fn = _visit(node.functionExpression);
1326 bool needsTagging = true;
1327 1319
1328 if (currentLibrary.source.isInSystemLibrary && 1320 if (currentLibrary.source.isInSystemLibrary &&
1329 _isInlineJSFunction(node.functionExpression)) { 1321 _isInlineJSFunction(node.functionExpression)) {
1330 fn = _simplifyPassThroughArrowFunCallBody(fn); 1322 fn = _simplifyPassThroughArrowFunCallBody(fn);
1331 needsTagging = !_isDartUtils;
1332 } 1323 }
1333 1324
1334 var id = new JS.Identifier(name); 1325 var id = new JS.Identifier(name);
1335 body.add(annotate(new JS.FunctionDeclaration(id, fn), node.element)); 1326 body.add(annotate(new JS.FunctionDeclaration(id, fn), node.element));
1336 if (needsTagging) { 1327 if (!_isDartRuntime) {
1337 body.add(_emitFunctionTagged(id, node.element.type, topLevel: true) 1328 body.add(_emitFunctionTagged(id, node.element.type, topLevel: true)
1338 .toStatement()); 1329 .toStatement());
1339 } 1330 }
1340 1331
1341 if (isPublic(name)) _addExport(name); 1332 if (isPublic(name)) _addExport(name);
1342 return _statement(body); 1333 return _statement(body);
1343 } 1334 }
1344 1335
1345 bool _isInlineJSFunction(FunctionExpression functionExpression) { 1336 bool _isInlineJSFunction(FunctionExpression functionExpression) {
1346 var body = functionExpression.body; 1337 var body = functionExpression.body;
1347 if (body is ExpressionFunctionBody) { 1338 if (body is ExpressionFunctionBody) {
1348 return _isJSInvocation(body.expression); 1339 return _isJSInvocation(body.expression);
1349 } else if (body is BlockFunctionBody) { 1340 } else if (body is BlockFunctionBody) {
1350 if (body.block.statements.length == 1) { 1341 if (body.block.statements.length == 1) {
1351 var stat = body.block.statements.single; 1342 var stat = body.block.statements.single;
1352 if (stat is ReturnStatement) { 1343 if (stat is ReturnStatement) {
1353 return _isJSInvocation(stat.expression); 1344 return _isJSInvocation(stat.expression);
1354 } 1345 }
1355 } 1346 }
1356 } 1347 }
1357 return false; 1348 return false;
1358 } 1349 }
1359 1350
1360 bool _isJSInvocation(Expression expr) => 1351 bool _isJSInvocation(Expression expr) =>
1361 expr is MethodInvocation && isInlineJS(expr.methodName.staticElement); 1352 expr is MethodInvocation && isInlineJS(expr.methodName.staticElement);
1362 1353
1363 // Simplify `(args) => ((x, y) => { ... })(x, y)` to `(args) => { ... }`. 1354 // Simplify `(args) => (() => { ... })()` to `(args) => { ... }`.
1364 // Note: we don't check if the top-level args match the ones passed through 1355 // Note: this allows silently passing args through to the body, which only
1365 // the arrow function, which allows silently passing args through to the 1356 // works if we don't do weird renamings of Dart params.
1366 // body (which only works if we don't do weird renamings of Dart params).
1367 JS.Fun _simplifyPassThroughArrowFunCallBody(JS.Fun fn) { 1357 JS.Fun _simplifyPassThroughArrowFunCallBody(JS.Fun fn) {
1368 String getIdent(JS.Node node) => node is JS.Identifier ? node.name : null;
1369 List<String> getIdents(List params) =>
1370 params.map(getIdent).toList(growable: false);
1371
1372 if (fn.body is JS.Block && fn.body.statements.length == 1) { 1358 if (fn.body is JS.Block && fn.body.statements.length == 1) {
1373 var stat = fn.body.statements.single; 1359 var stat = fn.body.statements.single;
1374 if (stat is JS.Return && stat.value is JS.Call) { 1360 if (stat is JS.Return && stat.value is JS.Call) {
1375 JS.Call call = stat.value; 1361 JS.Call call = stat.value;
1376 if (call.target is JS.ArrowFun) { 1362 if (call.target is JS.ArrowFun && call.arguments.isEmpty) {
1377 var passedArgs = getIdents(call.arguments);
1378 JS.ArrowFun innerFun = call.target; 1363 JS.ArrowFun innerFun = call.target;
1379 if (_listEquality.equals(getIdents(innerFun.params), passedArgs)) { 1364 if (innerFun.params.isEmpty) {
1380 return new JS.Fun(fn.params, innerFun.body); 1365 return new JS.Fun(fn.params, innerFun.body);
1381 } 1366 }
1382 } 1367 }
1383 } 1368 }
1384 } 1369 }
1385 return fn; 1370 return fn;
1386 } 1371 }
1387 1372
1388 JS.Method _emitTopLevelProperty(FunctionDeclaration node) { 1373 JS.Method _emitTopLevelProperty(FunctionDeclaration node) {
1389 var name = node.name.name; 1374 var name = node.name.name;
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 } 1754 }
1770 if (jsArgs != null) { 1755 if (jsArgs != null) {
1771 var genericName = _emitTopLevelName(element, suffix: '\$'); 1756 var genericName = _emitTopLevelName(element, suffix: '\$');
1772 return js.call('#(#)', [genericName, jsArgs]); 1757 return js.call('#(#)', [genericName, jsArgs]);
1773 } 1758 }
1774 } 1759 }
1775 1760
1776 return _emitTopLevelName(element); 1761 return _emitTopLevelName(element);
1777 } 1762 }
1778 1763
1779 JS.Expression _emitTopLevelName(Element e, {String suffix : ''}) { 1764 JS.Expression _emitTopLevelName(Element e, {String suffix: ''}) {
1780 var libName = _libraryName(e.library); 1765 var libName = _libraryName(e.library);
1781 var nameExpr = _propertyName((_getJSExportName(e) ?? e.name) + suffix); 1766 var nameExpr = _propertyName((_getJSExportName(e) ?? e.name) + suffix);
1782 1767
1783 // Always qualify: 1768 // Always qualify:
1784 // * mutable top-level fields 1769 // * mutable top-level fields
1785 // * elements from other libraries 1770 // * elements from other libraries
1786 bool mutableTopLevel = e is TopLevelVariableElement && 1771 bool mutableTopLevel = e is TopLevelVariableElement &&
1787 !e.isConst && 1772 !e.isConst &&
1788 !_isFinalJSDecl(e.computeNode()); 1773 !_isFinalJSDecl(e.computeNode());
1789 bool fromAnotherLibrary = e.library != currentLibrary; 1774 bool fromAnotherLibrary = e.library != currentLibrary;
(...skipping 1664 matching lines...) Expand 10 before | Expand all | Expand 10 after
3454 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody; 3439 node.externalKeyword != null || _functionBody(node) is NativeFunctionBody;
3455 3440
3456 FunctionBody _functionBody(node) => 3441 FunctionBody _functionBody(node) =>
3457 node is FunctionDeclaration ? node.functionExpression.body : node.body; 3442 node is FunctionDeclaration ? node.functionExpression.body : node.body;
3458 3443
3459 /// Choose a canonical name from the library element. 3444 /// Choose a canonical name from the library element.
3460 /// This never uses the library's name (the identifier in the `library` 3445 /// This never uses the library's name (the identifier in the `library`
3461 /// declaration) as it doesn't have any meaningful rules enforced. 3446 /// declaration) as it doesn't have any meaningful rules enforced.
3462 JS.Identifier _libraryName(LibraryElement library) { 3447 JS.Identifier _libraryName(LibraryElement library) {
3463 if (library == currentLibrary) return _exportsVar; 3448 if (library == currentLibrary) return _exportsVar;
3449 if (library.name == 'dart._runtime') return _runtimeLibVar;
3464 return _imports.putIfAbsent( 3450 return _imports.putIfAbsent(
3465 library, () => new JS.TemporaryId(jsLibraryName(library))); 3451 library, () => new JS.TemporaryId(jsLibraryName(library)));
3466 } 3452 }
3467 3453
3468 DartType getStaticType(Expression e) => 3454 DartType getStaticType(Expression e) =>
3469 e.staticType ?? DynamicTypeImpl.instance; 3455 e.staticType ?? DynamicTypeImpl.instance;
3470 3456
3471 @override 3457 @override
3472 String getQualifiedName(TypeDefiningElement type) { 3458 String getQualifiedName(TypeDefiningElement type) {
3473 JS.TemporaryId id = _imports[type.library]; 3459 JS.TemporaryId id = _imports[type.library];
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
3634 3620
3635 /// A special kind of element created by the compiler, signifying a temporary 3621 /// A special kind of element created by the compiler, signifying a temporary
3636 /// variable. These objects use instance equality, and should be shared 3622 /// variable. These objects use instance equality, and should be shared
3637 /// everywhere in the tree where they are treated as the same variable. 3623 /// everywhere in the tree where they are treated as the same variable.
3638 class TemporaryVariableElement extends LocalVariableElementImpl { 3624 class TemporaryVariableElement extends LocalVariableElementImpl {
3639 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 3625 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
3640 3626
3641 int get hashCode => identityHashCode(this); 3627 int get hashCode => identityHashCode(this);
3642 bool operator ==(Object other) => identical(this, other); 3628 bool operator ==(Object other) => identical(this, other);
3643 } 3629 }
OLDNEW
« no previous file with comments | « lib/runtime/dart/typed_data.js ('k') | lib/src/compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698