| OLD | NEW |
| 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 ddc.src.codegen.js_codegen; | 5 library ddc.src.codegen.js_codegen; |
| 6 | 6 |
| 7 import 'dart:io' show Directory, File; | 7 import 'dart:io' show Directory, File; |
| 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 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 // This must match the optional parameter name used in runtime.js | 31 // This must match the optional parameter name used in runtime.js |
| 32 const String _jsNamedParameterName = r'opt$'; | 32 const String _jsNamedParameterName = r'opt$'; |
| 33 | 33 |
| 34 class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor { | 34 class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor { |
| 35 final LibraryInfo libraryInfo; | 35 final LibraryInfo libraryInfo; |
| 36 final TypeRules rules; | 36 final TypeRules rules; |
| 37 | 37 |
| 38 /// The variable for the target of the current `..` cascade expression. | 38 /// The variable for the target of the current `..` cascade expression. |
| 39 SimpleIdentifier _cascadeTarget; | 39 SimpleIdentifier _cascadeTarget; |
| 40 /// The variable for the current catch clause |
| 41 String _catchParameter; |
| 40 | 42 |
| 41 ClassDeclaration currentClass; | 43 ClassDeclaration currentClass; |
| 42 ConstantEvaluator _constEvaluator; | 44 ConstantEvaluator _constEvaluator; |
| 43 | 45 |
| 44 final _exports = <String>[]; | 46 final _exports = <String>[]; |
| 45 final _lazyFields = <VariableDeclaration>[]; | 47 final _lazyFields = <VariableDeclaration>[]; |
| 46 final _properties = <FunctionDeclaration>[]; | 48 final _properties = <FunctionDeclaration>[]; |
| 47 | 49 |
| 48 JSCodegenVisitor(LibraryInfo libraryInfo, TypeRules rules) | 50 JSCodegenVisitor(LibraryInfo libraryInfo, TypeRules rules) |
| 49 : libraryInfo = libraryInfo, | 51 : libraryInfo = libraryInfo, |
| (...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 visitThrowExpression(ThrowExpression node) { | 1282 visitThrowExpression(ThrowExpression node) { |
| 1281 var expr = _visit(node.expression); | 1283 var expr = _visit(node.expression); |
| 1282 if (node.parent is ExpressionStatement) { | 1284 if (node.parent is ExpressionStatement) { |
| 1283 return js.statement('throw #;', expr); | 1285 return js.statement('throw #;', expr); |
| 1284 } else { | 1286 } else { |
| 1285 return js.call('dart.throw_(#)', expr); | 1287 return js.call('dart.throw_(#)', expr); |
| 1286 } | 1288 } |
| 1287 } | 1289 } |
| 1288 | 1290 |
| 1289 @override | 1291 @override |
| 1292 visitRethrowExpression(RethrowExpression node){ |
| 1293 if (node.parent is ExpressionStatement) { |
| 1294 return js.statement('throw #;', _catchParameter); |
| 1295 } else { |
| 1296 return js.call('dart.throw_(#)', _catchParameter); |
| 1297 } |
| 1298 } |
| 1299 |
| 1300 @override |
| 1290 JS.If visitIfStatement(IfStatement node) { | 1301 JS.If visitIfStatement(IfStatement node) { |
| 1291 return new JS.If(_visit(node.condition), _visit(node.thenStatement), | 1302 return new JS.If(_visit(node.condition), _visit(node.thenStatement), |
| 1292 _visitOrEmpty(node.elseStatement)); | 1303 _visitOrEmpty(node.elseStatement)); |
| 1293 } | 1304 } |
| 1294 | 1305 |
| 1295 @override | 1306 @override |
| 1296 JS.For visitForStatement(ForStatement node) { | 1307 JS.For visitForStatement(ForStatement node) { |
| 1297 var init = _visit(node.initialization); | 1308 var init = _visit(node.initialization); |
| 1298 if (init == null) init = _visit(node.variables); | 1309 if (init == null) init = _visit(node.variables); |
| 1299 return new JS.For(init, _visit(node.condition), | 1310 return new JS.For(init, _visit(node.condition), |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1335 visitTryStatement(TryStatement node) { | 1346 visitTryStatement(TryStatement node) { |
| 1336 return new JS.Try(_visit(node.body), _visitCatch(node.catchClauses), | 1347 return new JS.Try(_visit(node.body), _visitCatch(node.catchClauses), |
| 1337 _visit(node.finallyBlock)); | 1348 _visit(node.finallyBlock)); |
| 1338 } | 1349 } |
| 1339 | 1350 |
| 1340 _visitCatch(NodeList<CatchClause> clauses) { | 1351 _visitCatch(NodeList<CatchClause> clauses) { |
| 1341 if (clauses == null || clauses.isEmpty) return null; | 1352 if (clauses == null || clauses.isEmpty) return null; |
| 1342 | 1353 |
| 1343 // TODO(jmesserly): need a better way to get a temporary variable. | 1354 // TODO(jmesserly): need a better way to get a temporary variable. |
| 1344 // This could incorrectly shadow a user's name. | 1355 // This could incorrectly shadow a user's name. |
| 1345 var name = '\$e'; | 1356 var savedCatch = _catchParameter; |
| 1357 _catchParameter = '\$e'; |
| 1346 | 1358 |
| 1347 if (clauses.length == 1) { | 1359 if (clauses.length == 1) { |
| 1348 // Special case for a single catch. | 1360 // Special case for a single catch. |
| 1349 var clause = clauses.single; | 1361 var clause = clauses.single; |
| 1350 if (clause.exceptionParameter != null) { | 1362 if (clause.exceptionParameter != null) { |
| 1351 name = clause.exceptionParameter.name; | 1363 _catchParameter = clause.exceptionParameter.name; |
| 1352 } | 1364 } |
| 1353 } | 1365 } |
| 1354 | 1366 |
| 1355 var catchBody = _statement(clauses.map((c) => _visitCatchClause(c, name))); | 1367 var catchVarDecl = new JS.VariableDeclaration(_catchParameter); |
| 1368 var catchBody = _statement(_visitList(clauses)); |
| 1369 _catchParameter = savedCatch; |
| 1356 | 1370 |
| 1357 return new JS.Catch(new JS.VariableDeclaration(name), catchBody); | 1371 return new JS.Catch(catchVarDecl, catchBody); |
| 1358 } | 1372 } |
| 1359 | 1373 |
| 1360 JS.Statement _statement(Iterable stmts) { | 1374 JS.Statement _statement(Iterable stmts) { |
| 1361 var s = stmts is List ? stmts : new List<JS.Statement>.from(stmts); | 1375 var s = stmts is List ? stmts : new List<JS.Statement>.from(stmts); |
| 1362 // TODO(jmesserly): empty block singleton? | 1376 // TODO(jmesserly): empty block singleton? |
| 1363 if (s.length == 0) return new JS.Block([]); | 1377 if (s.length == 0) return new JS.Block([]); |
| 1364 if (s.length == 1) return s[0]; | 1378 if (s.length == 1) return s[0]; |
| 1365 return new JS.Block(s); | 1379 return new JS.Block(s); |
| 1366 } | 1380 } |
| 1367 | 1381 |
| 1368 JS.Statement _visitCatchClause(CatchClause node, String varName) { | 1382 @override |
| 1383 JS.Statement visitCatchClause(CatchClause node) { |
| 1369 var body = []; | 1384 var body = []; |
| 1385 |
| 1386 var savedCatch = _catchParameter; |
| 1370 if (node.catchKeyword != null) { | 1387 if (node.catchKeyword != null) { |
| 1371 var name = node.exceptionParameter; | 1388 var name = node.exceptionParameter; |
| 1372 if (name != null && name.name != varName) { | 1389 if (name != null && name.name != _catchParameter) { |
| 1373 body.add(js.statement('let # = #;', [_visit(name), varName])); | 1390 body.add(js.statement('let # = #;', [_visit(name), _catchParameter])); |
| 1391 _catchParameter = name.name; |
| 1374 } | 1392 } |
| 1375 if (node.stackTraceParameter != null) { | 1393 if (node.stackTraceParameter != null) { |
| 1376 var stackVar = node.stackTraceParameter.name; | 1394 var stackVar = node.stackTraceParameter.name; |
| 1377 body.add(js.statement( | 1395 body.add(js.statement( |
| 1378 'let # = dart.stackTrace(#);', [stackVar, _visit(name)])); | 1396 'let # = dart.stackTrace(#);', [stackVar, _visit(name)])); |
| 1379 } | 1397 } |
| 1380 } | 1398 } |
| 1381 | 1399 |
| 1382 body.add(_visit(node.body)); | 1400 body.add(_visit(node.body)); |
| 1401 _catchParameter = savedCatch; |
| 1383 | 1402 |
| 1384 if (node.exceptionType != null) { | 1403 if (node.exceptionType != null) { |
| 1385 return js.statement('if (dart.is(#, #)) #;', [ | 1404 return js.statement('if (dart.is(#, #)) #;', [ |
| 1386 varName, | 1405 _catchParameter, |
| 1387 _emitTypeName(node.exceptionType.type), | 1406 _emitTypeName(node.exceptionType.type), |
| 1388 _statement(body) | 1407 _statement(body) |
| 1389 ]); | 1408 ]); |
| 1390 } | 1409 } |
| 1410 |
| 1391 return _statement(body); | 1411 return _statement(body); |
| 1392 } | 1412 } |
| 1393 | 1413 |
| 1394 @override | 1414 @override |
| 1395 JS.Case visitSwitchCase(SwitchCase node) { | 1415 JS.Case visitSwitchCase(SwitchCase node) { |
| 1396 var expr = _visit(node.expression); | 1416 var expr = _visit(node.expression); |
| 1397 var body = _visitList(node.statements); | 1417 var body = _visitList(node.statements); |
| 1398 if (node.labels.isNotEmpty) { | 1418 if (node.labels.isNotEmpty) { |
| 1399 body.insert(0, js.comment('Unimplemented case labels: ${node.labels}')); | 1419 body.insert(0, js.comment('Unimplemented case labels: ${node.labels}')); |
| 1400 } | 1420 } |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1832 | 1852 |
| 1833 // TODO(jmesserly): in many cases marking the end will be unncessary. | 1853 // TODO(jmesserly): in many cases marking the end will be unncessary. |
| 1834 printer.mark(_location(node.end)); | 1854 printer.mark(_location(node.end)); |
| 1835 } | 1855 } |
| 1836 | 1856 |
| 1837 String _getIdentifier(AstNode node) { | 1857 String _getIdentifier(AstNode node) { |
| 1838 if (node is SimpleIdentifier) return node.name; | 1858 if (node is SimpleIdentifier) return node.name; |
| 1839 return null; | 1859 return null; |
| 1840 } | 1860 } |
| 1841 } | 1861 } |
| OLD | NEW |