From c81fcbafde47a028390c5f79eb935dfd9feb41cd Mon Sep 17 00:00:00 2001 From: "scheglov@google.com" Date: Wed, 29 Feb 2012 23:50:01 +0000 Subject: [PATCH] Remove backends. R=zundel@google.com,brianwilkerson@google.com BUG= TEST= Review URL: https://chromiumcodereview.appspot.com//9479013 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@4771 260f80e4-7a28-3924-810f-c04153c831b5 --- compiler/dart-compiler.gyp | 2 - .../com/google/dart/compiler/Backend.java | 54 - .../dart/compiler/CommandLineOptions.java | 47 - .../dart/compiler/CompilerConfiguration.java | 22 +- .../google/dart/compiler/DartCompiler.java | 185 +- .../dart/compiler/DartCompilerContext.java | 9 +- .../DefaultCompilerConfiguration.java | 82 +- .../DelegatingCompilerConfiguration.java | 20 - .../google/dart/compiler/LibrarySource.java | 11 +- .../com/google/dart/compiler/SubSystem.java | 2 +- .../compiler/ast/CoverageInstrumenter.java | 807 ---- .../google/dart/compiler/ast/DartNode.java | 9 - .../dart/compiler/ast/viz/ConsoleWriter.java | 9 +- .../dart/compiler/ast/viz/DotWriter.java | 6 +- .../compiler/backend/dart/DartBackend.java | 99 - .../backend/js/AbstractJsBackend.java | 518 --- .../dart/compiler/backend/js/Cloner.java | 253 -- .../dart/compiler/backend/js/DartMangler.java | 143 - .../compiler/backend/js/DollarMangler.java | 424 -- .../backend/js/GenerateJavascriptAST.java | 3877 ----------------- .../backend/js/GenerateNamesAndScopes.java | 214 - .../backend/js/JavascriptBackend.java | 181 - .../js/JsConstructExpressionVisitor.java | 114 - .../dart/compiler/backend/js/JsErrorCode.java | 49 - .../backend/js/JsFirstExpressionVisitor.java | 134 - .../compiler/backend/js/JsNameProvider.java | 87 - .../dart/compiler/backend/js/JsNamer.java | 23 - .../compiler/backend/js/JsNormalizer.java | 112 - .../backend/js/JsParserException.java | 92 - .../backend/js/JsPrecedenceVisitor.java | 317 -- .../compiler/backend/js/JsPrettyNamer.java | 127 - .../backend/js/JsRequiresSemiVisitor.java | 158 - .../backend/js/JsReservedIdentifiers.java | 223 - .../backend/js/JsSourceGenerationVisitor.java | 39 - .../js/JsToStringGenerationVisitor.java | 1354 ------ .../backend/js/NormalizedVisitor.java | 21 - .../dart/compiler/backend/js/Normalizer.java | 1034 ----- .../backend/js/RuntimeTypeInjector.java | 1277 ------ .../compiler/backend/js/ScopeRootInfo.java | 533 --- .../backend/js/TranslationContext.java | 78 - .../backend/js/TraversalContextProvider.java | 40 - .../js/UncheckedJsParserException.java | 21 - .../js/analysis/DependencyComputer.java | 262 -- .../js/analysis/JavascriptElement.java | 130 - .../js/analysis/TopLevelElementIndexer.java | 283 -- .../backend/js/analysis/TreeShaker.java | 191 - .../backend/js/ast/CanBooleanEval.java | 15 - .../compiler/backend/js/ast/HasArguments.java | 15 - .../compiler/backend/js/ast/HasCondition.java | 15 - .../dart/compiler/backend/js/ast/HasName.java | 14 - .../backend/js/ast/JsArrayAccess.java | 68 - .../backend/js/ast/JsArrayLiteral.java | 67 - .../backend/js/ast/JsBinaryOperation.java | 107 - .../backend/js/ast/JsBinaryOperator.java | 120 - .../dart/compiler/backend/js/ast/JsBlock.java | 44 - .../backend/js/ast/JsBooleanLiteral.java | 53 - .../dart/compiler/backend/js/ast/JsBreak.java | 46 - .../dart/compiler/backend/js/ast/JsCase.java | 39 - .../dart/compiler/backend/js/ast/JsCatch.java | 66 - .../compiler/backend/js/ast/JsCatchScope.java | 75 - .../backend/js/ast/JsConditional.java | 78 - .../compiler/backend/js/ast/JsContext.java | 27 - .../compiler/backend/js/ast/JsContinue.java | 46 - .../compiler/backend/js/ast/JsDebugger.java | 25 - .../compiler/backend/js/ast/JsDefault.java | 28 - .../compiler/backend/js/ast/JsDoWhile.java | 54 - .../dart/compiler/backend/js/ast/JsEmpty.java | 26 - .../compiler/backend/js/ast/JsExprStmt.java | 36 - .../compiler/backend/js/ast/JsExpression.java | 52 - .../dart/compiler/backend/js/ast/JsFor.java | 105 - .../dart/compiler/backend/js/ast/JsForIn.java | 71 - .../compiler/backend/js/ast/JsFunction.java | 225 - .../backend/js/ast/JsGlobalBlock.java | 19 - .../dart/compiler/backend/js/ast/JsIf.java | 65 - .../compiler/backend/js/ast/JsInvocation.java | 62 - .../dart/compiler/backend/js/ast/JsLabel.java | 52 - .../compiler/backend/js/ast/JsLiteral.java | 14 - .../compiler/backend/js/ast/JsModVisitor.java | 189 - .../dart/compiler/backend/js/ast/JsName.java | 114 - .../compiler/backend/js/ast/JsNameRef.java | 120 - .../dart/compiler/backend/js/ast/JsNew.java | 61 - .../dart/compiler/backend/js/ast/JsNode.java | 51 - .../backend/js/ast/JsNullLiteral.java | 46 - .../backend/js/ast/JsNumberLiteral.java | 53 - .../backend/js/ast/JsObjectLiteral.java | 66 - .../compiler/backend/js/ast/JsOperator.java | 32 - .../compiler/backend/js/ast/JsParameter.java | 41 - .../backend/js/ast/JsPostfixOperation.java | 42 - .../backend/js/ast/JsPrefixOperation.java | 69 - .../compiler/backend/js/ast/JsProgram.java | 172 - .../backend/js/ast/JsProgramFragment.java | 34 - .../backend/js/ast/JsPropertyInitializer.java | 56 - .../compiler/backend/js/ast/JsRegExp.java | 64 - .../compiler/backend/js/ast/JsReturn.java | 48 - .../compiler/backend/js/ast/JsRootScope.java | 50 - .../dart/compiler/backend/js/ast/JsScope.java | 301 -- .../compiler/backend/js/ast/JsStatement.java | 22 - .../backend/js/ast/JsStringLiteral.java | 53 - .../compiler/backend/js/ast/JsSwitch.java | 47 - .../backend/js/ast/JsSwitchMember.java | 24 - .../compiler/backend/js/ast/JsThisRef.java | 51 - .../dart/compiler/backend/js/ast/JsThrow.java | 48 - .../dart/compiler/backend/js/ast/JsTry.java | 59 - .../backend/js/ast/JsUnaryOperation.java | 53 - .../backend/js/ast/JsUnaryOperator.java | 78 - .../backend/js/ast/JsValueLiteral.java | 24 - .../dart/compiler/backend/js/ast/JsVars.java | 115 - .../compiler/backend/js/ast/JsVisitable.java | 19 - .../compiler/backend/js/ast/JsVisitor.java | 433 -- .../dart/compiler/backend/js/ast/JsWhile.java | 52 - .../compiler/backend/js/ast/NodeKind.java | 50 - .../compiler/metrics/CompilerMetrics.java | 50 - .../dart/compiler/metrics/DartEventType.java | 15 +- .../testing/TestCompilerConfiguration.java | 23 +- .../dart/compiler/type/TypeAnalyzer.java | 14 +- .../google/dart/compiler/util/AstUtil.java | 226 - .../dart/compiler/CompilerTestCase.java | 15 +- .../dart/compiler/MockArtifactProvider.java | 3 +- .../testArrayIncompatibleArrayOperator.dart | 4 - .../common/testCombinedExpressions.dart | 4 - .../common/testCompatibleBinaryOp.dart | 4 - .../backend/common/testCompatibleFields.dart | 4 - .../backend/common/testCompatibleMethods.dart | 4 - .../common/testIncompatibleBinaryOp1.dart | 4 - .../common/testIncompatibleBinaryOp2.dart | 4 - .../common/testIncompatibleFields.dart | 4 - .../common/testIncompatibleFields2.dart | 4 - .../testIncompatibleFieldsWithGetter.dart | 4 - .../testIncompatibleFieldsWithSetter.dart | 4 - .../common/testIncompatibleLogicalOp.dart | 4 - .../common/testIncompatibleMethods.dart | 4 - .../compiler/backend/js/ComparingVisitor.java | 367 -- .../backend/js/FlatteningVisitor.java | 53 - .../backend/js/JavaScriptStringTest.java | 51 - .../dart/compiler/backend/js/JsScopeTest.java | 81 - .../dart/compiler/backend/js/RttTest.java | 105 - .../compiler/backend/js/SnippetTestCase.java | 163 - .../js/analysis/DependencyComputerTest.java | 182 - .../backend/js/analysis/JsAnalysisTests.java | 26 - .../analysis/TopLevelElementIndexerTest.java | 249 -- .../backend/js/analysis/TreeShakerTest.java | 73 - .../compiler/backend/js/testClosureOpt.dart | 66 - .../backend/js/testCompoundBinaryExprOpt.dart | 141 - .../backend/js/testConstantExprOpt.dart | 35 - .../backend/js/testConstructorOptTest.dart | 37 - .../backend/js/testFieldAccessExprOpt.dart | 109 - .../compiler/backend/js/testListExprOpt.dart | 51 - .../backend/js/testListSubTypeExprOpt.dart | 44 - .../backend/js/testLiteralExpressions.dart | 95 - .../compiler/backend/js/testRuntimeTypes.dart | 49 - .../backend/js/testUnaryDecIncExprOpt.dart | 70 - .../inc/IncrementalCompilation2Test.java | 11 +- .../inc/IncrementalCompilationTest.java | 5 +- .../IncrementalCompilationWithPrefixTest.java | 3 +- .../end2end/inc/MemoryLibrarySource.java | 3 +- tools/testing/dart/test_suite.dart | 6 +- 156 files changed, 64 insertions(+), 20548 deletions(-) delete mode 100644 compiler/java/com/google/dart/compiler/Backend.java delete mode 100644 compiler/java/com/google/dart/compiler/ast/CoverageInstrumenter.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/dart/DartBackend.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/AbstractJsBackend.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/Cloner.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/DartMangler.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/DollarMangler.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/GenerateNamesAndScopes.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JavascriptBackend.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsConstructExpressionVisitor.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsErrorCode.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsFirstExpressionVisitor.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsNameProvider.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsNamer.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsNormalizer.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsParserException.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsPrecedenceVisitor.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsPrettyNamer.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsRequiresSemiVisitor.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsReservedIdentifiers.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsSourceGenerationVisitor.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/JsToStringGenerationVisitor.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/NormalizedVisitor.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/Normalizer.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ScopeRootInfo.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/TranslationContext.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/TraversalContextProvider.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/UncheckedJsParserException.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/analysis/DependencyComputer.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/analysis/JavascriptElement.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/analysis/TopLevelElementIndexer.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/analysis/TreeShaker.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/CanBooleanEval.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/HasArguments.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/HasCondition.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/HasName.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsArrayAccess.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsArrayLiteral.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsBinaryOperation.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsBinaryOperator.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsBlock.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsBooleanLiteral.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsBreak.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsCase.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsCatch.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsCatchScope.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsConditional.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsContext.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsContinue.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsDebugger.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsDefault.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsDoWhile.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsEmpty.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsExprStmt.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsExpression.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsFor.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsForIn.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsFunction.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsGlobalBlock.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsIf.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsInvocation.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsLabel.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsLiteral.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsModVisitor.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsName.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsNameRef.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsNew.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsNode.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsNullLiteral.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsNumberLiteral.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsObjectLiteral.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsOperator.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsParameter.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsPostfixOperation.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsPrefixOperation.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsProgram.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsProgramFragment.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsPropertyInitializer.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsRegExp.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsReturn.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsRootScope.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsScope.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsStatement.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsStringLiteral.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsSwitch.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsSwitchMember.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsThisRef.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsThrow.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsTry.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsUnaryOperation.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsUnaryOperator.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsValueLiteral.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsVars.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsVisitable.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsVisitor.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/JsWhile.java delete mode 100644 compiler/java/com/google/dart/compiler/backend/js/ast/NodeKind.java delete mode 100644 compiler/java/com/google/dart/compiler/util/AstUtil.java delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testArrayIncompatibleArrayOperator.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testCombinedExpressions.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleBinaryOp.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleFields.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleMethods.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleBinaryOp1.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleBinaryOp2.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFields.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFields2.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFieldsWithGetter.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFieldsWithSetter.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleLogicalOp.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleMethods.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/ComparingVisitor.java delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/FlatteningVisitor.java delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/JavaScriptStringTest.java delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/JsScopeTest.java delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/RttTest.java delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/SnippetTestCase.java delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/analysis/DependencyComputerTest.java delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/analysis/JsAnalysisTests.java delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/analysis/TopLevelElementIndexerTest.java delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/analysis/TreeShakerTest.java delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/testClosureOpt.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/testCompoundBinaryExprOpt.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/testConstantExprOpt.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/testConstructorOptTest.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/testFieldAccessExprOpt.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/testListExprOpt.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/testListSubTypeExprOpt.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/testLiteralExpressions.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/testRuntimeTypes.dart delete mode 100644 compiler/javatests/com/google/dart/compiler/backend/js/testUnaryDecIncExprOpt.dart diff --git a/compiler/dart-compiler.gyp b/compiler/dart-compiler.gyp index 64df41798b9..605ed304838 100644 --- a/compiler/dart-compiler.gyp +++ b/compiler/dart-compiler.gyp @@ -40,7 +40,6 @@ '../third_party/args4j/2.0.12/args4j-2.0.12.jar', '../third_party/guava/r09/guava-r09.jar', '../third_party/json/r2_20080312/json.jar', - '../third_party/rhino/1_7R3/js.jar', '../third_party/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar', '../third_party/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar', '../third_party/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar', @@ -135,7 +134,6 @@ 'action': [ '<(PRODUCT_DIR)/dartc', 'api.dart', '--fatal-warnings', '--fatal-type-errors', - '--deprecated-generate-code', '-out', '<(INTERMEDIATE_DIR)/<(_target_name)/api', ], }, diff --git a/compiler/java/com/google/dart/compiler/Backend.java b/compiler/java/com/google/dart/compiler/Backend.java deleted file mode 100644 index 8e7cfe99a62..00000000000 --- a/compiler/java/com/google/dart/compiler/Backend.java +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler; - -import com.google.dart.compiler.ast.DartUnit; -import com.google.dart.compiler.ast.LibraryUnit; -import com.google.dart.compiler.resolver.CoreTypeProvider; - -import java.io.IOException; -import java.util.Collection; - -/** - * Interface for compiler backends. - */ -public interface Backend { - - /** - * Determines whether compilation artifacts are out of date with respect to - * this source. - */ - boolean isOutOfDate(DartSource src, DartCompilerContext context); - - /** - * Compile the given compilation unit. - * @param context The listener through which compilation errors are reported - * (not null) - */ - void compileUnit(DartUnit unit, DartSource src, - DartCompilerContext context, - CoreTypeProvider typeProvider) - throws IOException; - - /** - * Package the given application. - * - * @param app The application library whose entry-point should be called - * @param libraries The transitive set of libraries contained in this - * application - * @param context The listener through which compilation errors are reported - * (not null) - */ - void packageApp(LibrarySource app, - Collection libraries, - DartCompilerContext context, - CoreTypeProvider typeProvider) - throws IOException; - - /** - * The application extension for the backend. - */ - String getAppExtension(); -} diff --git a/compiler/java/com/google/dart/compiler/CommandLineOptions.java b/compiler/java/com/google/dart/compiler/CommandLineOptions.java index 8429f18f1ae..3a4dea3c931 100644 --- a/compiler/java/com/google/dart/compiler/CommandLineOptions.java +++ b/compiler/java/com/google/dart/compiler/CommandLineOptions.java @@ -30,10 +30,6 @@ public class CommandLineOptions { usage = "Batch mode (for unit testing)") private boolean batch = false; - @Option(name = "--deprecated-generate-code", - usage = "Use deprecated code generation.\n Will be removed 1 March 2012.") - private boolean deprecatedGenerateCode = false; - @Option(name = "--expose_core_impl", usage = "Automatic import of dart:coreimpl library") private boolean exposeCoreImpl = false; @@ -49,23 +45,10 @@ public class CommandLineOptions { usage = "Turn off type optimizations\n (for debugging)") private boolean disableTypeOptimizations = false; - @Option(name = "--generate_source_maps", - usage = "Generate source maps") - private boolean generateSourceMaps = false; - @Option(name = "--dump_ast_format", usage = "Dump parse tree. Supported formats include console, text or dot") private String dumpAST = ""; - @Option(name = "--coverage_type", - usage = "Add instrumentation probes for collecting coverage. " + - "Supported types include function, statement, branch and all") - private String coverage = ""; - - @Option(name = "--human-readable-output", - usage = "Write human readable javascript") - private boolean generateHumanReadableOutput = false; - @Option(name = "--ignore-unrecognized-flags", usage = "Ignore unrecognized command line flags") private boolean ignoreUnrecognizedFlags = false; @@ -96,10 +79,6 @@ public class CommandLineOptions { usage = "Enable incremental compilation") private boolean incremental = false; - @Option(name = "--out", - usage = "Write generated JavaScript to a file") - private File outputFilename = null; - // TODO(zundel): -out is for backward compatibility until scripts are updated @Option(name = "--work", aliases = { "-out" }, usage = "Directory to receive compiler output\n for future incremental builds") @@ -128,13 +107,6 @@ public class CommandLineOptions { @Argument private final List sourceFiles = new ArrayList(); - /** - * Returns whether the only analysis should be done, without code generation. - */ - public boolean checkOnly() { - return !deprecatedGenerateCode; - } - /** * @return true to automatically import dart:coreimpl */ @@ -182,29 +154,10 @@ public class CommandLineOptions { return disableTypeOptimizations; } - public boolean generateSourceMaps() { - return generateSourceMaps; - } - - public boolean generateHumanReadableOutput() { - return generateHumanReadableOutput; - } - public String dumpAST(){ return dumpAST; } - public String getCoverageType(){ - return coverage; - } - - /** - * @return the path to receive compiler output. - */ - public File getOutputFilename() { - return outputFilename; - } - /** * Returns true if the compiler should print it's help message. */ diff --git a/compiler/java/com/google/dart/compiler/CompilerConfiguration.java b/compiler/java/com/google/dart/compiler/CompilerConfiguration.java index 78100898f32..c76ac405fd6 100644 --- a/compiler/java/com/google/dart/compiler/CompilerConfiguration.java +++ b/compiler/java/com/google/dart/compiler/CompilerConfiguration.java @@ -1,4 +1,4 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. @@ -11,8 +11,7 @@ import java.io.File; import java.util.List; /** - * A configuration for the Dart compiler specifying which phases - * and backends will be executed. + * A configuration for the Dart compiler specifying which phases will be executed. */ public interface CompilerConfiguration { @@ -23,8 +22,6 @@ public interface CompilerConfiguration { List getPhases(); - List getBackends(); - /** * Indicates whether developer-mode runtime checks are needed. * @return true if developer-mode checks should be inserted, false if not @@ -61,26 +58,11 @@ public interface CompilerConfiguration { */ boolean incremental(); - /** - * The first backend that runs outputs to this filename if set. - */ - File getOutputFilename(); - /** * The work directory where incremental build output is stored between invocations. */ File getOutputDirectory(); - /** - * Returns true if the compiler should not produce output. - */ - boolean checkOnly(); - - /** - * Returns true if the compiler should expect an entry point to be defined. - */ - boolean expectEntryPoint(); - /** * Returns the error formatting the compiler should print with */ diff --git a/compiler/java/com/google/dart/compiler/DartCompiler.java b/compiler/java/com/google/dart/compiler/DartCompiler.java index 476cdffb972..2911484190a 100644 --- a/compiler/java/com/google/dart/compiler/DartCompiler.java +++ b/compiler/java/com/google/dart/compiler/DartCompiler.java @@ -9,11 +9,9 @@ import com.google.common.collect.Sets; import com.google.common.collect.Sets.SetView; import com.google.common.io.CharStreams; import com.google.common.io.Closeables; -import com.google.common.io.Files; import com.google.dart.compiler.CommandLineOptions.CompilerOptions; import com.google.dart.compiler.LibraryDeps.Dependency; import com.google.dart.compiler.UnitTestBatchRunner.Invocation; -import com.google.dart.compiler.ast.CoverageInstrumenter; import com.google.dart.compiler.ast.DartDirective; import com.google.dart.compiler.ast.DartLibraryDirective; import com.google.dart.compiler.ast.DartNode; @@ -30,7 +28,6 @@ import com.google.dart.compiler.metrics.JvmMetrics; import com.google.dart.compiler.metrics.Tracer; import com.google.dart.compiler.metrics.Tracer.TraceEvent; import com.google.dart.compiler.parser.DartParser; -import com.google.dart.compiler.parser.DartScanner.Location; import com.google.dart.compiler.parser.DartScannerParserContext; import com.google.dart.compiler.resolver.CompileTimeConstantResolver; import com.google.dart.compiler.resolver.CoreTypeProvider; @@ -55,7 +52,6 @@ import java.io.PrintStream; import java.io.Reader; import java.io.Writer; import java.net.URI; -import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -126,13 +122,10 @@ public class DartCompiler { private final DartCompilerMainContext context; private final CompilerConfiguration config; private final Map libraries = new LinkedHashMap(); - private boolean packageApp = false; - private final boolean checkOnly; private CoreTypeProvider typeProvider; private final boolean incremental; private final boolean usePrecompiledDartLibs; private final List phases; - private final List backends; private final LibrarySource coreLibrarySource; private Compiler(LibrarySource app, List embedded, CompilerConfiguration config, @@ -140,9 +133,7 @@ public class DartCompiler { this.app = app; this.config = config; this.phases = config.getPhases(); - this.backends = config.getBackends(); this.context = context; - checkOnly = config.checkOnly(); for (LibrarySource library : embedded) { if (SystemLibraryManager.isDartSpec(library.getName())) { embeddedLibraries.add(context.getSystemLibraryFor(library.getName())); @@ -164,16 +155,7 @@ public class DartCompiler { if (context.getErrorCount() > 0) { return; } - if (!context.getFilesHaveChanged()) { - for (Backend be : backends) { - if(context.isOutOfDate(app, app, be.getAppExtension())) { - packageApp = true; - break; - } - } - } compileLibraries(); - packageApp(); } catch (IOException e) { context.onError(new DartCompilationError(app, DartCompilerErrorCode.IO, e.getMessage())); } finally { @@ -459,33 +441,16 @@ public class DartCompiler { return true; } - if (checkOnly) { - TraceEvent backendEvent = - Tracer.canTrace() ? Tracer.start(DartEventType.TIMESTAMP_OUTOFDATE, - "src", dartSrc.getName()) : null; - try { - if (context.isOutOfDate(dartSrc, dartSrc, EXTENSION_TIMESTAMP)) { - return true; - } - } finally { - Tracer.end(backendEvent); - } - } else { - // TODO(zundel): remove this case when code generation goes away - for (Backend backend : backends) { - TraceEvent backendEvent = - Tracer.canTrace() ? Tracer.start(DartEventType.BACKEND_OUTOFDATE, "be", backend - .getClass().getCanonicalName(), "src", dartSrc.getName()) : null; - try { - if (backend.isOutOfDate(dartSrc, context)) { - return true; - } - } finally { - Tracer.end(backendEvent); - } - } + TraceEvent timestampEvent = + Tracer.canTrace() ? Tracer.start( + DartEventType.TIMESTAMP_OUTOFDATE, + "src", + dartSrc.getName()) : null; + try { + return context.isOutOfDate(dartSrc, dartSrc, EXTENSION_TIMESTAMP); + } finally { + Tracer.end(timestampEvent); } - return false; } finally { Tracer.end(logEvent); } @@ -749,10 +714,6 @@ public class DartCompiler { // Dump the compiler parse tree if dump format is set in arguments BaseASTWriter astWriter = ASTWriterFactory.create(config); - // Coverage instrumenter - CoverageInstrumenter coverageInstrumenter = CoverageInstrumenter.createInstance(config); - coverageInstrumenter.process(libraries); - // The two following for loops can be parallelized. for (LibraryUnit lib : libraries.values()) { boolean persist = false; @@ -782,7 +743,6 @@ public class DartCompiler { Tracer.end(phaseEvent); } if (context.getErrorCount() > 0) { - packageApp = false; return; } } @@ -790,30 +750,11 @@ public class DartCompiler { // To help support the IDE, notify the listener that this unit is compiled. context.unitCompiled(unit); - if (!checkOnly) { - // Run the unit through all the backends. This loop can also be - // parallelized. - for (Backend be : config.getBackends()) { - TraceEvent backendEvent = - Tracer.canTrace() ? Tracer.start(DartEventType.BACKEND_COMPILE, - "be", be.getClass().getSimpleName(), - "lib", lib.getName(), - "unit", unit.getSourceName()) : null; - try { - be.compileUnit(unit, unit.getSource(), context, typeProvider); - } finally { - Tracer.end(backendEvent); - } - } - } - // Update deps. lib.getDeps(context).update(context, unit); - // We compiled something, so remember that this means we need to - // persist the deps and package the app. + // We analyzed something, so we need to persist the deps. persist = true; - packageApp = true; } // Persist the DEPS file. @@ -837,48 +778,6 @@ public class DartCompiler { writer.close(); } - private void packageApp() throws IOException { - TraceEvent logEvent = Tracer.canTrace() ? Tracer.start(DartEventType.PACKAGE_APP) : null; - - CompilerMetrics compilerMetrics = context.getCompilerMetrics(); - if (compilerMetrics != null) { - compilerMetrics.startPackageAppTime(); - } - - try { - // Package output for each backend. - if (packageApp) { - // When there's no entry-point in the application unit, - // don't attempt to package it. This can happen when - // compileUnit() is called on a library. - if (context.getApplicationUnit().getEntryNode() == null) { - if (config.expectEntryPoint()) { - context.onError(new DartCompilationError( - context.getApplicationUnit().getSource(), Location.NONE, - DartCompilerErrorCode.NO_ENTRY_POINT)); - } - return; - } - - for (Backend be : backends) { - TraceEvent backendEvent = - Tracer.canTrace() ? Tracer.start(DartEventType.BACKEND_PACKAGE_APP, "be", be - .getClass().getSimpleName()) : null; - try { - be.packageApp(app, libraries.values(), context, typeProvider); - } finally { - Tracer.end(backendEvent); - } - } - } - } finally { - if (compilerMetrics != null) { - compilerMetrics.endPackageAppTime(); - } - Tracer.end(logEvent); - } - } - DartUnit parse(DartSource dartSrc, Set libraryPrefixes, boolean diet) throws IOException { TraceEvent parseEvent = Tracer.canTrace() ? Tracer.start(DartEventType.PARSE, "src", dartSrc.getName()) : null; @@ -1092,12 +991,6 @@ public class DartCompiler { TraceEvent logEvent = Tracer.canTrace() ? Tracer.start(DartEventType.COMPILE_APP, "src", sourceFile.toString()) : null; - File outFile = config.getOutputFilename(); - if (outFile != null && config.getBackends().size() > 1) { - // More than one backend is ambiguous. - throw new IllegalArgumentException("Output filename " - + outFile + " specified. Only valid with a single backend."); - } try { File outputDirectory = config.getOutputDirectory(); DefaultDartArtifactProvider provider = new DefaultDartArtifactProvider(outputDirectory); @@ -1106,53 +999,7 @@ public class DartCompiler { // Compile the Dart application and its dependencies. LibrarySource lib = new UrlLibrarySource(sourceFile); - config = new DelegatingCompilerConfiguration(config) { - @Override - public boolean expectEntryPoint() { - return true; - } - }; - String errorString = compileLib(lib, config, provider, listener); - - // Write out a copy of the generated JS if specified by the user - if (errorString == null && outFile != null && !config.getBackends().isEmpty()) { - File dir = outFile.getParentFile(); - if (dir != null) { - if (dir != null && !dir.exists()) { - throw new IOException("Cannot create: " + outFile.getName() - + ". " + dir + " does not exist"); - } - if (!dir.canWrite()) { - throw new IOException("Cannot write " + outFile.getName() + " to " - + dir + ": Permission denied."); - } - } else { - dir = new File ("."); - if (!dir.canWrite()) { - throw new IOException("Cannot write " + outFile.getName() + " to " - + dir + ": Permission denied."); - } - } - - if (!config.getCompilerOptions().checkOnly()) { - Reader r = null; - try { - // HACK: there can be more than one backend. Since there isn't - // an obvious way to tell which one the user meant, for now - // just restrict the option to save the output if more than - // one is active. - r = provider.getArtifactReader(lib, "", - config.getBackends().get(0).getAppExtension()); - String js = CharStreams.toString(r); - if (r != null) { - Files.write(js, outFile, Charset.defaultCharset()); - } - } finally { - Closeables.close(r, true); - } - } - } return errorString; } finally { Tracer.end(logEvent); @@ -1163,12 +1010,8 @@ public class DartCompiler { * Compiles the given library, translating all its source files, and those * of its imported libraries, transitively. * - * If the specified library contains an entry-point method, then the application will be packaged - * by each backend. Otherwise, only library artifacts will be generated. - * * @param lib The library to be compiled (not null) * @param config The compiler configuration specifying the compilation phases - * and backends * @param provider A mechanism for specifying where code should be generated * @param listener An object notified when compilation errors occur */ @@ -1212,7 +1055,8 @@ public class DartCompiler { if (!context.getFilesHaveChanged()) { return null; } - if (config.checkOnly()) { + // Write checking log. + { Writer writer = provider.getArtifactWriter(lib, "", EXTENSION_LOG); boolean threw = true; try { @@ -1235,9 +1079,8 @@ public class DartCompiler { * instead of parsing the associated source from storage. Intended for * IDE use when modified buffers must be analyzed. AST nodes in the map may be * ignored if not referenced by {@code lib}. (May be null.) - * @param config The compiler configuration (phases and backends - * will not be used), but resolution and type-analysis will be - * invoked + * @param config The compiler configuration (phases will not be used), but resolution and + * type-analysis will be invoked * @param provider A mechanism for specifying where code should be generated * @param listener An object notified when compilation errors occur * @throws NullPointerException if any of the arguments except {@code parsedUnits} diff --git a/compiler/java/com/google/dart/compiler/DartCompilerContext.java b/compiler/java/com/google/dart/compiler/DartCompilerContext.java index ef4e17e52a1..61e3302150a 100644 --- a/compiler/java/com/google/dart/compiler/DartCompilerContext.java +++ b/compiler/java/com/google/dart/compiler/DartCompilerContext.java @@ -13,11 +13,10 @@ import java.io.Writer; import java.net.URI; /** - * An interface used internally by the {@link DartCompiler} and implementers of - * {@link Backend} for determining where an artifact should be generated and - * providing feedback during the compilation process. This is an internal - * compiler construct and as such should not be instantiated or implemented by - * those outside the compiler itself. + * An interface used internally by the {@link DartCompiler} for determining where an artifact should + * be generated and providing feedback during the compilation process. This is an internal compiler + * construct and as such should not be instantiated or implemented by those outside the compiler + * itself. */ public interface DartCompilerContext { diff --git a/compiler/java/com/google/dart/compiler/DefaultCompilerConfiguration.java b/compiler/java/com/google/dart/compiler/DefaultCompilerConfiguration.java index 42025369763..7feb6c3e711 100644 --- a/compiler/java/com/google/dart/compiler/DefaultCompilerConfiguration.java +++ b/compiler/java/com/google/dart/compiler/DefaultCompilerConfiguration.java @@ -5,28 +5,22 @@ package com.google.dart.compiler; import com.google.dart.compiler.CommandLineOptions.CompilerOptions; -import com.google.dart.compiler.backend.js.JavascriptBackend; import com.google.dart.compiler.metrics.CompilerMetrics; import com.google.dart.compiler.resolver.CompileTimeConstantAnalyzer; import com.google.dart.compiler.resolver.Resolver; import com.google.dart.compiler.type.TypeAnalyzer; import java.io.File; -import java.io.FileNotFoundException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** - * A configuration for the Dart compiler specifying which phases - * and backends will be executed. + * A configuration for the Dart compiler specifying which phases will be executed. */ public class DefaultCompilerConfiguration implements CompilerConfiguration { - private List backends; - private final CompilerOptions compilerOptions; private final CompilerMetrics compilerMetrics; @@ -34,66 +28,26 @@ public class DefaultCompilerConfiguration implements CompilerConfiguration { private final SystemLibraryManager systemLibraryManager; /** - * A default configuration with the {@link JavascriptBackend} + * A default configuration. */ public DefaultCompilerConfiguration() { - this(new JavascriptBackend()); + this(new CompilerOptions()); } /** - * A new instance with the specified {@link CompilerOptions} - * @throws FileNotFoundException + * A new instance with the specified {@link CompilerOptions}. */ public DefaultCompilerConfiguration(CompilerOptions compilerOptions) { - this (new JavascriptBackend(), compilerOptions); + this(compilerOptions, new SystemLibraryManager()); } /** - * A new instance with the specified {@link Backend} - */ - public DefaultCompilerConfiguration(Backend backend) { - this(new CompilerOptions(), backend); - } - - /** - * A new instance with the specified {@link Backend} and {@link CompilerOptions} - */ - public DefaultCompilerConfiguration(Backend backend, CompilerOptions compilerOptions) { - this(compilerOptions, backend); - } - - /** - * A new instance with the specified list of {@link Backend} - */ - public DefaultCompilerConfiguration(Backend... backends) { - this(new CompilerOptions(), backends); - } - - /** - * A new instance with the specified list of {@link Backend} - */ - public DefaultCompilerConfiguration(CompilerOptions compilerOptions, Backend... backends) { - this(compilerOptions, new SystemLibraryManager(), backends); - } - - /** - * A new instance with the specified options, system library manager, and default {@link Backend - * backends}. + * A new instance with the specified options and system library manager. */ public DefaultCompilerConfiguration(CompilerOptions compilerOptions, - SystemLibraryManager libraryManager) throws FileNotFoundException { - this(compilerOptions, libraryManager, new JavascriptBackend()); - } - - /** - * A new instance with the specified options, system library manager, and list of {@link Backend - * backends}. - */ - public DefaultCompilerConfiguration(CompilerOptions compilerOptions, SystemLibraryManager libraryManager, Backend... backends) { - this.backends = Arrays.asList(backends); + SystemLibraryManager libraryManager) { this.compilerOptions = compilerOptions; - this.compilerMetrics = compilerOptions.showMetrics() ? - new CompilerMetrics() : null; + this.compilerMetrics = compilerOptions.showMetrics() ? new CompilerMetrics() : null; this.systemLibraryManager = libraryManager; } @@ -106,11 +60,6 @@ public class DefaultCompilerConfiguration implements CompilerConfiguration { return phases; } - @Override - public List getBackends() { - return backends; - } - @Override public boolean developerModeChecks() { return compilerOptions.developerModeChecks(); @@ -146,26 +95,11 @@ public class DefaultCompilerConfiguration implements CompilerConfiguration { return compilerOptions.buildIncrementally(); } - @Override - public File getOutputFilename() { - return compilerOptions.getOutputFilename(); - } - @Override public File getOutputDirectory() { return compilerOptions.getWorkDirectory(); } - @Override - public boolean checkOnly() { - return compilerOptions.checkOnly(); - } - - @Override - public boolean expectEntryPoint() { - return false; - } - @Override public LibrarySource getSystemLibraryFor(String importSpec) { URI systemUri; diff --git a/compiler/java/com/google/dart/compiler/DelegatingCompilerConfiguration.java b/compiler/java/com/google/dart/compiler/DelegatingCompilerConfiguration.java index 0ec62b1cc36..123afa9923b 100644 --- a/compiler/java/com/google/dart/compiler/DelegatingCompilerConfiguration.java +++ b/compiler/java/com/google/dart/compiler/DelegatingCompilerConfiguration.java @@ -33,11 +33,6 @@ public class DelegatingCompilerConfiguration implements CompilerConfiguration { return delegate.getPhases(); } - @Override - public List getBackends() { - return delegate.getBackends(); - } - @Override public CompilerMetrics getCompilerMetrics() { return delegate.getCompilerMetrics(); @@ -68,26 +63,11 @@ public class DelegatingCompilerConfiguration implements CompilerConfiguration { return delegate.incremental(); } - @Override - public File getOutputFilename() { - return delegate.getOutputFilename(); - } - @Override public File getOutputDirectory() { return delegate.getOutputDirectory(); } - @Override - public boolean checkOnly() { - return delegate.checkOnly(); - } - - @Override - public boolean expectEntryPoint() { - return delegate.expectEntryPoint(); - } - @Override public LibrarySource getSystemLibraryFor(String importSpec) { return delegate.getSystemLibraryFor(importSpec); diff --git a/compiler/java/com/google/dart/compiler/LibrarySource.java b/compiler/java/com/google/dart/compiler/LibrarySource.java index 395f7168f13..1d2ab24bbb3 100644 --- a/compiler/java/com/google/dart/compiler/LibrarySource.java +++ b/compiler/java/com/google/dart/compiler/LibrarySource.java @@ -8,12 +8,11 @@ import java.io.IOException; /** * Abstract interface to library source. - * - * TODO(jgw): Consider requiring implementors to intern LibrarySource instances - * so that users can depend upon reference equality to avoid cycles (or require - * them to use .equals()). As it is, there are two pieces of code in - * DartCompiler and one in JavascriptBackend that do this manually, and it's a - * little tricky. + * + * TODO(jgw): Consider requiring implementors to intern LibrarySource instances so that users can + * depend upon reference equality to avoid cycles (or require them to use .equals()). As it is, + * there are two pieces of code in {@link DartCompiler} that do this manually, and it's a little + * tricky. */ public interface LibrarySource extends Source { diff --git a/compiler/java/com/google/dart/compiler/SubSystem.java b/compiler/java/com/google/dart/compiler/SubSystem.java index 6868abb209b..c85755d0c15 100644 --- a/compiler/java/com/google/dart/compiler/SubSystem.java +++ b/compiler/java/com/google/dart/compiler/SubSystem.java @@ -8,5 +8,5 @@ package com.google.dart.compiler; * Subsystem of compiler. */ public enum SubSystem { - COMPILER, PARSER, STATIC_TYPE, RESOLVER, NORMALIZE, CODE_GEN, JS_BACKEND, CLOSURE_BACKEND + COMPILER, PARSER, STATIC_TYPE, RESOLVER } \ No newline at end of file diff --git a/compiler/java/com/google/dart/compiler/ast/CoverageInstrumenter.java b/compiler/java/com/google/dart/compiler/ast/CoverageInstrumenter.java deleted file mode 100644 index b1ef94c1ce5..00000000000 --- a/compiler/java/com/google/dart/compiler/ast/CoverageInstrumenter.java +++ /dev/null @@ -1,807 +0,0 @@ -package com.google.dart.compiler.ast; - -import java.math.BigInteger; -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.google.dart.compiler.common.SourceInfo; -import com.google.dart.compiler.CommandLineOptions.CompilerOptions; -import com.google.dart.compiler.CompilerConfiguration; - -/** - * CoverageInstrumenter contains specialized instrumenters to perform specific - * instrumentation for obtaining coverage of different program entities - */ -public class CoverageInstrumenter { - private List instrumenters; - private static final String[] ignoredLibs = { "corelib", "corelib_impl", - "dom", "html", "htmlimpl", "base", "touch", "view", "utilslib", - "observable", "layout.dart", "unittest", "dartest" }; - - private static final String functionCoverage = "function"; - private static final String statementCoverage = "statement"; - private static final String branchCoverage = "branch"; - private static final String allCoverage = "all"; - - // Only createInstance should be used to instantiate this class - private CoverageInstrumenter() { - } - - /** - * Method to instantiate a CoverageInstrumenter containing multiple - * instrumenters created based on command line flags. - * - * @param config - * @return instance of this class - */ - public static CoverageInstrumenter createInstance( - CompilerConfiguration config) { - - CompilerOptions compilerOptions = config.getCompilerOptions(); - String coverageTypes = compilerOptions.getCoverageType(); - - CoverageInstrumenter instr = new CoverageInstrumenter(); - if (!"".equals(coverageTypes)) { - String outDir = compilerOptions.getWorkDirectory() - .getAbsolutePath(); - instr.createInstrumenters(coverageTypes, outDir); - } - return instr; - } - - /** - * Performs instrumentation of all classes - * - * @param libraries - */ - public void process(Map libraries) { - - if (instrumenters == null) { - return; - } - - // Instrument all dart units - for (LibraryUnit lib : libraries.values()) { - for (DartUnit unit : lib.getUnits()) { - exec(unit); - } - } - - // Populate totals and initialize coverage - for (LibraryUnit lib : libraries.values()) { - for (DartUnit unit : lib.getUnits()) { - init(unit); - } - } - } - - /** - * Runs all instrumenters on a particular Dart unit - * - * @param unit - */ - private void exec(DartUnit unit) { - if (isIgnored(unit)) { - return; - } - System.out.println("Instrumenting " + unit.getSourceName() + ", lib:" - + unit.getLibrary().getName()); - for (BaseInstrumenter instrumenter : instrumenters) { - instrumenter.accept(unit); - } - } - - /** - * Ignores a Dart unit based on the library it belongs to - * - * @param unit - * @return true is the unit should be ignored - */ - private boolean isIgnored(DartUnit unit) { - LibraryUnit lu = unit.getLibrary(); - if (lu != null) { - String libName = lu.getName(); - for (String ignoredLib : ignoredLibs) { - if (ignoredLib.equals(libName)) { - return true; - } - } - } - return false; - } - - /** - * Runs the TotalSettingInstrumenter on the supplied Dart unit, which adds - * totals of all coverable program entities - * - * @param unit - */ - private void init(DartUnit unit) { - if (isIgnored(unit)) { - return; - } - new TotalSettingInstrumenter().accept(unit); - } - - /** - * Factory method to create instrumenters based on supplied command line - * configuration - * - * @param coverageTypes - * @param outDir - */ - private void createInstrumenters(String coverageTypes, String outDir) { - BaseInstrumenter.setOutDir(outDir); - instrumenters = new ArrayList(); - if (coverageTypes.length() > 0) { - for (String covType : coverageTypes.split(",")) { - if (allCoverage.equals(covType)) { - instrumenters.add(new StatementInstrumenter()); - instrumenters.add(new FunctionInstrumenter()); - instrumenters.add(new BranchInstrumenter()); - } - if (statementCoverage.equals(covType)) { - instrumenters.add(new StatementInstrumenter()); - } - if (functionCoverage.equals(covType)) { - instrumenters.add(new FunctionInstrumenter()); - } - if (branchCoverage.equals(covType)) { - instrumenters.add(new BranchInstrumenter()); - } - } - } - } - - /** - * The Base Instrumenter class that provides some common functionalities to - * all Instrumenters - */ - private static class BaseInstrumenter extends DartModVisitor { - // TODO: Switch to DartNodeTraverser - private static String outputDir; - protected DartUnit currentUnit; - protected static Set unitsVisited = new HashSet(); - protected static Map numFunctionsMap = - new HashMap(); - protected static Map numStatementsMap = - new HashMap(); - protected static Map numBranchesMap = - new HashMap(); - - public static void setOutDir(String outDir) { - outputDir = outDir; - } - - @Override - public boolean visit(DartUnit x, DartContext ctx) { - currentUnit = x; - unitsVisited.add(x.getSourceName()); - return super.visit(x, ctx); - } - - /** - * Prepend a function call to a Dart block, which is a body of a - * function. - * - * @param oldBody - * @param functionStmt - * @return - */ - protected DartBlock prependToFnBody(DartBlock oldBody, - DartExprStmt functionStmt) { - List blockStmts = new ArrayList(); - blockStmts.add(functionStmt); - if (oldBody != null) { - List stmts = oldBody.getStatements(); - if (stmts != null) { - blockStmts.addAll(stmts); - } - } - DartBlock newDB = new DartBlock(blockStmts); - if (oldBody != null) { - newDB.setSourceInfo(oldBody.getSourceInfo()); - } - return newDB; - } - - protected void replaceFunction(DartContext ctx, DartFunction x, - DartBlock newFnBody) { - DartFunction newFn = new DartFunction(x.getParams(), newFnBody, - x.getReturnTypeNode()); - newFn.setSourceInfo(x.getSourceInfo()); - ctx.replaceMe(newFn); - } - - protected DartExprStmt createFunctionCall(String functionName, - List args, DartNode oldNode) { - DartIdentifier funcName = new DartIdentifier(functionName); - DartUnqualifiedInvocation funcInvocation = new DartUnqualifiedInvocation( - funcName, args); - DartExprStmt functionStmt = new DartExprStmt(funcInvocation); - if (oldNode != null) { - SourceInfo sourceInfo = oldNode.getSourceInfo(); - setInstrumentedSourceInfo(functionStmt, sourceInfo); - setInstrumentedSourceInfo(funcInvocation, sourceInfo); - setInstrumentedSourceInfo(funcName, sourceInfo); - for (DartExpression arg : args) { - setInstrumentedSourceInfo(arg, sourceInfo); - } - } - return functionStmt; - } - - void setInstrumentedSourceInfo(DartNode node, SourceInfo info) { - node.setInstrumentedNode(true); - node.setSourceInfo(info); - } - } - - /** - * TotalSettingInstrumenter instruments the main function to initialize - * coverage variables and set totals for covered entities - */ - private class TotalSettingInstrumenter extends BaseInstrumenter { - - @Override - public boolean visit(DartFunction x, DartContext ctx) { - DartNode parent = x.getParent(); - if (parent instanceof DartMethodDefinition) { - String funcName = ((DartMethodDefinition) parent).getName() - .toString(); - if ("main".equals(funcName)) { - DartBlock newFnBody = x.getBody(); - - for (String unitName : unitsVisited) { - int numFunctions = nullCheckingUnBox(numFunctionsMap - .get(unitName)); - int numStatements = nullCheckingUnBox(numStatementsMap - .get(unitName)); - int numBranches = nullCheckingUnBox(numBranchesMap - .get(unitName)); - List args = new ArrayList(); - args.add(DartStringLiteral.get(unitName)); - args.add(DartIntegerLiteral.get(BigInteger - .valueOf(numFunctions))); - args.add(DartIntegerLiteral.get(BigInteger - .valueOf(numStatements))); - args.add(DartIntegerLiteral.get(BigInteger - .valueOf(numBranches))); - DartExprStmt callCovTotals = createFunctionCall( - "setCoverageTotals", args, newFnBody); - callCovTotals.setInstrumentedNode(true); - newFnBody = prependToFnBody(newFnBody, callCovTotals); - } - - replaceFunction(ctx, x, newFnBody); - } - } - return super.visit(x, ctx); - } - - int nullCheckingUnBox(Integer value) { - int ret = 0; - if (value != null) { - ret = value.intValue(); - } - return ret; - } - } - - /** - * FunctionInstrumenter adds instrumentation to track function coverage - */ - private class FunctionInstrumenter extends BaseInstrumenter { - - private int numFunctions; - - /** - * This visitor method transforms: - * - * myFunction(){ stmts; ... } - * - * to: - * - * myFunction(){ coverFunction('unit.dart', 'myFunction'); stmts; ... } - * - * TODO: Cover closures as well - */ - @Override - public boolean visit(DartFunction x, DartContext ctx) { - DartNode parent = x.getParent(); - if (parent instanceof DartMethodDefinition) { - String funcName = ((DartMethodDefinition) parent).getName() - .toString(); - DartBlock oldBody = x.getBody(); - List covArgs = new ArrayList(); - covArgs.add(DartStringLiteral.get(currentUnit.getSourceName())); - covArgs.add(DartStringLiteral.get(funcName)); - DartExprStmt callCovFunc = createFunctionCall("coverFunction", - covArgs, oldBody); - DartBlock newFnBody = prependToFnBody(oldBody, callCovFunc); - replaceFunction(ctx, x, newFnBody); - numFunctions++; - } - return super.visit(x, ctx); - } - - /** - * Initialize function counter - */ - @Override - public boolean visit(DartUnit x, DartContext ctx) { - numFunctions = 0; - return super.visit(x, ctx); - } - - /** - * Populate number of functions for current unit - */ - @Override - public void endVisit(DartUnit x, DartContext ctx) { - numFunctionsMap.put(currentUnit.getSourceName(), numFunctions); - super.endVisit(x, ctx); - } - - } - - /** - * StatementInstrumenter adds instrumentation before each statement to - * capture runtime coverage of that statement - */ - private class StatementInstrumenter extends BaseInstrumenter { - private int numStatements; - - /** - * Initialize statement counter - */ - @Override - public boolean visit(DartUnit x, DartContext ctx) { - numStatements = 0; - return super.visit(x, ctx); - } - - /** - * Populate number of statements for current unit - */ - @Override - public void endVisit(DartUnit x, DartContext ctx) { - numStatementsMap.put(currentUnit.getSourceName(), numStatements); - super.endVisit(x, ctx); - } - - /** - * This visitor method transforms: - * - * { stmts; ... } - * - * to: - * - * { coverStatement('unit.dart', lineNum1); stmt1; - * coverStatement('unit.dart', lineNum2); stmt2; - * ... } - * - */ - @Override - public boolean visit(DartBlock x, DartContext ctx) { - List newStmts = new ArrayList(); - for (DartStatement stmt : x.getStatements()) { - if (!stmt.isInstrumentedNode()) { - List covArgs = new ArrayList(); - covArgs.add(DartStringLiteral.get(currentUnit - .getSourceName())); - covArgs.add(DartIntegerLiteral.get(BigInteger.valueOf(stmt - .getSourceLine()))); - DartExprStmt callCoverStmt = createFunctionCall( - "coverStatement", covArgs, stmt); - newStmts.add(callCoverStmt); - } - newStmts.add(stmt); - numStatements++; - } - DartBlock newBlock = new DartBlock(newStmts); - ctx.replaceMe(newBlock); - return super.visit(x, ctx); - } - - } - - /** - * BranchInstrumenter captures runtime execution of each branch in the - * program by adding instrumentation at each branch point - */ - private class BranchInstrumenter extends BaseInstrumenter { - private int numBranches; - - @Override - public boolean visit(DartUnit x, DartContext ctx) { - numBranches = 0; - return super.visit(x, ctx); - } - - @Override - public void endVisit(DartUnit x, DartContext ctx) { - numBranchesMap.put(currentUnit.getSourceName(), numBranches); - super.endVisit(x, ctx); - } - - /** - * - * This visitor method transforms: - * - * if { stmts; ... } - * else { ... } - * - * to: - * - * if { coverBranch('unit.dart', lineNum1, startLineNum); stmts; ... } - * else { coverBranch('unit.dart', lineNum1, startLineNum); ... } - * - * A synthetic else is added to track the non-if branch if there is no else - * - * Post-order instrumentation is needed to handle nested ifs and - * synthetic else - */ - @Override - public void endVisit(DartIfStatement x, DartContext ctx) { - DartIfStatement newIfStmt; - DartStatement thenStmt = x.getThenStatement(); - DartStatement elseStmt = x.getElseStatement(); - - List newThen = doCallCoverBranch(thenStmt); - numBranches++; - if (thenStmt instanceof DartBlock) { - List stmts = ((DartBlock) thenStmt) - .getStatements(); - if (stmts != null) { - newThen.addAll(stmts); - } - } else { - newThen.add(thenStmt); - } - - if (elseStmt instanceof DartIfStatement) { - newIfStmt = new DartIfStatement(x.getCondition(), - new DartBlock(newThen), elseStmt); - } else { - List newElse; - if (elseStmt != null) { - newElse = doCallCoverBranch(elseStmt); - if (elseStmt instanceof DartBlock) { - List stmts = ((DartBlock) elseStmt) - .getStatements(); - if (stmts != null) { - newElse.addAll(stmts); - } - } else { - newElse.add(elseStmt); - } - } else { - // Although else block is missing, there is a branch which - // doesn't cover the IfStatement - // So, we need to add a synthetic else block to track that - newElse = doCallCoverBranch(x); - } - newIfStmt = new DartIfStatement(x.getCondition(), - new DartBlock(newThen), new DartBlock(newElse)); - numBranches++; - } - newIfStmt.setSourceInfo(x.getSourceInfo()); - ctx.replaceMe(newIfStmt); - super.endVisit(x, ctx); - } - - /** - * This method instruments all non-empty switch case blocks and the - * default block. It inserts a synthetic default statement if one - * doesn't exist. - * This visitor method transforms: - * - * switch(var a) { - * case a: ...; - * case b: ...; - * } - * - * to: - * - * switch(var a) { - * case a: coverBranch('unit.dart', lineNum1, startLineNum1); ...; - * case b: coverBranch('unit.dart', lineNum2, startLineNum2); ...; - * default: coverBranch('unit.dart', lineNum3, startLineNum3); ...; - * } - * - * The existing code ignores empty switch cases. - * - * For tracking branch on empty cases, this logic won't work directly - * since instrumenting empty cases will throw a FallThroughError at - * runtime. For achieving this, the switch needs to be transformed into - * an if. Its slightly complicated but here is what I think the - * transformation should be: - * - * switch(expr) { - * case 'a': // empty switch case - * case 'b': do1(); break; - * case 'c': do2(); break; - * default: doDefault(); - * } - * - * should be transformed to: - * - * var tmp = expr; - * if( (tmp == 'a' && coverBranch(..)) || (tmp == 'b' && - * coverBranch(..))) { - * do1(); - * } else if (tmp == 'a' && coverBranch(..)) { - * do2(); - * } else { - * coverBranch(..); - * doDefault(); - * } - * - * However, I don't see much value in covering empty cases and hence - * this was written like described. - */ - @Override - public void endVisit(DartSwitchStatement x, DartContext ctx) { - List newSwitchMembers = - new ArrayList(); - boolean hasDefault = false; - for (DartSwitchMember swMember : x.getMembers()) { - List stmts = doCallCoverBranch(swMember); - List oldStmts = swMember.getStatements(); - if (oldStmts == null || oldStmts.size() == 0) { - newSwitchMembers.add(swMember); - continue; // Ignore empty cases - } else { - stmts.addAll(oldStmts); - } - - assert (swMember instanceof DartCase || - swMember instanceof DartDefault); - - DartSwitchMember newMember; - if (swMember instanceof DartCase) { - newMember = new DartCase(((DartCase) swMember).getExpr(), - swMember.getLabel(), stmts); - } else { - hasDefault = true; - newMember = new DartDefault(swMember.getLabel(), stmts); - } - setInstrumentedSourceInfo(newMember, swMember); - newSwitchMembers.add(newMember); - numBranches++; - } - - if (!hasDefault) { - List statements = doCallCoverBranch(x); - DartSwitchMember defaultMember = new DartDefault(null, - statements); - newSwitchMembers.add(defaultMember); - numBranches++; - } - - DartSwitchStatement newSwitch = new DartSwitchStatement( - x.getExpression(), newSwitchMembers); - newSwitch.setSourceInfo(x.getSourceInfo()); - - ctx.replaceMe(newSwitch); - super.visit(x, ctx); - } - - /** - * The instrumentation is similar to if and switch. - * A synthetic finally block is inserted if not present. - */ - - @Override - public void endVisit(DartTryStatement x, DartContext ctx) { - DartBlock tryBlock = x.getTryBlock(), finallyBlock = x - .getFinallyBlock(); - List catchBlocks = x.getCatchBlocks(); - - List tryStmts = doCallCoverBranch(tryBlock); - if (tryBlock != null && tryBlock.getStatements() != null) { - tryStmts.addAll(tryBlock.getStatements()); - } - DartBlock newTryBlock = new DartBlock(tryStmts); - setInstrumentedSourceInfo(newTryBlock, tryBlock.getSourceInfo()); - numBranches++; - - List newCatchBlocks = null; - if (catchBlocks != null) { - newCatchBlocks = new ArrayList(); - for (DartCatchBlock cBlock : catchBlocks) { - DartBlock oldBlock = cBlock.getBlock(); - - List cBlockStmts = doCallCoverBranch(cBlock); - if (oldBlock != null && oldBlock.getStatements() != null) { - cBlockStmts.addAll(oldBlock.getStatements()); - } - DartBlock newBlock = new DartBlock(cBlockStmts); - setInstrumentedSourceInfo(newBlock, - oldBlock.getSourceInfo()); - - DartCatchBlock newCatchBlock = new DartCatchBlock(newBlock, - cBlock.getException(), cBlock.getStackTrace()); - setInstrumentedSourceInfo(newCatchBlock, - cBlock.getSourceInfo()); - - newCatchBlocks.add(newCatchBlock); - numBranches++; - } - } - - DartBlock newFinallyBlock = null; - if(finallyBlock != null){ - List finallyStmts = doCallCoverBranch(finallyBlock); - if(finallyBlock.getStatements() != null){ - finallyStmts.addAll(finallyBlock.getStatements()); - } - newFinallyBlock = new DartBlock(finallyStmts); - setInstrumentedSourceInfo(newFinallyBlock, - finallyBlock.getSourceInfo()); - } else { - List finallyStmts = doCallCoverBranch(x); - newFinallyBlock = new DartBlock(finallyStmts); - setInstrumentedSourceInfo(newFinallyBlock, x.getSourceInfo()); - } - numBranches++; - - DartTryStatement newTry = new DartTryStatement(tryBlock, - newCatchBlocks, newFinallyBlock); - ctx.replaceMe(newTry); - super.endVisit(x, ctx); - } - - /** - * Rewrite all loops in this block - * - * While loop is transformed from this: - * - * while(cond) { stmts; } - * - * to: - * - * loopBranchBefore('unit.dart', loopLine, loopStart); - * while(cond) { - * loopBranchInside('unit.dart', loopLine, loopStart); - * stmts; - * } - * coverLoopBranch('unit.dart', loopLine, loopStart); - * - * We track two branches for every loop - one that goes inside and one that - * doesn't execute the loop at all. This is tracked by resetting/setting - * a variable from loopBranchBefore and loopBranchInside, which is checked - * in coverLoopBranch to decide which branch was taken. - */ - @Override - public void endVisit(DartBlock x, DartContext ctx) { - List blockStmts = new ArrayList(); - for(DartStatement stmt : x.getStatements()) { - if(stmt instanceof DartForInStatement) { - doLoopBefore(stmt, blockStmts); - - DartForInStatement oldForIn = (DartForInStatement) stmt; - DartStatement setup = null; - if(oldForIn.introducesVariable()){ - setup = oldForIn.getVariableStatement(); - } else { - setup = new DartExprStmt(oldForIn.getIdentifier()); - } - DartBlock body = doLoopInside(stmt, oldForIn.getBody()); - DartForInStatement newForIn = - new DartForInStatement(setup, oldForIn.getIterable(), body); - setInstrumentedSourceInfo(newForIn, oldForIn.getSourceInfo()); - - doLoopAfter(stmt, blockStmts); - numBranches+=2; - } else if (stmt instanceof DartForStatement) { - doLoopBefore(stmt, blockStmts); - - DartForStatement oldFor = (DartForStatement) stmt; - DartBlock body = doLoopInside(stmt, oldFor.getBody()); - DartForStatement newFor = new DartForStatement(oldFor.getInit(), - oldFor.getCondition(), oldFor.getIncrement(), body); - setInstrumentedSourceInfo(newFor, oldFor.getSourceInfo()); - - doLoopAfter(stmt, blockStmts); - numBranches+=2; - } else if (stmt instanceof DartWhileStatement) { - doLoopBefore(stmt, blockStmts); - - DartWhileStatement oldWhile = (DartWhileStatement) stmt; - DartBlock body = doLoopInside(stmt, oldWhile.getBody()); - DartWhileStatement newWhile = - new DartWhileStatement(oldWhile.getCondition(), body); - setInstrumentedSourceInfo(newWhile, oldWhile.getSourceInfo()); - - doLoopAfter(stmt, blockStmts); - numBranches+=2; - } else if (stmt instanceof DartDoWhileStatement) { - doLoopBefore(stmt, blockStmts); - - DartDoWhileStatement oldDoWhile = (DartDoWhileStatement) stmt; - DartBlock body = doLoopInside(stmt, oldDoWhile.getBody()); - DartDoWhileStatement newDoWhile = - new DartDoWhileStatement(oldDoWhile.getCondition(), body); - setInstrumentedSourceInfo(newDoWhile, oldDoWhile.getSourceInfo()); - - doLoopAfter(stmt, blockStmts); - numBranches+=2; - } else { - blockStmts.add(stmt); - } - } - - super.visit(x, ctx); - } - - /** - * Adds function call to track coverage of a branch represented by - * blockNode - * - * @param blockNode - * @return - */ - private List doCallCoverBranch(DartNode blockNode) { - List newBlockStmts = new ArrayList(); - List covArgs = makeCoverageArgs(blockNode); - DartExprStmt callCoverBranch = createFunctionCall("coverBranch", - covArgs, blockNode); - newBlockStmts.add(callCoverBranch); - setInstrumentedSourceInfo(callCoverBranch, - blockNode.getSourceInfo()); - return newBlockStmts; - } - - private void doLoopBefore(DartNode loopNode, List stmts) { - List args = makeCoverageArgs(loopNode); - DartExprStmt callLoopBefore = - createFunctionCall("loopBranchBefore", args, loopNode); - stmts.add(callLoopBefore); - } - - private void doLoopAfter(DartNode loopNode, List stmts) { - List args = makeCoverageArgs(loopNode); - args.add(DartIntegerLiteral.get(BigInteger.valueOf( - loopNode.getSourceStart() + loopNode.getSourceLength()))); - DartExprStmt callLoopAfter = - createFunctionCall("coverLoopBranch", args, loopNode); - stmts.add(callLoopAfter); - } - - private DartBlock doLoopInside(DartNode loopNode, DartStatement body) { - List newBlockStmts = new ArrayList(); - List covArgs = makeCoverageArgs(loopNode); - DartExprStmt callCoverBranch = createFunctionCall("loopBranchInside", - covArgs, loopNode); - newBlockStmts.add(callCoverBranch); - setInstrumentedSourceInfo(callCoverBranch, - loopNode.getSourceInfo()); - - if(body instanceof DartBlock) { - newBlockStmts.addAll(((DartBlock) body).getStatements()); - } else { - newBlockStmts.add(body); - } - - return new DartBlock(newBlockStmts); - } - - private List makeCoverageArgs(DartNode blockNode) { - List covArgs = new ArrayList(); - covArgs.add(DartStringLiteral.get(currentUnit.getSourceName())); - covArgs.add(DartIntegerLiteral.get(BigInteger.valueOf(blockNode - .getSourceLine()))); - covArgs.add(DartIntegerLiteral.get(BigInteger.valueOf(blockNode - .getSourceStart()))); - return covArgs; - } - } - -} diff --git a/compiler/java/com/google/dart/compiler/ast/DartNode.java b/compiler/java/com/google/dart/compiler/ast/DartNode.java index 8c30143c89b..3761c1f303a 100644 --- a/compiler/java/com/google/dart/compiler/ast/DartNode.java +++ b/compiler/java/com/google/dart/compiler/ast/DartNode.java @@ -18,7 +18,6 @@ import java.util.List; public abstract class DartNode extends AbstractNode implements DartVisitable { private DartNode parent; - private boolean isInstrumentedNode; public final String toSource() { DefaultTextOutput out = new DefaultTextOutput(false); @@ -152,12 +151,4 @@ public abstract class DartNode extends AbstractNode implements DartVisitable { public String getObjectIdentifier(){ return super.toString(); } - - public boolean isInstrumentedNode() { - return isInstrumentedNode; - } - - public void setInstrumentedNode(boolean isInstrumentedNode) { - this.isInstrumentedNode = isInstrumentedNode; - } } diff --git a/compiler/java/com/google/dart/compiler/ast/viz/ConsoleWriter.java b/compiler/java/com/google/dart/compiler/ast/viz/ConsoleWriter.java index 5161563340b..961cb017fa9 100644 --- a/compiler/java/com/google/dart/compiler/ast/viz/ConsoleWriter.java +++ b/compiler/java/com/google/dart/compiler/ast/viz/ConsoleWriter.java @@ -1,18 +1,17 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. package com.google.dart.compiler.ast.viz; +import com.google.dart.compiler.ast.DartNode; +import com.google.dart.compiler.ast.DartUnit; + import java.io.IOException; import java.io.OutputStreamWriter; import java.util.HashMap; import java.util.Map; -import com.google.common.io.Closeables; -import com.google.dart.compiler.ast.DartNode; -import com.google.dart.compiler.ast.DartUnit; - /** * Write the AST in to System out. */ diff --git a/compiler/java/com/google/dart/compiler/ast/viz/DotWriter.java b/compiler/java/com/google/dart/compiler/ast/viz/DotWriter.java index 9a4fa71e96c..b0ad21504da 100644 --- a/compiler/java/com/google/dart/compiler/ast/viz/DotWriter.java +++ b/compiler/java/com/google/dart/compiler/ast/viz/DotWriter.java @@ -1,4 +1,4 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. @@ -110,10 +110,6 @@ public class DotWriter extends BaseASTWriter { style.append(", color=blue"); } - if(node.isInstrumentedNode()){ - style.append(", style=filled, fillcolor=yellow"); - } - return style.toString(); } diff --git a/compiler/java/com/google/dart/compiler/backend/dart/DartBackend.java b/compiler/java/com/google/dart/compiler/backend/dart/DartBackend.java deleted file mode 100644 index 1cbccf86c67..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/dart/DartBackend.java +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.dart; - -import com.google.common.io.CharStreams; -import com.google.common.io.Closeables; -import com.google.dart.compiler.Backend; -import com.google.dart.compiler.DartCompilerContext; -import com.google.dart.compiler.DartSource; -import com.google.dart.compiler.LibrarySource; -import com.google.dart.compiler.ast.DartToSourceVisitor; -import com.google.dart.compiler.ast.DartUnit; -import com.google.dart.compiler.ast.LibraryUnit; -import com.google.dart.compiler.resolver.CoreTypeProvider; -import com.google.dart.compiler.util.DefaultTextOutput; -import com.google.dart.compiler.util.TextOutput; - -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; -import java.util.Collection; - -/** - * A compiler backend that produces optimized Dart. - */ -public class DartBackend implements Backend { - - public static final String EXTENSION_DART = "opt.dart"; - - private static void packageLibs(Collection libraries, - Writer w, - DartCompilerContext context) - throws IOException { - for (LibraryUnit libUnit : libraries) { - for (DartUnit unit : libUnit.getUnits()) { - DartSource src = unit.getSource(); - if (src != null) { - Reader r = context.getArtifactReader(src, "", EXTENSION_DART); - boolean failed = true; - try { - CharStreams.copy(r, w); - failed = false; - } finally { - Closeables.close(r, failed); - } - } - } - } - } - - @Override - public boolean isOutOfDate(DartSource src, DartCompilerContext context) { - return context.isOutOfDate(src, src, EXTENSION_DART); - } - - @Override - public void compileUnit(DartUnit unit, DartSource src, - DartCompilerContext context, CoreTypeProvider typeProvider) throws IOException { - // Generate Javascript output. - TextOutput out = new DefaultTextOutput(false); - DartToSourceVisitor srcGenerator = new DartToSourceVisitor(out); - srcGenerator.accept(unit); - Writer w = context.getArtifactWriter(src, "", EXTENSION_DART); - boolean failed = true; - try { - w.write(out.toString()); - failed = false; - } finally { - Closeables.close(w, failed); - } - } - - @Override - public void packageApp(LibrarySource app, - Collection libraries, - DartCompilerContext context, - CoreTypeProvider typeProvider) throws IOException { - Writer out = context.getArtifactWriter(app, "", EXTENSION_DART); - boolean failed = true; - try { - // Emit the concatenated Javascript sources in dependency order. - packageLibs(libraries, out, context); - - // Emit entry point call. - // TODO: How does a dart app start? - // out.write(app.getEntryMethod() + "();"); - failed = false; - } finally { - Closeables.close(out, failed); - } - } - - @Override - public String getAppExtension() { - return EXTENSION_DART; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/AbstractJsBackend.java b/compiler/java/com/google/dart/compiler/backend/js/AbstractJsBackend.java deleted file mode 100644 index 231c1e9b6c8..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/AbstractJsBackend.java +++ /dev/null @@ -1,518 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.HashMultiset; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; -import com.google.common.collect.Multiset; -import com.google.common.io.Closeables; -import com.google.dart.compiler.Backend; -import com.google.dart.compiler.CommandLineOptions.CompilerOptions; -import com.google.dart.compiler.DartCompilerContext; -import com.google.dart.compiler.DartSource; -import com.google.dart.compiler.ast.DartClass; -import com.google.dart.compiler.ast.DartNode; -import com.google.dart.compiler.ast.DartUnit; -import com.google.dart.compiler.ast.LibraryNode; -import com.google.dart.compiler.ast.LibraryUnit; -import com.google.dart.compiler.backend.js.ast.JsBlock; -import com.google.dart.compiler.backend.js.ast.JsProgram; -import com.google.dart.compiler.metrics.DartEventType; -import com.google.dart.compiler.metrics.Tracer.TraceEvent; -import com.google.dart.compiler.metrics.Tracer; -import com.google.dart.compiler.resolver.ClassElement; -import com.google.dart.compiler.resolver.CoreTypeProvider; -import com.google.dart.compiler.resolver.MethodElement; -import com.google.dart.compiler.type.InterfaceType; -import com.google.dart.compiler.util.DefaultTextOutput; -import com.google.dart.compiler.util.TextOutput; - -import java.io.IOException; -import java.io.Writer; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.PriorityQueue; -import java.util.Set; - -/** - * Methods common to the ClosureJsBackend and JavascriptBackend. - * @author johnlenz@google.com (John Lenz) - */ -public abstract class AbstractJsBackend implements Backend { - - public static final String EXTENSION_JS = "js"; - public static final String EXTENSION_APP_JS = "app.js"; - - private static final String ROOT_PART_NAME = ""; - private static final String STATICS_PART_NAME = "$statics$"; - private static final String SEPARATOR_PART_NAME = "$seperator$"; - - protected final DartMangler mangler = new DollarMangler(); - - protected static class Part { - final LibraryUnit lib; - final DartUnit unit; - final String part; - final ClassElement element; - final ClassElement superElement; - - public Part(LibraryUnit lib, DartUnit unit, String part, - ClassElement element, ClassElement superElement) { - this.lib = lib; - this.unit = unit; - this.element = element; - this.part = part; - this.superElement = superElement; - } - - @Override - public int hashCode() { - if (element != null) { - return element.hashCode(); - } - final int prime = 31; - int result = 1; - result = prime * result + ((part == null) ? 0 : part.hashCode()); - result = prime * result + ((unit == null) ? 0 : unit.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Part other = (Part) obj; - if (element != null) { - return element.equals(other.element); - } - return unit.equals(other.unit) && part.equals(other.part); - } - } - - protected static interface DepsCallback { - void visitNative(LibraryUnit libUnit, LibraryNode node) throws IOException; - void visitPart(Part part) throws IOException; - } - - protected static class DependencyBuilder { - private final List parts; - private final Part staticSeparator = new Part(null, null, SEPARATOR_PART_NAME, null, null); - - static void build(LibraryUnit libUnit, DepsCallback callback) throws IOException { - DependencyBuilder builder = new DependencyBuilder(); - builder.gatherParts(libUnit); - builder.sortParts(); - builder.writeParts(callback); - } - - private DependencyBuilder() { - this.parts = new ArrayList(); - } - - private void gatherParts(LibraryUnit libUnit) { - gatherParts(libUnit, new HashSet()); - } - - private void gatherParts(LibraryUnit libUnit, Set seenLibs) { - // Avoid cycles. - if (seenLibs.contains(libUnit)) { - return; - } - seenLibs.add(libUnit); - - // Visit dependencies first. - for (LibraryUnit importUnit : libUnit.getImports()) { - gatherParts(importUnit, seenLibs); - } - - for (DartUnit unit : libUnit.getUnits()) { - DartSource src = unit.getSource(); - if (src != null) { - // get the list of source source parts - gatherUnitParts(libUnit, unit); - } - } - } - - private void gatherUnitParts(LibraryUnit libUnit, DartUnit unit) { - List nodes = ((DartUnit)unit.getNormalizedNode()).getTopLevelNodes(); - for (DartNode node : nodes) { - DartNode norm = node.getNormalizedNode(); - if (norm instanceof DartClass) { - DartClass clasz = (DartClass)norm; - ClassElement selfElement = clasz.getSymbol(); - InterfaceType superType = selfElement.getSupertype(); - ClassElement superElement = null; - if (superType != null) { - superElement = superType.getElement(); - assert(superElement != null); - } - - parts.add(new Part(libUnit, unit, - clasz.getClassName(), selfElement, superElement)); - } - } - - parts.add(new Part(libUnit, unit, ROOT_PART_NAME, null, null)); // top-level bits - parts.add(new Part(libUnit, unit, STATICS_PART_NAME, null, null)); // static initializer bits - } - - /** - * @param items The list of items to sort. - * @param deps A map of dependencies between items. - * @return A list of items in dependency order. - */ - private static List topologicalStableSort( - List items, Multimap deps) { - final Map originalIndex = Maps.newHashMap(); - for (int i = 0; i < items.size(); i++) { - originalIndex.put(items.get(i), i); - } - - PriorityQueue inDegreeZero = new PriorityQueue(items.size(), - new Comparator() { - @Override - public int compare(T a, T b) { - return originalIndex.get(a).intValue() - - originalIndex.get(b).intValue(); - } - }); - List result = Lists.newArrayList(); - - Multiset inDegree = HashMultiset.create(); - Multimap reverseDeps = ArrayListMultimap.create(); - Multimaps.invertFrom(deps, reverseDeps); - - // First, add all the inputs with in-degree 0. - for (T item : items) { - Collection itemDeps = deps.get(item); - inDegree.add(item, itemDeps.size()); - if (itemDeps.isEmpty()) { - inDegreeZero.add(item); - } - } - - // Then, iterate to a fixed point over the reverse dependency graph. - while (!inDegreeZero.isEmpty()) { - T item = inDegreeZero.remove(); - result.add(item); - for (T inWaiting : reverseDeps.get(item)) { - inDegree.remove(inWaiting, 1); - if (inDegree.count(inWaiting) == 0) { - inDegreeZero.add(inWaiting); - } - } - } - - return result; - } - - /** - * Build a map of dependencies between Parts. - * @param parts The parts to build dependencies from. - */ - private Multimap buildDependencyMap(List parts) { - // Add a Part to act as separator between class initialization - // and static initialization. Statics may depend on the classes - // being properly setup. - parts.add(staticSeparator); - - final Map elementToPartMap = Maps.newHashMap(); - for (Part part : parts) { - if (part.element != null) { - Part previous = elementToPartMap.put(part.element, part); - assert(previous == null); - } - } - - // Get the direct dependencies. - final Multimap deps = HashMultimap.create(); - for (Part part : parts) { - if (part.superElement != null) { - Part superPart = elementToPartMap.get(part.superElement); - assert(superPart != null); - deps.put(part, superPart); - } - - // Don't add a dependency on itself. - if (part != staticSeparator) { - if (part.part.equals(STATICS_PART_NAME)) { - // Push all statics after classes. - deps.put(part, staticSeparator); - } else { - // All classes before statics. - deps.put(staticSeparator, part); - } - } - } - return deps; - } - - /** - * Sort the parts based on their dependencies. - */ - private void sortParts() { - List unsortedParts = parts; - - Multimap deps = buildDependencyMap(unsortedParts); - List sortParts = topologicalStableSort(unsortedParts, deps); - - parts.clear(); - parts.addAll(sortParts); - } - - private long writeParts(DepsCallback callback) - throws IOException { - long charsWritten = 0; - Set seenLibs = new HashSet(); - for (Part part : parts) { - writePart(part, callback, seenLibs); - } - return charsWritten; - } - - private void writePart(Part part, DepsCallback callback, Set seenLibs) - throws IOException { - - // Don't try to do anything with the fake separator part. - if (part == staticSeparator) { - return; - } - - // Avoid cycles. - if (!seenLibs.contains(part.lib)) { - seenLibs.add(part.lib); - // Prepend all native JS for this library. - for (LibraryNode node : part.lib.getNativePaths()) { - callback.visitNative(part.lib, node); - } - } - - callback.visitPart(part); - } - } - - protected Map translateToJS(DartUnit unit, DartCompilerContext context, - CoreTypeProvider typeProvider) { - TraceEvent logEvent = - Tracer.canTrace() ? Tracer.start(DartEventType.TRANSLATE_TO_JS, "unit", - unit.getSourceName()) : null; - - try { - TraceEvent normalizeEvent = - Tracer.canTrace() ? Tracer.start(DartEventType.JS_NORMALIZE, "unit", - unit.getSourceName()) : null; - try { - // Normalize front-end AST for back-end consumption. - unit = (DartUnit) (new Normalizer()).exec(unit, typeProvider).getNormalizedNode(); - } finally { - Tracer.end(normalizeEvent); - } - - // TODO(floitsch.: Make namer configurable. - JsNamer namer = new JsPrettyNamer(); - - Map parts = new LinkedHashMap(); - - List topNodes = unit.getTopLevelNodes(); - - // Generate an id for this unit that can be used to make globally unique - // identifiers. - String baseUnitId = generateBaseUnitId(unit); - int partIndex = 0; - - // Translate the AST to JS. - JsProgram nonClassStatements = new JsProgram(baseUnitId + partIndex++); - GenerateJavascriptAST nonClassGenerator = null; - TranslationContext nonClassTranslationContext = null; - - JsProgram staticInitStatements = new JsProgram(baseUnitId + partIndex++); - JsBlock staticInitBlock = staticInitStatements.getGlobalBlock(); - - for (DartNode node : topNodes) { - node = node.getNormalizedNode(); - if (node instanceof DartClass) { - // TODO: Don't write out *.js for interfaces -- there are a lot of them - TraceEvent nodeEvent = - Tracer.canTrace() ? Tracer.start(DartEventType.TRANSLATE_NODE, "unit", - unit.getSourceName(), "node", node.getSymbol().getOriginalSymbolName()) : null; - try { - // Translate the AST to JS. - JsProgram program = new JsProgram(baseUnitId + partIndex++); - - TranslationContext translationContext = TranslationContext.createContext(unit, program, - mangler, node); - - // Generate the Javascript AST. - GenerateJavascriptAST generator = - new GenerateJavascriptAST(unit, typeProvider, context); - generator.translateNode(translationContext, node, staticInitBlock); - - TraceEvent namerEvent = - Tracer.canTrace() ? Tracer.start(DartEventType.NAMER, "unit", - unit.getSourceName()) : null; - try { - namer.exec(program); - } finally { - Tracer.end(namerEvent); - } - - parts.put(((DartClass) node).getClassName(), program); - } finally { - Tracer.end(nodeEvent); - } - } else { - - if (nonClassGenerator == null) { - // This block generates the AST used to generate for all non-class nodes at once - // and is saved for subsequent iterations. - TraceEvent genInitEvent = - Tracer.canTrace() ? Tracer.start(DartEventType.GEN_AST_INIT, "unit", - unit.getSourceName()) : null; - try { - nonClassTranslationContext = TranslationContext.createContext(unit, - nonClassStatements, mangler, null); - nonClassGenerator = new GenerateJavascriptAST(unit, typeProvider, context); - } finally { - Tracer.end(genInitEvent); - } - } - - nonClassGenerator.translateNode(nonClassTranslationContext, node, staticInitBlock); - } - } - - TraceEvent namerEvent = - Tracer.canTrace() ? Tracer.start(DartEventType.NAMER, "unit", unit.getSourceName()) - : null; - try { - namer.exec(nonClassStatements); - } finally { - Tracer.end(namerEvent); - } - - // Out-of-date checks rely on the root JS file existing, even if it is empty - parts.put(ROOT_PART_NAME, nonClassStatements); - - // Only add static parts if they are not empty - for (int i = 0; i < staticInitStatements.getFragmentCount(); ++i) { - if (!staticInitStatements.getFragmentBlock(i).getStatements().isEmpty()) { - parts.put(STATICS_PART_NAME, staticInitStatements); - break; - } - } - - return parts; - } finally { - Tracer.end(logEvent); - } - } - - private static String generateBaseUnitId(DartUnit unit) { - MessageDigest md; - try { - md = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - throw new AssertionError("Could not find MD5 digest"); - } - StringBuilder sb = new StringBuilder(); - byte[] md5 = md.digest(unit.getSource().getUri().toString().getBytes()); - // Only use the first 6 hex characters of the md5. - for (int i = 0; i < 3; i++) { - sb.append(Integer.toHexString((md5[i] & 0xf0) >> 4)); - sb.append(Integer.toHexString(md5[i] & 0xf)); - } - - return sb.toString(); - } - - protected int writeEntryPointCall(String entry, Writer out) throws IOException { - // Emit entry point call. - // TODO: Actually validate that this method exists. - // Small hack: the V8 arguments object is not an instance of Array. [].concat(arguments) - // copies the elements of the arguments and returns a proper array. - // However in Rhino this operation simply creates an array with 'arguments' as the first (and - // only) element. By calling "arguments.slice()" on it, a new array is returned, and the - // concatenation works again. - // TODO: Use a more robust check to test that the argument is - // array. - String entryPointCall = "RunEntry(" + entry + ", this.arguments ?" + - " (this.arguments.slice ? [].concat(this.arguments.slice())" + - " : this.arguments) : []);"; - out.write(entryPointCall); - return entryPointCall.length(); - } - - protected String getMangledEntryPoint(DartCompilerContext context) { - MethodElement entry = context.getApplicationUnit().getElement().getEntryPoint(); - if (entry == null) { - return null; - } - - return mangler.mangleEntryPoint(entry, context.getApplicationUnit().getElement()); - } - - @Override - public boolean isOutOfDate(DartSource src, DartCompilerContext context) { - return context.isOutOfDate(src, src, EXTENSION_JS); - } - - @Override - public void compileUnit(DartUnit unit, DartSource src, DartCompilerContext context, - CoreTypeProvider typeProvider) throws IOException { - // Translate the AST to JS. - Map parts = translateToJS(unit, context, typeProvider); - String srcName = src.getName(); - - for (Map.Entry entry : parts.entrySet()) { - // Generate Javascript output. - TextOutput out = new DefaultTextOutput(false); - JsToStringGenerationVisitor srcGenerator; - String name = entry.getKey(); - boolean failed = true; - Writer w; - - JsProgram program = entry.getValue(); - JsBlock globalBlock = program.getGlobalBlock(); - - TraceEvent srcEvent = - Tracer.canTrace() ? Tracer.start(DartEventType.JS_SOURCE_GEN, "src", srcName, "name", - name) : null; - try { - srcGenerator = new JsSourceGenerationVisitor(out); - - srcGenerator.accept(globalBlock); - w = context.getArtifactWriter(src, name, EXTENSION_JS); - try { - w.write(out.toString()); - failed = false; - } finally { - Closeables.close(w, failed); - } - } finally { - Tracer.end(srcEvent); - } - } - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/Cloner.java b/compiler/java/com/google/dart/compiler/backend/js/Cloner.java deleted file mode 100644 index b0dd804410e..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/Cloner.java +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright 2011, the Dart project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.InternalCompilerException; -import com.google.dart.compiler.backend.js.ast.JsArrayAccess; -import com.google.dart.compiler.backend.js.ast.JsArrayLiteral; -import com.google.dart.compiler.backend.js.ast.JsBinaryOperation; -import com.google.dart.compiler.backend.js.ast.JsBooleanLiteral; -import com.google.dart.compiler.backend.js.ast.JsConditional; -import com.google.dart.compiler.backend.js.ast.JsContext; -import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsFunction; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.google.dart.compiler.backend.js.ast.JsNew; -import com.google.dart.compiler.backend.js.ast.JsNullLiteral; -import com.google.dart.compiler.backend.js.ast.JsNumberLiteral; -import com.google.dart.compiler.backend.js.ast.JsObjectLiteral; -import com.google.dart.compiler.backend.js.ast.JsPostfixOperation; -import com.google.dart.compiler.backend.js.ast.JsPrefixOperation; -import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer; -import com.google.dart.compiler.backend.js.ast.JsRegExp; -import com.google.dart.compiler.backend.js.ast.JsStringLiteral; -import com.google.dart.compiler.backend.js.ast.JsThisRef; -import com.google.dart.compiler.backend.js.ast.JsVisitor; - -import java.util.ArrayList; -import java.util.List; -import java.util.Stack; - -/** - * Implements actual cloning logic. We rely on the JsExpressions to provide - * traversal logic. The {@link #stack} field is used to accumulate - * already-cloned JsExpression instances. One gotcha that falls out of this is - * that argument lists are on the stack in reverse order, so lists should be - * constructed via inserts, rather than appends. - */ -public class Cloner extends JsVisitor { - protected final Stack stack = new Stack(); - private boolean successful = true; - - /** - * @param expression - * @return Return a clone of the expression tree - */ - public static JsExpression clone(JsExpression expression) { - Cloner c = new Cloner(); - c.accept(expression); - return c.getExpression(); - } - - @Override - public void endVisit(JsArrayAccess x, JsContext ctx) { - JsArrayAccess newExpression = new JsArrayAccess(); - newExpression.setIndexExpr(stack.pop()); - newExpression.setArrayExpr(stack.pop()); - stack.push(newExpression); - } - - @Override - public void endVisit(JsArrayLiteral x, JsContext ctx) { - JsArrayLiteral toReturn = new JsArrayLiteral(); - List expressions = toReturn.getExpressions(); - int size = x.getExpressions().size(); - while (size-- > 0) { - expressions.add(0, stack.pop()); - } - stack.push(toReturn); - } - - @Override - public void endVisit(JsBinaryOperation x, JsContext ctx) { - JsBinaryOperation toReturn = new JsBinaryOperation(x.getOperator()); - toReturn.setArg2(stack.pop()); - toReturn.setArg1(stack.pop()); - stack.push(toReturn); - } - - @Override - public void endVisit(JsBooleanLiteral x, JsContext ctx) { - stack.push(x); - } - - @Override - public void endVisit(JsConditional x, JsContext ctx) { - JsConditional toReturn = new JsConditional(); - toReturn.setElseExpression(stack.pop()); - toReturn.setThenExpression(stack.pop()); - toReturn.setTestExpression(stack.pop()); - stack.push(toReturn); - } - - /** - * The only functions that would get be visited are those being used as - * first-class objects. - */ - @Override - public void endVisit(JsFunction x, JsContext ctx) { - // Set a flag to indicate that we cannot continue, and push a null so - // we don't run out of elements on the stack. - successful = false; - stack.push(null); - } - - /** - * Cloning the invocation allows us to modify it without damaging other call - * sites. - */ - @Override - public void endVisit(JsInvocation x, JsContext ctx) { - JsInvocation toReturn = new JsInvocation(); - List params = toReturn.getArguments(); - int size = x.getArguments().size(); - while (size-- > 0) { - params.add(0, stack.pop()); - } - toReturn.setQualifier(stack.pop()); - stack.push(toReturn); - } - - /** - * Do a deep clone of a JsNameRef. Because JsNameRef chains are shared - * throughout the AST, you can't just go and change their qualifiers when - * re-writing an invocation. - */ - @Override - public void endVisit(JsNameRef x, JsContext ctx) { - JsNameRef toReturn; - JsName name = x.getName(); - if (name != null) { - toReturn = new JsNameRef(name); - } else { - toReturn = new JsNameRef(x.getIdent()); - } - - if (x.getQualifier() != null) { - toReturn.setQualifier(stack.pop()); - } - stack.push(toReturn); - } - - @Override - public void endVisit(JsNew x, JsContext ctx) { - int size = x.getArguments().size(); - List arguments = new ArrayList(size); - while (size-- > 0) { - arguments.add(0, stack.pop()); - } - JsNew toReturn = new JsNew(stack.pop()); - toReturn.getArguments().addAll(arguments); - stack.push(toReturn); - } - - @Override - public void endVisit(JsNullLiteral x, JsContext ctx) { - stack.push(x); - } - - @Override - public void endVisit(JsNumberLiteral x, JsContext ctx) { - stack.push(x); - } - - @Override - public void endVisit(JsObjectLiteral x, JsContext ctx) { - JsObjectLiteral toReturn = new JsObjectLiteral(); - List inits = toReturn.getPropertyInitializers(); - - int size = x.getPropertyInitializers().size(); - while (size-- > 0) { - /* - * JsPropertyInitializers are the only non-JsExpression objects that we - * care about, so we just go ahead and create the objects in the loop, - * rather than expecting it to be on the stack and having to perform - * narrowing casts at all stack.pop() invocations. - */ - JsPropertyInitializer newInit = new JsPropertyInitializer(); - newInit.setValueExpr(stack.pop()); - newInit.setLabelExpr(stack.pop()); - - inits.add(0, newInit); - } - stack.push(toReturn); - } - - @Override - public void endVisit(JsPostfixOperation x, JsContext ctx) { - JsPostfixOperation toReturn = new JsPostfixOperation(x.getOperator()); - toReturn.setArg(stack.pop()); - stack.push(toReturn); - } - - @Override - public void endVisit(JsPrefixOperation x, JsContext ctx) { - JsPrefixOperation toReturn = new JsPrefixOperation(x.getOperator()); - toReturn.setArg(stack.pop()); - stack.push(toReturn); - } - - @Override - public void endVisit(JsRegExp x, JsContext ctx) { - stack.push(x); - } - - @Override - public void endVisit(JsStringLiteral x, JsContext ctx) { - stack.push(x); - } - - @Override - public void endVisit(JsThisRef x, JsContext ctx) { - stack.push(new JsThisRef()); - } - - public JsExpression getExpression() { - return (successful && checkStack()) ? stack.peek() : null; - } - - private boolean checkStack() { - if (stack.size() > 1) { - throw new InternalCompilerException("Too many expressions on stack"); - } - - return stack.size() == 1; - } -} - diff --git a/compiler/java/com/google/dart/compiler/backend/js/DartMangler.java b/compiler/java/com/google/dart/compiler/backend/js/DartMangler.java deleted file mode 100644 index 3848cd9fa32..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/DartMangler.java +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.parser.Token; -import com.google.dart.compiler.resolver.ClassElement; -import com.google.dart.compiler.resolver.Element; -import com.google.dart.compiler.resolver.FieldElement; -import com.google.dart.compiler.resolver.LibraryElement; -import com.google.dart.compiler.resolver.MethodElement; - -/** - * Mangles dart identifiers so that they don't conflict with JavaScript identifiers. - * This complements the JsScope infrastructure. The JsScope infrastructure deals with obfuscatable - * identifiers, whereas the DartMangler deals with non-obfuscatable identifiers. - */ -public interface DartMangler { - public static final String NEGATE_OPERATOR_NAME = "negate"; - - /** - * Mangles the given className, so that it does not clash with any global variable or other - * mangled identifiers. - * @return a String that identifies the class, and does not clash with any global variable. - */ - public String mangleClassName(ClassElement classElement); - @Deprecated - public String mangleClassNameHack(LibraryElement library, String str); - - /** - * Mangles the given constructor, so that it does not clash with any built-in JS property, - * initializers, factories or other mangled fields.
- * The given LibraryElement is used if the constructor is library private. - * @return a String that identifies the constructor, and does not clash with any global variable. - */ - public String mangleConstructor(String constructorName, LibraryElement currentLibrary); - - /** - * Returns a mangled identifier for the given method. - */ - public String mangleNativeMethod(MethodElement methodElement); - - /** - * Mangles the given initializer, so that it does not clash with any built-in JS property, - * factories, constructors or other mangled fields.
- * The given LibraryElement is used if the initializer is library private. - * @return a String that identifies the initializer, and does not clash with any global variable. - */ - public String createInitializerSyntax(String constructorName, LibraryElement currentLibrary); - - /** - * Mangles the given factory, so that it does not clash with any built-in JS property, - * constructors, initializers or other mangled fields.
- * Note that factories may be unrelated to the containing class. A class A can - * have a factory method returning an instance of class B. In this case - * className equals B.
- * The given LibraryElement is used if the factory is library private. - * - * @return a String that identifies the factory, and does not clash with any global variable. - */ - public String createFactorySyntax(String className, String constructorName, - LibraryElement currentlibrary); - - - /** - *

Returns a name for the given closure. The returned name does not - * clash with any global variable or other mangled identifiers.

- * The closure is identified by the closureIdentifier. Manglers are allowed to discard the - * closureName completely. - * - * @param closureIdentifier must be a valid identifier of the form [a-zA-Z]+[0-9]* - * @param closureName the closures short readable name. May be null. - * @return a String that identifies the hoisted closure, and does not clash with any global - * variable. - */ - public String createHoistedFunctionName(Element holder, - Element classMemberElement, - String closureIdentifier, - String closureName); - - /** - * Mangles the given field, so that it does not clash with any built-in JS property or other - * mangled fields or methods.
- * The given LibraryElement is used if the field is library private. - * @return a String that identifies the member, and does not clash with built-in JS properties. - */ - public String mangleField(FieldElement field, LibraryElement currentLibrary); - - /** - * Mangles the given method, so that it does not clash with any built-in JS property or other - * mangled fields or methods.
- * The given LibraryElement is used if the method is library private. - * @return a String that identifies the member, and does not clash with built-in JS properties. - */ - public String mangleMethod(MethodElement method, LibraryElement currentLibrary); - public String mangleMethod(String methodName, LibraryElement currentLibrary); - - /** - * Mangles the given method to its $named form. - * @return a String that identifies the named form of the member. - */ - public String mangleNamedMethod(MethodElement method, LibraryElement currentLibrary); - public String mangleNamedMethod(String methodName, LibraryElement currentLibrary); - - /** - * Mangles the given method to its _$lookupRTT form. - * @return a String that identifies the named form of the member. - */ - public String mangleRttLookupMethod(MethodElement method, LibraryElement currentLibrary); - public String mangleRttLookupMethod(String methodName, LibraryElement currentLibrary); - - /** - * Mangles the given method, so that it does not clash with any built-in JS property or other - * mangled fields or methods. This method is different than mangleMethod, as it returns - * the fully qualified mangled name. - * @return a String that identifies the entry, and does not clash with built-in JS properties. - */ - public String mangleEntryPoint(MethodElement method, LibraryElement library); - - /** - * @return the JavaScript property identifier for the given operation. - */ - public String createOperatorSyntax(Token token); - - /** - * @return the JavaScript property identifier for the given operation. - */ - public String createOperatorSyntax(String operation); - - /** - * @return the JavaScript getter property for the given member. - */ - public String createGetterSyntax(String member, LibraryElement currentLibrary); - public String createGetterSyntax(FieldElement member, LibraryElement currentLibrary); - public String createGetterSyntax(MethodElement member, LibraryElement currentLibrary); - - /** - * @return the JavaScript setter property for the given member. - */ - public String createSetterSyntax(String member, LibraryElement currentLibrary); - public String createSetterSyntax(FieldElement member, LibraryElement currentLibrary); -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/DollarMangler.java b/compiler/java/com/google/dart/compiler/backend/js/DollarMangler.java deleted file mode 100644 index 648a0d75d74..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/DollarMangler.java +++ /dev/null @@ -1,424 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.common.collect.ImmutableSet; -import com.google.dart.compiler.InternalCompilerException; -import com.google.dart.compiler.ast.LibraryUnit; -import com.google.dart.compiler.parser.Token; -import com.google.dart.compiler.resolver.ClassElement; -import com.google.dart.compiler.resolver.Element; -import com.google.dart.compiler.resolver.ElementKind; -import com.google.dart.compiler.resolver.FieldElement; -import com.google.dart.compiler.resolver.LibraryElement; -import com.google.dart.compiler.resolver.MethodElement; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Set; - -/** - * Mangles classes and members (including constructors and operators). - * These must be accessible from outside the compilation unit and must therefore have a - * predictable mangling. - * - *

Functions, constructors and initializers to become top-level functions. They - * cannot conflict with other members, but must not conflict with predefined JavaScript globals. - * - *

Other members (fields, operators, methods) are always accessed through an object. The mangler - * only needs to guard against conflicts with predefined JavaScript properties (like "prototype" - * and "__proto__"). - */ -public class DollarMangler implements DartMangler { - // TODO(floitsch): get rid of the blacklisted libraries. - // Libraries, where class-names must not include the library-name. - private static final Set BLACKLISTED_LIBRARIES = ImmutableSet.of("corelib", - "corelib_impl", "dom"); - - // Helpers for getters/setters/operator name mangling. - private static final String OPERATOR_SUFFIX = "$operator"; - private static final String GETTER_SUFFIX = "$getter"; - private static final String SETTER_SUFFIX = "$setter"; - private static final String FIELD_SUFFIX = "$field"; - private static final String METHOD_SUFFIX = "$member"; - private static final String NAMED_SUFFIX = "$named"; - private static final String CONSTRUCTOR_SUFFIX = "$Constructor"; - private static final String FACTORY_SUFFIX = "$Factory"; - private static final String INITIALIZER_SUFFIX = "$Initializer"; - - private static final String CLASS_SUFFIX = "$Dart"; - private static final String HOISTED_METHOD_SUFFIX = "$Hoisted"; - private static final String HOISTED_OPERATOR_SUFFIX = "$HoistedOperator"; - private static final String HOISTED_CONSTRUCTOR_SUFFIX = "$HoistedConstructor"; - private static final String HOISTED_STATIC_SUFFIX = "$HoistedStatic"; - private static final String DYNAMIC_CLASS_NAME = "$_Dynamic_"; - private static final String RTT_LOOKUP_NAME = "_$lookupRTT"; - - private static final String NATIVE_PREFIX = "native_"; - - private boolean isLibraryPrivate(String id) { - return (id.length() > 0) && (id.charAt(0) == '_'); - } - - private String attachSuffix(String name, String suffix, - boolean isLibraryPrivate, LibraryElement currentLibrary) { - if (isLibraryPrivate) { - return name + '$' + mangleLibraryName(currentLibrary) + suffix + '_'; - } - return name + suffix; - } - - private String attachSuffix(String name, String suffix, LibraryElement currentLibrary) { - return attachSuffix(name, suffix, isLibraryPrivate(name), currentLibrary); - } - - private String mangleLibraryName(LibraryElement element) { - LibraryUnit library = element.getLibraryUnit(); - if (isInBlacklist(library)) { - return ""; - } - - // TODO(floitsch): Replace this libraryName + md5(source) with something more enhanced. - - String libName = library.getName(); - if (libName == null || libName.isEmpty()) { - libName = "unnamed"; - } - - // If the libraryName is a path, cut off everything before the last slash. - int nameStart = libName.lastIndexOf('/') + 1; - - // add space for md5 + trailing '$' (and possible leading 'l'). - StringBuilder sb = new StringBuilder(libName.length() + 8); - - // see if we have a leading number, in which case need to prepend an alpha char - final char startChar = libName.charAt(nameStart); - if ('0' <= startChar && startChar <= '9') { - sb.append('l'); - } - sb.append(libName.substring(nameStart)); - - // Replace all non-word chars ([^a-z_A-Z0-9]) with "_". - replaceNonWordChars(sb); - - MessageDigest md; - try { - md = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - throw new AssertionError("Could not find MD5 digest"); - } - byte[] md5 = md.digest(library.getSource().getUri().toString().getBytes()); - // Only use the first 6 hex characters of the md5. - for (int i = 0; i < 3; i++) { - sb.append(Integer.toHexString((md5[i] & 0xf0) >> 4)); - sb.append(Integer.toHexString(md5[i] & 0xf)); - } - - sb.append("$"); - - return sb.toString(); - } - - /* - * Replace all non-word characters with an underscore - */ - private void replaceNonWordChars(StringBuilder sb) { - /* - * This code is implemented as a more efficient implementation than using - * String.replaceAll("\\W", "_") - */ - final int len = sb.length(); - for (int idx = 0; idx < len; idx++) { - final char ch = sb.charAt(idx); - if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'))) { - sb.setCharAt(idx, '_'); - } - } - } - - @Override - public String mangleClassName(ClassElement classElement) { - String className = !classElement.isDynamic() ? classElement.getName() : DYNAMIC_CLASS_NAME; - return mangleClassNameHack(classElement.getLibrary(), className); - } - - @Override - @Deprecated - public String mangleClassNameHack(LibraryElement library, String className) { - String libraryToken = library == null ? "" : mangleLibraryName(library); - return libraryToken + className + CLASS_SUFFIX; - } - - private boolean isInBlacklist(LibraryUnit libraryUnit) { - if (libraryUnit.getName() == null) { - return false; - } - if (BLACKLISTED_LIBRARIES.contains(libraryUnit.getName())) { - return true; - } - - // Libraries that use the new syntax (with no name) will have a URI for a name, e.g.: - // file://blah/blah/coreimpl.dart - for (String name : BLACKLISTED_LIBRARIES) { - if (libraryUnit.getName().endsWith(name)) { - return true; - } - } - return false; - } - - @Override - public String mangleConstructor(String constructorName, LibraryElement currentLibrary) { - return attachSuffix(constructorName, CONSTRUCTOR_SUFFIX, currentLibrary); - } - - @Override - public String createInitializerSyntax(String constructorName, LibraryElement currentLibrary) { - return attachSuffix(constructorName, INITIALIZER_SUFFIX, currentLibrary); - } - - @Override - public String createFactorySyntax(String className, String constructor, - LibraryElement currentLibrary) { - // We can't just return the constructor + suffix. - // A class might have factories for different classes. - String factoryName; - className = className.equals("") ? DYNAMIC_CLASS_NAME : className; - if (constructor.equals("")) { - factoryName = className + "$"; - } else { - factoryName = className + "$" + constructor + "$" + className.length(); - } - - return attachSuffix(factoryName, FACTORY_SUFFIX, isLibraryPrivate(constructor), currentLibrary); - } - - private boolean containsDollar(String str) { - return str.indexOf('$') >= 0; - } - - private String createHoistedFunctionName(String holderName, - String elementName, - String closureIdentifier, - String closureName, - String suffix) { - assert closureIdentifier.indexOf('$') == -1; - boolean containsDollar = containsDollar(holderName) - || containsDollar(elementName) - || (closureName != null && containsDollar(closureName)); - String result; - if (closureName != null) { - // Return a mangled id of the form: - // class$method$id$closure$$Hoisted, or - // class$method$id$closure$12_23_45$Hoisted (if any of the strings contains dollars). - result = holderName + "$" + elementName + "$" + closureIdentifier + "$" + closureName + "$"; - if (containsDollar) { - result += holderName.length() + "_" + elementName.length() + "_" - + closureIdentifier.length(); - } - } else { - // Return a mangled id of the form: - // class$method$id$$Hoisted, or - // class$method$id$12_23$Hoisted (if any of the strings contains dollars). - result = holderName + "$" + elementName + "$" + closureIdentifier + "$"; - if (containsDollar) { - result += holderName.length() + "_" + holderName.length(); - } - } - return result + suffix; - } - - @Override - public String createHoistedFunctionName(Element holder, - Element element, - String closureIdentifier, - String closureName) { - String holderName = ""; - switch (ElementKind.of(holder)) { - case CLASS: - holderName = mangleClassName((ClassElement) holder); - break; - - case LIBRARY: - holderName = mangleLibraryName((LibraryElement) holder); - break; - } - - String name = element.getName(); - String suffix; - switch (ElementKind.of(element)) { - case METHOD: - if (element.getModifiers().isOperator()) { - suffix = HOISTED_OPERATOR_SUFFIX; - if (!name.equals(NEGATE_OPERATOR_NAME)) { - name = Token.lookup(name).name(); - } - } else { - suffix = HOISTED_METHOD_SUFFIX; - } - break; - - case CONSTRUCTOR: - suffix = HOISTED_CONSTRUCTOR_SUFFIX; - break; - - default: - // Otherwise we are in a static initializer. - suffix = HOISTED_STATIC_SUFFIX; - } - return createHoistedFunctionName(holderName, name, closureIdentifier, closureName, - suffix); - } - - private String createFieldOrMethodBaseName(Element field, boolean accessor) { - String prefix = ""; - Element enclosing = field.getEnclosingElement(); - if (ElementKind.of(enclosing).equals(ElementKind.LIBRARY)) { - prefix = mangleLibraryName((LibraryElement) enclosing); - } else if (!accessor && field.getModifiers().isStatic()) { - prefix = mangleClassName((ClassElement) enclosing); - } - return prefix + field.getName(); - } - - @Override - public String mangleField(FieldElement field, LibraryElement currentLibrary) { - return attachSuffix(createFieldOrMethodBaseName(field, false), FIELD_SUFFIX, - isLibraryPrivate(field.getName()), currentLibrary); - } - - @Override - public String mangleMethod(MethodElement method, LibraryElement currentLibrary) { - String methodName = method.getName(); - if (method.getModifiers().isOperator()) { - methodName = createOperatorSyntax(methodName); - } else if (method.getModifiers().isGetter()) { - methodName = createGetterSyntax(methodName, currentLibrary); - } else if (method.getModifiers().isSetter()) { - methodName = createSetterSyntax(methodName, currentLibrary); - } else { - methodName = attachSuffix(methodName, METHOD_SUFFIX, currentLibrary); - } - - String prefix = ""; - if (ElementKind.of(method.getEnclosingElement()).equals(ElementKind.LIBRARY)) { - prefix = mangleLibraryName((LibraryElement) method.getEnclosingElement()); - } - return prefix + methodName; - } - - @Override - public String mangleNamedMethod(MethodElement method, LibraryElement currentLibrary) { - // There can be no named shims for operators, getters, or setters. - String methodName = method.getName(); - methodName = attachSuffix(methodName, NAMED_SUFFIX, currentLibrary); - - String prefix = ""; - if (ElementKind.of(method.getEnclosingElement()).equals(ElementKind.LIBRARY)) { - prefix = mangleLibraryName((LibraryElement) method.getEnclosingElement()); - } - return prefix + methodName; - } - - @Override - public String mangleNamedMethod(String methodName, LibraryElement currentLibrary) { - return attachSuffix(methodName, NAMED_SUFFIX, currentLibrary); - } - - @Override - public String mangleEntryPoint(MethodElement method, LibraryElement library) { - Element holder = method.getEnclosingElement(); - switch (ElementKind.of(holder)) { - case CLASS: - String mangledClassName = mangleClassName((ClassElement) holder); - return mangledClassName + "." + mangleMethod(method.getName(), library); - - case LIBRARY: - return mangleMethod(method, library); - } - throw new InternalCompilerException("Unknown entry point kind" + method); - } - - @Override - public String createGetterSyntax(FieldElement field, LibraryElement currentLibrary) { - return attachSuffix(createFieldOrMethodBaseName(field, true), GETTER_SUFFIX, - isLibraryPrivate(field.getName()), currentLibrary); - } - - @Override - public String createGetterSyntax(MethodElement field, LibraryElement currentLibrary) { - return attachSuffix(createFieldOrMethodBaseName(field, true), GETTER_SUFFIX, - isLibraryPrivate(field.getName()), currentLibrary); - } - - @Override - public String createSetterSyntax(FieldElement field, LibraryElement currentLibrary) { - return attachSuffix(createFieldOrMethodBaseName(field, true), SETTER_SUFFIX, - isLibraryPrivate(field.getName()), currentLibrary); - } - - @Override - public String mangleMethod(String methodName, LibraryElement currentLibrary) { - return attachSuffix(methodName, METHOD_SUFFIX, currentLibrary); - } - - private static String getNegateOperator() { - return NEGATE_OPERATOR_NAME + OPERATOR_SUFFIX; - } - - @Override - public String createOperatorSyntax(Token token) { - return token.name() + OPERATOR_SUFFIX; - } - - @Override - public String createOperatorSyntax(String operation) { - if (operation.equals(NEGATE_OPERATOR_NAME)) { - return getNegateOperator(); - } - return Token.lookup(operation).name() + OPERATOR_SUFFIX; - } - - @Override - public String createGetterSyntax(String member, LibraryElement currentLibrary) { - return attachSuffix(member, GETTER_SUFFIX, currentLibrary); - } - - @Override - public String createSetterSyntax(String member, LibraryElement currentLibrary) { - return attachSuffix(member, SETTER_SUFFIX, currentLibrary); - } - - @Override - public String mangleNativeMethod(MethodElement element) { - String elementName = element.getName(); - String encodedName = null; - if (element.getModifiers().isOperator()) { - if ("negate".equals(elementName)) { - encodedName = elementName; - } else { - encodedName = Token.lookup(elementName).name(); - } - } else if (element.getModifiers().isGetter()) { - encodedName = "get$" + elementName; - } else if (element.getModifiers().isSetter()) { - encodedName = "set$" + elementName; - } else { - encodedName = elementName; - } - String holderName = element.getEnclosingElement().getName(); - return NATIVE_PREFIX + holderName + "_" + encodedName; - } - - @Override - public String mangleRttLookupMethod(MethodElement method, LibraryElement currentLibrary) { - return mangleNamedMethod(method, currentLibrary) + RTT_LOOKUP_NAME; - } - - @Override - public String mangleRttLookupMethod(String methodName, LibraryElement currentLibrary) { - return mangleNamedMethod(methodName, currentLibrary) + RTT_LOOKUP_NAME; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java b/compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java deleted file mode 100644 index 2942b740588..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java +++ /dev/null @@ -1,3877 +0,0 @@ -// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.common.collect.Lists; -import com.google.dart.compiler.DartCompilationError; -import com.google.dart.compiler.DartCompilerContext; -import com.google.dart.compiler.InternalCompilerException; -import com.google.dart.compiler.ast.DartArrayAccess; -import com.google.dart.compiler.ast.DartArrayLiteral; -import com.google.dart.compiler.ast.DartAssertion; -import com.google.dart.compiler.ast.DartBinaryExpression; -import com.google.dart.compiler.ast.DartBlock; -import com.google.dart.compiler.ast.DartBooleanLiteral; -import com.google.dart.compiler.ast.DartBreakStatement; -import com.google.dart.compiler.ast.DartCase; -import com.google.dart.compiler.ast.DartCatchBlock; -import com.google.dart.compiler.ast.DartClass; -import com.google.dart.compiler.ast.DartClassMember; -import com.google.dart.compiler.ast.DartConditional; -import com.google.dart.compiler.ast.DartContinueStatement; -import com.google.dart.compiler.ast.DartDefault; -import com.google.dart.compiler.ast.DartDoWhileStatement; -import com.google.dart.compiler.ast.DartDoubleLiteral; -import com.google.dart.compiler.ast.DartEmptyStatement; -import com.google.dart.compiler.ast.DartExprStmt; -import com.google.dart.compiler.ast.DartExpression; -import com.google.dart.compiler.ast.DartField; -import com.google.dart.compiler.ast.DartFieldDefinition; -import com.google.dart.compiler.ast.DartForInStatement; -import com.google.dart.compiler.ast.DartForStatement; -import com.google.dart.compiler.ast.DartFunction; -import com.google.dart.compiler.ast.DartFunctionExpression; -import com.google.dart.compiler.ast.DartFunctionObjectInvocation; -import com.google.dart.compiler.ast.DartFunctionTypeAlias; -import com.google.dart.compiler.ast.DartIdentifier; -import com.google.dart.compiler.ast.DartIfStatement; -import com.google.dart.compiler.ast.DartImportDirective; -import com.google.dart.compiler.ast.DartInitializer; -import com.google.dart.compiler.ast.DartIntegerLiteral; -import com.google.dart.compiler.ast.DartInvocation; -import com.google.dart.compiler.ast.DartLabel; -import com.google.dart.compiler.ast.DartLibraryDirective; -import com.google.dart.compiler.ast.DartMapLiteral; -import com.google.dart.compiler.ast.DartMapLiteralEntry; -import com.google.dart.compiler.ast.DartMethodDefinition; -import com.google.dart.compiler.ast.DartMethodInvocation; -import com.google.dart.compiler.ast.DartNamedExpression; -import com.google.dart.compiler.ast.DartNativeBlock; -import com.google.dart.compiler.ast.DartNativeDirective; -import com.google.dart.compiler.ast.DartNewExpression; -import com.google.dart.compiler.ast.DartNode; -import com.google.dart.compiler.ast.DartNodeTraverser; -import com.google.dart.compiler.ast.DartNullLiteral; -import com.google.dart.compiler.ast.DartParameter; -import com.google.dart.compiler.ast.DartParameterizedTypeNode; -import com.google.dart.compiler.ast.DartParenthesizedExpression; -import com.google.dart.compiler.ast.DartPlainVisitor; -import com.google.dart.compiler.ast.DartPropertyAccess; -import com.google.dart.compiler.ast.DartRedirectConstructorInvocation; -import com.google.dart.compiler.ast.DartResourceDirective; -import com.google.dart.compiler.ast.DartReturnStatement; -import com.google.dart.compiler.ast.DartSourceDirective; -import com.google.dart.compiler.ast.DartStatement; -import com.google.dart.compiler.ast.DartStringInterpolation; -import com.google.dart.compiler.ast.DartStringLiteral; -import com.google.dart.compiler.ast.DartSuperConstructorInvocation; -import com.google.dart.compiler.ast.DartSuperExpression; -import com.google.dart.compiler.ast.DartSwitchStatement; -import com.google.dart.compiler.ast.DartSyntheticErrorExpression; -import com.google.dart.compiler.ast.DartSyntheticErrorStatement; -import com.google.dart.compiler.ast.DartThisExpression; -import com.google.dart.compiler.ast.DartThrowStatement; -import com.google.dart.compiler.ast.DartTryStatement; -import com.google.dart.compiler.ast.DartTypeExpression; -import com.google.dart.compiler.ast.DartTypeNode; -import com.google.dart.compiler.ast.DartTypeParameter; -import com.google.dart.compiler.ast.DartUnaryExpression; -import com.google.dart.compiler.ast.DartUnit; -import com.google.dart.compiler.ast.DartUnqualifiedInvocation; -import com.google.dart.compiler.ast.DartVariable; -import com.google.dart.compiler.ast.DartVariableStatement; -import com.google.dart.compiler.ast.DartWhileStatement; -import com.google.dart.compiler.ast.Modifiers; -import com.google.dart.compiler.backend.js.ScopeRootInfo.DartScope; -import com.google.dart.compiler.backend.js.ast.JsArrayLiteral; -import com.google.dart.compiler.backend.js.ast.JsBinaryOperation; -import com.google.dart.compiler.backend.js.ast.JsBinaryOperator; -import com.google.dart.compiler.backend.js.ast.JsBlock; -import com.google.dart.compiler.backend.js.ast.JsBreak; -import com.google.dart.compiler.backend.js.ast.JsCase; -import com.google.dart.compiler.backend.js.ast.JsCatch; -import com.google.dart.compiler.backend.js.ast.JsConditional; -import com.google.dart.compiler.backend.js.ast.JsContinue; -import com.google.dart.compiler.backend.js.ast.JsDefault; -import com.google.dart.compiler.backend.js.ast.JsDoWhile; -import com.google.dart.compiler.backend.js.ast.JsEmpty; -import com.google.dart.compiler.backend.js.ast.JsExprStmt; -import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsFor; -import com.google.dart.compiler.backend.js.ast.JsFunction; -import com.google.dart.compiler.backend.js.ast.JsIf; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsLabel; -import com.google.dart.compiler.backend.js.ast.JsLiteral; -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.google.dart.compiler.backend.js.ast.JsNew; -import com.google.dart.compiler.backend.js.ast.JsNode; -import com.google.dart.compiler.backend.js.ast.JsNullLiteral; -import com.google.dart.compiler.backend.js.ast.JsNumberLiteral; -import com.google.dart.compiler.backend.js.ast.JsObjectLiteral; -import com.google.dart.compiler.backend.js.ast.JsParameter; -import com.google.dart.compiler.backend.js.ast.JsPostfixOperation; -import com.google.dart.compiler.backend.js.ast.JsPrefixOperation; -import com.google.dart.compiler.backend.js.ast.JsProgram; -import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer; -import com.google.dart.compiler.backend.js.ast.JsReturn; -import com.google.dart.compiler.backend.js.ast.JsScope; -import com.google.dart.compiler.backend.js.ast.JsStatement; -import com.google.dart.compiler.backend.js.ast.JsStringLiteral; -import com.google.dart.compiler.backend.js.ast.JsSwitch; -import com.google.dart.compiler.backend.js.ast.JsSwitchMember; -import com.google.dart.compiler.backend.js.ast.JsThisRef; -import com.google.dart.compiler.backend.js.ast.JsThrow; -import com.google.dart.compiler.backend.js.ast.JsTry; -import com.google.dart.compiler.backend.js.ast.JsUnaryOperator; -import com.google.dart.compiler.backend.js.ast.JsValueLiteral; -import com.google.dart.compiler.backend.js.ast.JsVars; -import com.google.dart.compiler.backend.js.ast.JsVars.JsVar; -import com.google.dart.compiler.backend.js.ast.JsWhile; -import com.google.dart.compiler.common.SourceInfo; -import com.google.dart.compiler.common.Symbol; -import com.google.dart.compiler.parser.Token; -import com.google.dart.compiler.resolver.ClassElement; -import com.google.dart.compiler.resolver.ConstructorElement; -import com.google.dart.compiler.resolver.CoreTypeProvider; -import com.google.dart.compiler.resolver.Element; -import com.google.dart.compiler.resolver.ElementKind; -import com.google.dart.compiler.resolver.Elements; -import com.google.dart.compiler.resolver.EnclosingElement; -import com.google.dart.compiler.resolver.FieldElement; -import com.google.dart.compiler.resolver.LibraryElement; -import com.google.dart.compiler.resolver.MethodElement; -import com.google.dart.compiler.resolver.SuperElement; -import com.google.dart.compiler.resolver.VariableElement; -import com.google.dart.compiler.type.InterfaceType; -import com.google.dart.compiler.type.Type; -import com.google.dart.compiler.type.TypeKind; -import com.google.dart.compiler.type.Types; -import com.google.dart.compiler.util.AstUtil; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.Stack; -import java.util.concurrent.Callable; - -/** - * Visitor that generates a Javascript AST from an existing Dart AST. - */ -public class GenerateJavascriptAST { - private final DartCompilerContext context; - private final DartUnit unit; - private final CoreTypeProvider typeProvider; - - /** - * Generates the Javascript AST using the names created in {@link GenerateNamesAndScopes}. - */ - static class GenerateJavascriptVisitor - implements DartPlainVisitor, TraversalContextProvider { - - private static boolean isSuperCall(Symbol symbol) { - return ElementKind.of(symbol).equals(ElementKind.SUPER); - } - - /** - * Returns true for members that are static or should be treated - * as if the user had declared them as static. - */ - private static boolean isDeclaredAsStaticOrImplicitlyStatic(Element element) { - Modifiers modifiers = element.getModifiers(); - if (modifiers.isStatic()) { - // Member was actually declared static - return true; - } - - if (Elements.isTopLevel(element)) { - // Top level fields and methods are implicitly static - ElementKind elementKind = ElementKind.of(element); - return elementKind == ElementKind.FIELD || elementKind == ElementKind.METHOD; - } - - return false; - } - - /** - * The name of the javascript function used to intern compile time constants - */ - private static final String INTERN_CONST_FUNCTION = "$intern"; - - /** - * The name of the function used to lookup a id for a constant object - */ - private static final String DART_CONST_ID_JS_FUNC = "$dart_const_id"; - - /** - * The name of the method use to generate the id for an constant object - */ - private static final String CONST_ID_JS_METHOD_NAME = "$const_id"; - - private static final String STATIC_UNINITIALIZED = "static$uninitialized"; - private static final String STATIC_INITIALIZING = "static$initializing"; - private static final String ISOLATE_CURRENT = "isolate$current"; - private static final String ISOLATE_INITS = "isolate$inits"; - private static final String ISOLATE_DEFAULT_FACTORY = "default$factory"; - static final int MAX_SPECIALIZED_BIND_SCOPES = 3; - static final int MAX_SPECIALIZED_BIND_ARGS = 5; - private static final String ISOLATE_ISOLATE_FACTORY = "isolateFactory"; - private static final String ISOLATE_ISOLATE_FACTORY_GETTER = "getIsolateFactory"; - - private final JsScope globalScope; - private final JsBlock globalBlock; - private final List staticInit = Lists.newArrayList(); - private final Deque functionStack = new LinkedList(); - private final Deque> jsNewDeclarationsStack = new LinkedList>(); - private Element currentHolder; - private boolean inFactory = false; - private boolean inFactoryOrStaticContext = false; - private ScopeRootInfo currentScopeInfo; - private JsName traceCounter; - private final RuntimeTypeInjector rtt; - - private final TranslationContext translationContext; - private final DartCompilerContext context; - private final LibraryElement unitLibrary; - private final DartMangler mangler; - private final CoreTypeProvider typeProvider; - private final Types typeUtils; - - private final Deque catchVarStack = new ArrayDeque(); - - public GenerateJavascriptVisitor(DartUnit unit, DartCompilerContext context, - TranslationContext translationContext, - CoreTypeProvider typeProvider) { - this.context = context; - this.translationContext = translationContext; - this.typeProvider = typeProvider; - this.typeUtils = Types.getInstance(typeProvider); - this.unitLibrary = unit.getLibrary().getElement(); - - // Cache the mangler in a field since it is used frequently - mangler = translationContext.getMangler(); - - JsProgram program = translationContext.getProgram(); - globalScope = program.getScope(); - globalBlock = program.getGlobalBlock(); - // setup the global scope. - jsNewDeclarationsStack.push(new HashSet()); - currentHolder = unit.getLibrary().getElement(); - rtt = new RuntimeTypeInjector(this, typeProvider, translationContext, - context.getCompilerConfiguration().developerModeChecks(), mangler, unitLibrary); - } - - /** - * @param block The global block to add the static init statements too. - */ - public void addStaticInitsToBlock(JsBlock block) { - if (staticInit.isEmpty()) return; - JsFunction init = new JsFunction(globalScope); - JsBlock body = new JsBlock(); - body.getStatements().addAll(staticInit); - init.setBody(body); - staticInit.clear(); - - // All the static variable initialization code belonging to the - // current compilation unit is appended to the initialization - // list (isolate$inits) through Array.prototype.push. - JsNameRef pushRef = AstUtil.newNameRef(new JsNameRef(ISOLATE_INITS), "push"); - JsInvocation invokePush = AstUtil.newInvocation(pushRef); - invokePush.getArguments().add(init); - block.getStatements().add(new JsExprStmt(invokePush)); - } - - /** - * @return the JsScope that is used to create temporary Js-variables in the current scope. - */ - private JsScope getCurrentFunctionScope() { - return translationContext.getMethods().get(functionStack.peek()).getScope(); - } - - /** - * Adds the given name to the declarations-array. All names in the array will be declared at - * the beginning of the function. The same name can be registered multiple times. - * @param name - */ - private void registerForDeclaration(JsName name) { - jsNewDeclarationsStack.peek().add(name); - } - - - /** - * Creates a temporary variable but does not register it for var-declaration. - * @return the JsName of the temporary. - */ - private JsName createNonVarTempory() { - JsScope scope; - if (!functionStack.isEmpty()) { - scope = getCurrentFunctionScope(); - } else { - scope = globalScope; - } - return scope.declareTemporary(); - } - - /** - * Creates a temporary variable and registers it, so that an declaration statement is - * emitted. - * @return the JsName of the temporary. - */ - @Override - public JsName createTemporary() { - JsName temp = createNonVarTempory(); - registerForDeclaration(temp); - return temp; - } - - /** - * Returns the JsName for the given element. If the element is global and - * hasn't been declared yet, it is done now. - */ - private JsName getJsName(Symbol symbol) { - return translationContext.getNames().getName(symbol); - } - - /** - * Creates a JS function with JS calling conventions and a deterministic name - * so that it can be invoked from JS. The function will then forward - * the call to the given method (with Dart calling conventions). - */ - private void generateJsExportedFunction(MethodElement element, JsName name) { - JsFunction fn = new JsFunction(globalScope); - - JsNameRef dartTarget = makeMethodJsReference(element, name); - JsInvocation callIntoDart = AstUtil.newInvocation(dartTarget); - - List parameters = fn.getParameters(); - List arguments = callIntoDart.getArguments(); - for (VariableElement p : element.getParameters()) { - JsName parameter = fn.getScope().declareFreshName(p.getName()); - parameters.add(new JsParameter(parameter)); - arguments.add(parameter.makeRef()); - } - JsBlock jsBlock = new JsBlock(); - jsBlock.getStatements().add(new JsReturn(callIntoDart)); - jsBlock.setSourceRef(element.getNode()); - - fn.setBody(jsBlock); - - String exportedFunctionName = mangler.mangleNativeMethod(element); - JsName exportedFunctionJsName = globalScope.declareName(exportedFunctionName, - exportedFunctionName, - exportedFunctionName); - fn.setName(exportedFunctionJsName); - fn.setSourceRef(element.getNode()); - globalBlock.getStatements().add(fn.makeStmt()); - } - - /** - * Makes the default-constructor accessible under a deterministic name and - * with JavaScript calling conventions so that it can be invoked from JS. - */ - private void generateIsolateDefaultFactoryMember(MethodElement element, JsName funcName) { - JsName className = getJsName(element.getEnclosingElement()); - JsNameRef unmangledName = AstUtil.newNameRef(className.makeRef(), ISOLATE_DEFAULT_FACTORY); - JsNameRef factoryName = AstUtil.newNameRef(className.makeRef(), funcName); - JsBinaryOperation defaultAsg = AstUtil.newAssignment(unmangledName, factoryName); - defaultAsg.setSourceRef(element.getNode()); - globalBlock.getStatements().add(defaultAsg.makeStmt()); - } - - @Override - public JsNode visitClass(DartClass x) { - assert ElementKind.of(currentHolder).equals(ElementKind.LIBRARY) - : "Nested classes should be impossible"; - Element previousHolder = currentHolder; - currentHolder = x.getSymbol(); - - ClassElement classElement = x.getSymbol(); - JsName classJsName = getJsName(classElement); - - // If there is already a native class we must not create the JS function. - if (classElement.getNativeName() == null) { - JsFunction jsClass = new JsFunction(globalScope, classJsName).setSourceRef(x); - jsClass.setIsConstructor(true); - jsClass.setBody(new JsBlock()); - globalBlock.getStatements().add(jsClass.makeStmt()); - } - - if (classElement.isInterface()) { - rtt.generateRuntimeTypeInfo(x); - - // Emit only static final fields for interfaces. - for (Element member : classElement.getMembers()) { - if (ElementKind.of(member).equals(ElementKind.FIELD)) { - Modifiers modifiers = member.getModifiers(); - if (modifiers.isStatic() && !modifiers.isAbstractField()) { - assert modifiers.isFinal(); - generateField((FieldElement) member); - } - } - } - } else { - // Inherits. - if (x.getSuperSymbol() != null) { - JsNameRef superRef = getJsName(x.getSuperSymbol()).makeRef(); - JsInvocation inherits = AstUtil.newInvocation( - new JsNameRef("$inherits"), - classJsName.makeRef(), - superRef); - inherits.setSourceRef(x); - globalBlock.getStatements().add(inherits.makeStmt()); - } - - maybeInjectIsolateMethods(classElement); - rtt.generateRuntimeTypeInfo(x); - - List classMembers = new ArrayList(); - classMembers.addAll(classElement.getConstructors()); - for (Element element : classElement.getMembers()) { - classMembers.add(element); - } - - if (Elements.needsImplicitDefaultConstructor(classElement)) { - addImplicitDefaultConstructor(x, classElement, classMembers); - } - - for (Element member : classMembers) { - switch(ElementKind.of(member)) { - case METHOD: { - MethodElement methodElement = (MethodElement) member; - generateMethodDefinition(methodElement); - if (!methodElement.getModifiers().isOperator()) { - generateMethodGetter(methodElement); - } - break; - } - - case CONSTRUCTOR: - generateMethodDefinition((MethodElement) member); - break; - - case FIELD: - generateField((FieldElement) member); - break; - - default: - throw new AssertionError("Invalid member " + member); - } - } - - // TODO(johnlenz): should we create a stub method to catch - // class without const constructors? As is, the a non-const - // class with get the id of an "const Object". - if (hasConstConstructor(classElement)) { - makeConstIdMethod(classElement); - } - - // Add temporary variable declarations, if any. - // TODO(johnlenz): This isn't always correct: an incremental compile - // might reuse temps, which we don't want. However, static initializations - // (where the temps would be used) aren't quite right either yet. Double - // check this when its done. - Set temps = jsNewDeclarationsStack.peek(); - declareTempsInBlock(globalBlock, temps); - - // Clear the set for the next class. - temps.clear(); - } - - assert currentHolder == x.getSymbol() : "Unbalanced class visitation"; - currentHolder = previousHolder; - - return null; - } - - private void addImplicitDefaultConstructor(DartClass x, ClassElement classElement, - List classElementMembers) { - for (DartNode member : x.getMembers()) { - if (member instanceof DartMethodDefinition) { - DartMethodDefinition method = (DartMethodDefinition) member; - MethodElement symbol = method.getSymbol(); - if (symbol.isConstructor() && "".equals(symbol.getName())) { - classElementMembers.add(symbol); - } - } - } - } - - /** - * @param classElement - * - */ - private void maybeInjectIsolateMethods(ClassElement classElement) { - if (isIsolateClass(classElement)) { - // In order to construct an isolate in another worker, it must be - // referrable by name, this requires a top level method. - generateIsolateFactory(classElement); - - // ... and a way to get the factory from a isolate instance - generateIsolateFactoryGetter(classElement); - } - } - - private JsName getIsolateFactoryFunctionName(ClassElement classElement) { - String fnNameStr = getJsName(classElement).getShortIdent() + "$" + ISOLATE_ISOLATE_FACTORY; - return globalScope.declareName(fnNameStr); - } - - private JsNameRef getIsolateFactoryGetterName(ClassElement classElement) { - return AstUtil.newNameRef( - AstUtil.newPrototypeNameRef(getJsName(classElement).makeRef()), - ISOLATE_ISOLATE_FACTORY_GETTER); - } - - private void generateIsolateFactory(ClassElement classElement) { - // Create static factory function: - // function Foo$IsolateFactory() { - // return Foo.default$Factory(); - // } - - // Build the function - JsName fnName = getIsolateFactoryFunctionName(classElement); - - JsNameRef defaultFactory = AstUtil.newNameRef( - getJsName(classElement).makeRef(), ISOLATE_DEFAULT_FACTORY); - JsInvocation invokeFactory = AstUtil.newInvocation(defaultFactory); - - // TODO(johnlenz): Add runtime type information if necessary. - JsFunction factoryFn = AstUtil.newFunction(globalScope, fnName, null, - new JsReturn(invokeFactory)); - - globalBlock.getStatements().add(factoryFn.makeStmt()); - } - - private void generateIsolateFactoryGetter(ClassElement classElement) { - // Create static factory function: - // function Foo.prototype.getFactory() { - // return Foo$IsolateFactory; - // } - - // Build the function - JsName fnName = getIsolateFactoryFunctionName(classElement); - JsFunction getterFn = AstUtil.newFunction(globalScope, null, null, - new JsReturn(fnName.makeRef())); - - // Declare it. - JsExpression declStmt = AstUtil.newAssignment( - getIsolateFactoryGetterName(classElement), getterFn); - globalBlock.getStatements().add(declStmt.makeStmt()); - } - - private boolean isIsolateClass(ClassElement classElement) { - return false; - } - - /** - * Creates a $getter for a method of a class, returning $method as a closure - * bound to the current instance if it is an instance method. - */ - private void generateMethodGetter(MethodElement methodElement) { - // Generate a getter for method binding to a variable - boolean isTopLevel = Elements.isTopLevel(methodElement); - if (methodElement.getModifiers().isGetter() || methodElement.getModifiers().isSetter()) { - return; - } - JsNameRef classJsNameRef = isTopLevel ? null : - getJsName(methodElement.getEnclosingElement()).makeRef(); - String getterName = mangler.createGetterSyntax(methodElement, unitLibrary); - String methodName = methodElement.getName(); - JsName getterJsName = globalScope.declareName(getterName, getterName, methodName); - getterJsName.setObfuscatable(false); - String mangledMethodName = mangler.mangleNamedMethod(methodElement, unitLibrary); - JsNameRef mangledRttMethod = rtt.getRTTLookupMethodNameRef(methodElement); - JsFunction func = new JsFunction(globalScope); - JsNameRef getterJsNameRef; - if (isTopLevel || methodElement.getModifiers().isStatic()) { - // function() { - // var ret = $named; - // ret.$lookupRTT = $named_$lookupRTT; - // return ret; - // } - func.setBody(new JsBlock()); - List stmts = func.getBody().getStatements(); - JsName returnVar = func.getScope().declareFreshName("ret"); - getterJsNameRef = AstUtil.newNameRef(classJsNameRef, getterJsName); - stmts.add(AstUtil.newVar(null, returnVar, - AstUtil.newNameRef(classJsNameRef, mangledMethodName))); - JsBinaryOperation varLookup = AstUtil.newAssignment( - AstUtil.newNameRef(returnVar.makeRef(), "$lookupRTT"), - mangledRttMethod); - stmts.add(varLookup.makeStmt()); - stmts.add(new JsReturn(returnVar.makeRef())); - } else { - // function() { return $bind(.prototype.$named, - // $bind(.prototype.$named_$lookupRTT, this); } - JsNameRef prototypeRef = AstUtil.newPrototypeNameRef(classJsNameRef); - getterJsNameRef = AstUtil.newNameRef(prototypeRef, getterJsName); - JsExpression bindMethodCall = AstUtil.newInvocation(new JsNameRef("$bind"), - AstUtil.newNameRef(prototypeRef, mangledMethodName), - mangledRttMethod, new JsThisRef()); - func.setBody(AstUtil.newBlock(new JsReturn(bindMethodCall))); - } - - JsExpression asg; - if (isTopLevel) { - func.setName(getterJsNameRef.getName()); - asg = func; - } else { - func.setSourceRef(methodElement.getNode()); - asg = AstUtil.newAssignment(getterJsNameRef, func); - } - asg.setSourceRef(methodElement.getNode()); - globalBlock.getStatements().add(asg.makeStmt()); - } - - private boolean hasConstConstructor(ClassElement element) { - for (ConstructorElement ctr : element.getConstructors()) { - if (ctr.getModifiers().isConstant()) { - return true; - } - } - return false; - } - - private void makeConstIdMethod(ClassElement classElement) { - JsNameRef methodRef = makeConstIdMethodRef(classElement); - JsStatement decl = AstUtil.newAssignment(methodRef, - makeConstIdMethodFunction(classElement)).makeStmt(); - this.globalBlock.getStatements().add(decl); - } - - private JsNameRef makeConstIdMethodRef(ClassElement classElement) { - // Instance methods hang from the prototype. - JsNameRef qualifier = AstUtil.newPrototypeNameRef(getJsName(classElement).makeRef()); - JsNameRef methodRef = AstUtil.newNameRef(qualifier, CONST_ID_JS_METHOD_NAME); - return methodRef; - } - - private JsFunction makeConstIdMethodFunction(ClassElement classElement) { - JsFunction func = new JsFunction(this.globalScope); - // Make an id like: - // :field1:field2:...-:field1:field2:... - JsExpression idExpr = rtt.getRTTClassId(classElement); - for (Element member : classElement.getMembers()) { - if (member.getKind() == ElementKind.FIELD) { - if (!member.getModifiers().isStatic()) { - idExpr = addConstIdFieldExpr((FieldElement) member, idExpr); - } - } - } - idExpr = addConstIdSuperExpr(classElement, idExpr); - func.setBody(AstUtil.newBlock(new JsReturn(idExpr))); - return func; - } - - private JsExpression addConstIdFieldExpr( - FieldElement element, JsExpression prevPart) { - JsExpression qualifier = getGetterSetterQualifier(element); - JsName fieldJsName = getJsName(element); - JsNameRef ref = AstUtil.newNameRef(qualifier, fieldJsName); - - // example: prevPart + ":" + $const_id(this.field) - return add(prevPart, add(string(":"), - AstUtil.newInvocation(new JsNameRef(DART_CONST_ID_JS_FUNC), ref))); - } - - private JsExpression addConstIdSuperExpr(ClassElement element, JsExpression prevPart) { - InterfaceType superType = element.getSupertype(); - if (superType == null || superType.getElement().isObject()) { - // The root object doesn't add anything. - return prevPart; - } - JsNameRef superConstIdRef = makeConstIdMethodRef(superType.getElement()); - JsNameRef callRef = AstUtil.newNameRef(superConstIdRef, "call"); - JsInvocation superCall = AstUtil.newInvocation(callRef, new JsThisRef()); - - // example: prevPart + "-" + super.prototype.$const_id.call(this); - return add(prevPart, add(string("-"), superCall)); - } - - private JsExpression add(JsExpression first, JsExpression second) { - return new JsBinaryOperation(JsBinaryOperator.ADD, first, second); - } - - private void generateField(FieldElement element) { - generate(element.getNode()); - } - - private void generateMethodDefinition(MethodElement element) { - JsFunction func = (JsFunction) generate(element.getNode()); - - // makeMethod clears the name of the function. - JsName funcName = func.getName(); - makeMethod(element, func); - - // If the method is the default factory we add the same method under an unmangled name. - // This is necessary for the isolate code. - if (Elements.isNonFactoryConstructor(element) - && "".equals(element.getName()) - && func.getParameters().size() == 0 - && isIsolateClass((ClassElement)element.getEnclosingElement())) { - generateIsolateDefaultFactoryMember(element, funcName); - } - - // If the function is exported to JavaScript make it accessible under its - // (more or less) unmangled name. - DartMethodDefinition method = (DartMethodDefinition) element.getNode(); - DartBlock body = method.getFunction().getBody(); - if (element.getModifiers().isNative() && !(body instanceof DartNativeBlock)) { - generateJsExportedFunction(element, funcName); - } - } - - private void createInlinedClassConstructor(DartClass x) { - ClassElement classElement = x.getSymbol(); - assert classElement.getNativeName() == null; - JsName classJsName = getJsName(classElement); - JsFunction jsClass = new JsFunction(globalScope, classJsName).setSourceRef(x); - jsClass.setIsConstructor(true); - JsBlock block = new JsBlock(); - JsScope scope = new JsScope(globalScope, "temp"); - for (FieldElement fieldElement : getFieldsInClassHierarchy(classElement)) { - String fieldName = translationContext.getMangler().mangleField(fieldElement, unitLibrary); - JsNameRef fieldRef = AstUtil.newNameRef(new JsThisRef(), fieldName); - JsName paramName = scope.declareName("p$" + fieldName); - jsClass.getParameters().add(new JsParameter(paramName)); - JsBinaryOperation asg = AstUtil.newAssignment(fieldRef, new JsNameRef(paramName)); - block.getStatements().add(asg.makeStmt()); - } - jsClass.setBody(block); - globalBlock.getStatements().add(jsClass.makeStmt()); - } - - private List getFieldsInClassHierarchy(ClassElement classElement) { - InterfaceType current = classElement.getType(); - Stack classes = new Stack(); - while ((current != null) && !current.getElement().isObject()) { - classElement = current.getElement(); - classes.push(classElement); - current = classElement.getSupertype(); - } - List fields = Lists.newArrayList(); - while (!classes.isEmpty()) { - classElement = classes.pop(); - for (Element elem : classElement.getMembers()) { - Modifiers modifiers = elem.getModifiers(); - if (ElementKind.of(elem).equals(ElementKind.FIELD) && !modifiers.isStatic() - && !modifiers.isAbstractField()) { - fields.add((FieldElement) elem); - } - } - } - return fields; - } - - private void generateAbstractField(FieldElement fieldElement) { - if (fieldElement.getGetter() != null) { - generateMethodDefinition(fieldElement.getGetter()); - } - if (fieldElement.getSetter() != null) { - generateMethodDefinition(fieldElement.getSetter()); - } - } - - private void declareTempsInBlock(JsBlock block, Collection tempCollection) { - // Add temporary variable declarations, if any. - Iterator temps = tempCollection.iterator(); - if (temps.hasNext()) { - JsVars jsVars = new JsVars(); - while (temps.hasNext()) { - JsName name = temps.next(); - JsVars.JsVar jsVar = new JsVars.JsVar(name); - jsVars.insert(jsVar); - } - block.getStatements().add(0, jsVars); - } - } - - private List getInlineFieldInitializers(ConstructorElement element) { - List fieldInitializers = new ArrayList(); - Iterable classMembers = element.getEnclosingElement().getMembers(); - for (Element member : classMembers) { - Modifiers modifiers = member.getModifiers(); - if (!modifiers.isStatic() - && !modifiers.isAbstractField() - && ElementKind.of(member).equals(ElementKind.FIELD)) { - DartField field = (DartField) member.getNode(); - if (field.getValue() != null) { - fieldInitializers.add(field); - } - } - } - return fieldInitializers; - } - - private JsExpression generateInlineFieldInitializer(DartField field) { - JsNameRef fieldName = AstUtil.newNameRef(new JsThisRef(), getJsName(field.getSymbol())); - JsExpression initExpr = (JsExpression) generate(field.getValue()); - return AstUtil.newAssignment(fieldName, initExpr); - } - - /** - * For a constructor B whose super is A we generate: - * - * FactoryB() { - * var tmp = new B; - * InitB(tmp); - * BodyB(tmp); - * } - * - * BodyB() { - * BodyA(); - * } - * - * InitB() { - * InitA(); - * } - * - * This method creates the InitB method and adds the BodyA call in the BodyB method. - */ - private void addInitializers(DartMethodDefinition constructor, - JsFunction factory, - JsName tempVar) { - ConstructorElement element = (ConstructorElement) constructor.getSymbol(); - JsScope classMemberScope = translationContext.getMemberScopes().get(element.getEnclosingElement()); - JsName curClassJsName = getJsName(element.getEnclosingElement()); - - // Create the initializer function. - String constructorName = element.getName(); - String initName = mangler.createInitializerSyntax(constructorName, unitLibrary); - JsName initJsName = classMemberScope.declareName(initName, initName, constructorName); - // Initializers are called from other class (as part of the super initialization). - initJsName.setObfuscatable(false); - JsFunction initFunction = new JsFunction(globalScope, initJsName).setSourceRef(constructor); - initFunction.setBody(new JsBlock()); - - // Add the initializer as a member of the current class. - makeMethod(element, initFunction); - - // Add the parameters to the initializer function. - List params = constructor.getFunction().getParams(); - for (DartParameter p : params) { - initFunction.getParameters().add( - new JsParameter(getJsName(p.getNormalizedNode().getSymbol()))); - } - - // If there are initializers, or inline field initializers, populate the - // initializer function. - List initializers = constructor.getInitializers(); - List fieldInitializers = getInlineFieldInitializers(element); - - if (!initializers.isEmpty() || !fieldInitializers.isEmpty()) { - // TODO(johnlenz): move this block shares the some of the same setup - // and tear down as the visitFunction method. - - // Give the initializer expressions access to the function parameters - functionStack.push(constructor.getFunction()); - jsNewDeclarationsStack.push(new HashSet()); - - // Do the field inline initializers first. If there are any assignments in the initializer - // list, they will be the last assignments. - List jsInitializers = initFunction.getBody().getStatements(); - Iterator fieldIterator = fieldInitializers.iterator(); - while (fieldIterator.hasNext()) { - jsInitializers.add(generateInlineFieldInitializer(fieldIterator.next()).makeStmt()); - } - - DartInvocation initInvocation = null; - Iterator iterator = initializers.iterator(); - while (iterator.hasNext()) { - DartInitializer initializer = iterator.next(); - if (!initializer.isInvocation()) { - jsInitializers.add((JsStatement) generate(initializer)); - } else { - initInvocation = (DartInvocation) initializer.getValue(); - } - } - - JsInvocation constructorInvocation = maybeGenerateSuperOrRedirectCall(constructor); - if (constructorInvocation != null) { - // Call the super initializer function in the initializer. - // Compute the super constructor initializer to call. - ConstructorElement superElement = (ConstructorElement) initInvocation.getSymbol(); - // TODO(floitsch): it would be better if we had a js-name and not just a string. - // This way the debugging information would be better. - // We need to generate the JsName (for the initializer/factory) once only and store it - // in some hashtable. Then instead of reusing the mangler, we should reuse those JsNames. - // The debugging information would then contain a link from the property-access to the - // constructor. Without JsName the debugger just assumes we access some random property. - String mangledSuperConstructorName = - mangler.createInitializerSyntax(superElement.getName(), unitLibrary); - Element superClassElement = superElement.getEnclosingElement(); - JsNameRef superInitRef = AstUtil.newNameRef(getJsName(superClassElement).makeRef(), - mangledSuperConstructorName); - JsNameRef callRef = AstUtil.newNameRef(superInitRef, "call"); - JsInvocation superInitCall = AstUtil.newInvocation(callRef); - initFunction.getBody().getStatements().add(0, superInitCall.makeStmt()); - // TODO(floitsch): don't copy the arguments from the super call for the initializer call. - // This will evaluate side-effects twice, and we are reusing nodes (thereby creating a - // DAG instead of a tree). - superInitCall.getArguments().addAll(constructorInvocation.getArguments()); - } - - // Call the initializer in the factory. This must be executed - // before calling the super constructor: .$Initializer.call(this, ...) - JsNameRef initRef = AstUtil.newNameRef(curClassJsName.makeRef(), initJsName); - JsNameRef initCallRef = AstUtil.newNameRef(initRef, "call"); - JsInvocation initCall = AstUtil.newInvocation(initCallRef, tempVar.makeRef()); - for (DartParameter p : params) { - initCall.getArguments().add(getJsName(p.getNormalizedNode().getSymbol()).makeRef()); - } - - factory.getBody().getStatements().add(0, initCall.makeStmt()); - - // Dart does not have an implicit call to a super constructor. - - // Add temporary variable declarations, if any. - declareTempsInBlock(initFunction.getBody(), jsNewDeclarationsStack.pop()); - - // setup the scope alias for the init function - maybeAddFunctionScopeAlias( - currentScopeInfo.getScope(constructor.getFunction()), initFunction); - - // Remove the containing function scope. - functionStack.pop(); - } - } - - private void addSuperOrRedirectConstructorCall(DartMethodDefinition constructor) { - JsInvocation superCall = maybeGenerateSuperOrRedirectCall(constructor); - if (superCall != null) { - // If we have a super constructor call, add it as the first statement - // in the constructor body. - // .$Constructor.call(this, ...). - JsFunction constructorFunction = translationContext.getMethods().get(constructor.getFunction()); - constructorFunction.getBody().getStatements().add(0, superCall.makeStmt()); - } - } - - private JsInvocation maybeGenerateSuperOrRedirectCall(DartMethodDefinition constructor) { - // If there are initializers, populate the initializer function. - List initializers = constructor.getInitializers(); - if (!initializers.isEmpty()) { - for (DartInitializer init : initializers) { - if (init.isInvocation()) { - JsExprStmt statement = (JsExprStmt) generate(init); - if (statement != null) { - return (JsInvocation) statement.getExpression(); - } - } - } - } - return null; - } - - private JsNode generateConstructorDefinition(DartMethodDefinition x) { - assert currentScopeInfo == null : "Nesting a constructor in a method should be impossible"; - currentScopeInfo = ScopeRootInfo.makeScopeInfo(x, !shouldGenerateDeveloperModeChecks()); - ConstructorElement element = (ConstructorElement) x.getSymbol(); - ClassElement classElement = (ClassElement) element.getEnclosingElement(); - JsScope classMemberScope = translationContext.getMemberScopes().get(classElement); - String constructorName = element.getName(); - JsName curClassJsName = getJsName(classElement); - - JsFunction dartCtor = (JsFunction) generate(x.getFunction()); - - // Add the constructor as a member of the current class. - makeMethod(element, dartCtor); - - // Create the static factory function that allocates the object - // and calls the constructor. - // .ConstructorName$Factory = function (args ...) { - // var tmp = new (); - // tmp.$typeInfo = runtimeType; - // .ConstructorName$Constructor.call(tmp, args ...); - // return tmp; - // } - // Attaching the factory to is done outside this method. We just provide the - // factory-name ("ConstructorName$Factory" here). - - // The factory becomes a member of and should therefore be declared in the same - // scope as all other members. - String className = element.getConstructorType().getName(); - String factoryName = mangler.createFactorySyntax(className, constructorName, unitLibrary); - JsName factoryJsName = - classMemberScope.declareName(factoryName, factoryName, constructorName); - // Factories are globally accessible. - factoryJsName.setObfuscatable(false); - - JsFunction factoryFunction = new JsFunction(globalScope, factoryJsName).setSourceRef(x); - JsScope factoryScope = factoryFunction.getScope(); - - // We do the constructor invocation before we declare the temporary variable. This is - // necessary to ensure that the created temporary does not conflict with the parameters. - JsInvocation constructorInvocation = new JsInvocation(); - JsName constructorJsName = getJsName(element); - JsNameRef constructorRef = AstUtil.newNameRef(curClassJsName.makeRef(), constructorJsName); - constructorInvocation.setQualifier(AstUtil.newNameRef(constructorRef, "call")); - - // Add the arguments to the constructor invocation. Note that the constructor call is still - // missing the 'tmp' variable. We will add it later. - List params = x.getFunction().getParams(); - List jsArgNames = new ArrayList(); - for (DartParameter p : params) { - // TODO(ngeoffray): We should actually copy the arguments. See b/4424659. - JsName argName = getJsName(p.getNormalizedNode().getSymbol()); - jsArgNames.add(argName); - constructorInvocation.getArguments().add(argName.makeRef()); - } - - JsName tempVar = factoryScope.declareTemporary(); - // Add the 'tmp' var to the constructor call. - constructorInvocation.getArguments().add(0, tempVar.makeRef()); - - factoryFunction.setBody(AstUtil.newBlock( - constructorInvocation.makeStmt(), - new JsReturn(tempVar.makeRef()))); - - addInitializers(x, factoryFunction, tempVar); - rtt.maybeAddClassRuntimeTypeToConstructor(classElement, factoryFunction, tempVar.makeRef()); - JsNew jsNew = new JsNew(curClassJsName.makeRef()); - if (classElement.getNativeName() != null && x.getFunction().getBody() == null) { - /* - * For native classes with bodyless constructors, we pass the user-declared arguments of - * the factory method to the native "new" expression. - */ - List newArguments = jsNew.getArguments(); - for (JsName jsArgName : jsArgNames) { - newArguments.add(jsArgName.makeRef()); - } - } - factoryFunction.getBody().getStatements().add(0, AstUtil.newVar(x, tempVar, jsNew)); - - generateAll(x.getFunction().getParams(), factoryFunction.getParameters(), JsParameter.class); - - assert currentScopeInfo != null; - inFactory = false; - inFactoryOrStaticContext = false; - currentScopeInfo = null; - - return factoryFunction; - } - - private void generateInitializersInlined(DartMethodDefinition x, JsFunction factoryFunction, - JsScope factoryScope, JsName tempVar) { - ConstructorElement element = (ConstructorElement) x.getSymbol(); - JsName curClassJsName = getJsName(element.getEnclosingElement()); - Map initMap = new HashMap(); - JsExpression superInvocation = null; - for (DartInitializer init : x.getInitializers()) { - JsExpression initValue = (JsExpression) generate(init.getValue()); - if (init.isInvocation()) { - superInvocation = initValue; - continue; - } else { - assert ElementKind.of(init.getName().getTargetSymbol()).equals(ElementKind.FIELD); - FieldElement fieldElement = (FieldElement) init.getName().getTargetSymbol(); - initMap.put(fieldElement, initValue); - } - } - List stmts = Lists.newArrayList(); - JsNew jsNew = new JsNew(curClassJsName.makeRef()); - ClassElement classElement = (ClassElement) element.getEnclosingElement(); - for (FieldElement fieldElement : getFieldsInClassHierarchy(classElement)) { - String fieldName = translationContext.getMangler().mangleField(fieldElement, unitLibrary); - JsName tmp = factoryScope.declareName("init$" + fieldName); - JsExpression initValue = initMap.get(fieldElement); - if (initValue == null) { - DartField fieldNode = (DartField) fieldElement.getNode(); - if (fieldNode.getValue() != null) { - initValue = (JsExpression) generate(fieldNode.getValue()); - } else { - initValue = undefined(); - } - } - stmts.add(AstUtil.newVar(x, tmp, initValue)); - jsNew.getArguments().add(new JsNameRef(tmp)); - } - if (superInvocation != null) { - factoryFunction.getBody().getStatements().add(0, new JsExprStmt(superInvocation)); - } - stmts.add(AstUtil.newVar(x, tempVar, jsNew)); - factoryFunction.getBody().getStatements().addAll(0, stmts); - } - - @Override - public JsNode visitMethodDefinition(DartMethodDefinition x) { - assert x == x.getNormalizedNode(); - if (Elements.isNonFactoryConstructor(x.getSymbol())) { - return generateConstructorDefinition(x); - } - - assert currentScopeInfo == null : "Nested methods should be impossible"; - inFactory = x.getModifiers().isFactory(); - inFactoryOrStaticContext = isFactoryOrStaticContext(x.getModifiers()); - currentScopeInfo = ScopeRootInfo.makeScopeInfo(x, !shouldGenerateDeveloperModeChecks()); - - JsFunction func = (JsFunction) generate(x.getFunction()); - assert currentScopeInfo != null; - inFactory = false; - inFactoryOrStaticContext = false; - currentScopeInfo = null; - - if (Elements.isTopLevel(x.getSymbol())) { - JsFunction tramp = generateNamedParameterMethodTrampoline(x, func.getName().makeRef()); - String mangled = mangler.mangleNamedMethod(x.getSymbol(), unitLibrary); - JsName trampName = globalScope.declareName(mangled); - tramp.setName(trampName); - - globalBlock.getStatements().add(func.makeStmt()); - globalBlock.getStatements().add(tramp.makeStmt()); - - // special case for top level methods - rtt.generateRuntimeTypeInfo(x); - generateMethodGetter(x.getSymbol()); - } - - return func; - } - - private JsFunction generateNamedParameterMethodTrampoline(DartMethodDefinition method, - JsNameRef origJsName) { - boolean preserveThis = !(method.getModifiers().isStatic() || - method.getModifiers().isFactory() || - Elements.isTopLevel(method.getSymbol())); - - return generateNamedParameterTrampoline(method.getFunction(), origJsName, 0, preserveThis); - } - - private JsFunction generateNamedParameterTrampoline(DartFunction func, - JsNameRef origJsName, int numClosureScopes, boolean preserveThis) { - // function([$s0, $s1, ...], $n, $o, P0, P1, P2, P3, ...) { - JsFunction tramp = new JsFunction(globalScope); - JsScope scope = tramp.getScope(); - - // Create fresh parameters for the explicit and synthetic parameters. - boolean hasNamedParams = false; - List explicitJsParams = new ArrayList(); - for (DartParameter dartParam : func.getParams()) { - String paramName = ((DartIdentifier) dartParam.getName()).getTargetName(); - JsParameter param = new JsParameter(scope.declareName(paramName)); - explicitJsParams.add(param); - if (dartParam.getModifiers().isNamed()) { - hasNamedParams = true; - } - } - - List closureScopeParams = new ArrayList(); - for (int i = 0; i < numClosureScopes; ++i) { - JsParameter param = new JsParameter(scope.declareFreshName("$s" + i)); - closureScopeParams.add(param); - } - JsParameter countParam = new JsParameter(scope.declareFreshName("$n")); - JsParameter namedParam = new JsParameter(scope.declareFreshName("$o")); - - // Declare parameters in the proper order. - for (int i = 0; i < numClosureScopes; ++i) { - tramp.getParameters().add(closureScopeParams.get(i)); - } - tramp.getParameters().add(countParam); - tramp.getParameters().add(namedParam); - for (int i = 0; i < explicitJsParams.size(); ++i) { - tramp.getParameters().add(explicitJsParams.get(i)); - } - - JsBlock body = new JsBlock(); - tramp.setBody(body); - List stmts = body.getStatements(); - - if (hasNamedParams) { - // var seen = 0, def = 0; - JsName seen = scope.declareFreshName("seen"); - JsName def = scope.declareFreshName("def"); - stmts.add(AstUtil.newVar(null, seen, number(0))); - stmts.add(AstUtil.newVar(null, def, number(0))); - - // switch ($n) { - // case 1: P0 = $o.P0 ? (++seen, $o.P0) : null; // no default value - // case 2: P1 = $o.P1 ? (++seen, $o.P1) : (++def, DEFAULT); // explicit default value - // ... - // } - JsSwitch jsSwitch = new JsSwitch(); - jsSwitch.setExpr(countParam.getName().makeRef()); - for (int i = 0; i < func.getParams().size(); ++i) { - DartParameter param = func.getParams().get(i); - JsParameter jsParam = tramp.getParameters().get(i + 2 + numClosureScopes); - if (!param.getModifiers().isNamed()) { - continue; - } - - String paramNameStr = getPropNameForNamedParameter(jsParam); - JsExpression paramName = string(getPropNameForNamedParameter(jsParam)); - JsExpression ifExpr = AstUtil.in(null, paramName, namedParam.getName().makeRef()); - - JsExpression ppSeen = AstUtil.preinc(null, seen.makeRef()); - JsBinaryOperation thenExpr = AstUtil.comma(null, ppSeen, - AstUtil.newNameRef(namedParam.getName().makeRef(), paramNameStr)); - - DartExpression defaultValue = param.getDefaultExpr(); - JsExpression elseExpr = (defaultValue != null) - ? generateDefaultValue(defaultValue) - : undefined(); - JsExpression ppDef = AstUtil.preinc(null, def.makeRef()); - elseExpr = AstUtil.comma(null, ppDef, elseExpr); - - JsBinaryOperation asg = assign( - jsParam.getName().makeRef(), - new JsConditional(ifExpr, thenExpr, elseExpr)); - - jsSwitch.getCases().add(AstUtil.newCase(number(i), asg.makeStmt())); - } - if (jsSwitch.getCases().size() > 0) { - stmts.add(jsSwitch); - } - - // if ((seen != $o.count) || (seen + def + $n != TOTAL)) { - // $nsme(); - // } - { - JsBinaryOperation ifLeft = neq(seen.makeRef(), - AstUtil.newNameRef(namedParam.getName().makeRef(), "count")); - - JsExpression add1 = add(seen.makeRef(), def.makeRef()); - JsExpression add2 = add(add1, countParam.getName().makeRef()); - JsExpression ifRight = neq(add2, number(func.getParams().size())); - - JsExpression ifExpr = or(ifLeft, ifRight); - JsStatement thenStmt = AstUtil.newInvocation(new JsNameRef("$nsme")).makeStmt(); - - stmts.add(new JsIf(ifExpr, thenStmt, null)); - } - } else { - // if ($o.count || ($n != TOTAL)) { - // $nsme(); - // } - { - JsExpression ifExpr = - or(AstUtil.newNameRef(namedParam.getName().makeRef(), "count"), - neq(countParam.getName().makeRef(), number(func.getParams().size()))); - JsStatement thenStmt = AstUtil.newInvocation(new JsNameRef("$nsme")).makeStmt(); - - stmts.add(new JsIf(ifExpr, thenStmt, null)); - } - } - JsInvocation jsInvoke = AstUtil.newInvocation( - AstUtil.newNameRef(origJsName.getQualifier(), origJsName.getName())); - if (preserveThis) { - JsNameRef call = AstUtil.newNameRef(jsInvoke.getQualifier(), "call"); - jsInvoke = AstUtil.newInvocation(call, new JsThisRef()); - } - for (int i = 0; i < numClosureScopes; ++i) { - jsInvoke.getArguments().add(closureScopeParams.get(i).getName().makeRef()); - } - for (JsParameter jsParam : explicitJsParams) { - jsInvoke.getArguments().add(jsParam.getName().makeRef()); - } - stmts.add(new JsReturn(jsInvoke)); - - return tramp; - } - - private String mangleNamedParameterName(String name) { - return "$p_" + name; - } - - private String getPropNameForNamedParameter(JsParameter jsParam) { - return mangleNamedParameterName(jsParam.getName().getShortIdent()); - } - - private String getPropNameForNamedParameter(DartNamedExpression namedExpr) { - return mangleNamedParameterName(namedExpr.getName().getTargetName()); - } - - /** - * If necessary, add object holding aliases for any parameters - * captured by function closures. - */ - private void maybeAddFunctionScopeAlias(DartScope scope, JsFunction function) { - if (scope.definesClosureReferencedSymbols()) { - JsScope jsScope = function.getScope(); - JsBlock body = function.getBody(); - - // Example: - // function f(a,b) { ... } - // to: - // function f(a,b) {var s0={f:f,a:a,b:b} ... }; - JsObjectLiteral aliasInit = new JsObjectLiteral(); - for (Entry entry : scope.getSymbols().entrySet()) { - if (entry.getValue().isReferencedFromClosure()) { - JsName param = getJsName(entry.getKey()); - aliasInit.getPropertyInitializers().add( - new JsPropertyInitializer(string(param.getIdent()), new JsNameRef(param))); - } - } - - JsName aliasName = scope.getAliasForJsScope(jsScope); - // Scope objects are declared (in the JsScope) at first use. By construction scope-objects - // are only created when they are used. Therefore the scope-object must exist in the - // JsScope. - assert aliasName != null; - JsStatement aliasDecl = AstUtil.newVar(null, aliasName, aliasInit); - body.getStatements().add(0, aliasDecl); - } - } - - private JsName getTraceCounter() { - if (traceCounter == null) { - traceCounter = globalScope.declareTemporary(); - JsStatement counterDecl = AstUtil.newVar(null, traceCounter, number(0)); - globalBlock.getStatements().add(0, counterDecl); - } - return traceCounter; - } - - private JsNameRef makeMethodJsReference(Element element, JsName name) { - JsNameRef qualifier; - boolean isNonFactoryConstructor = Elements.isNonFactoryConstructor(element); - Modifiers modifiers = element.getModifiers(); - JsNameRef classJsName = getJsName(element.getEnclosingElement()).makeRef(); - if (modifiers.isStatic() || modifiers.isFactory() || isNonFactoryConstructor) { - // Static methods hang directly from the constructor. - qualifier = classJsName; - } else { - // Instance methods hang from the prototype. - qualifier = AstUtil.newPrototypeNameRef(classJsName); - } - - JsNameRef prop = AstUtil.newNameRef(qualifier, name); - // TODO(johnlenz): This should be the name node reference - prop.setSourceRef(element.getNode()); - return prop; - } - - private boolean isFactoryOrStaticContext(Modifiers modifiers) { - return modifiers.isFactory() || modifiers.isStatic(); - } - - /** - * Turns a method into a prototype assignment on the JS class. Clears the name from the given - * function. - */ - private void makeMethod(Element element, JsFunction func) { - if (element.getEnclosingElement().getKind().equals(ElementKind.CLASS)) { - JsNameRef prop = makeMethodJsReference(element, func.getName()); - func.setName(null); - JsBinaryOperation asg = AstUtil.newAssignment(prop, func); - - // TODO(johnlenz): This should be the stmt node reference - asg.setSourceRef(element.getNode()); - globalBlock.getStatements().add(asg.makeStmt()); - - // If it's a (non-operator, non-property) method, generate its named trampoline. - if (element.getKind().equals(ElementKind.METHOD) && !element.getModifiers().isOperator() - && !element.getModifiers().isGetter() && !element.getModifiers().isSetter()) { - // Declare the mangled trampoline's name in the same scope as its target. - String mangled = mangler.mangleNamedMethod((MethodElement) element, unitLibrary); - JsName namedName = prop.getName().getEnclosing().declareName(mangled); - JsNameRef namedProp = makeMethodJsReference(element, namedName); - - DartMethodDefinition method = (DartMethodDefinition) element.getNode(); - JsFunction tramp = generateNamedParameterMethodTrampoline(method, prop); - - asg = assign(namedProp, tramp); - globalBlock.getStatements().add(asg.makeStmt()); - - // Generate a lookup method after finally writing function / named tramp - assert currentScopeInfo == null : "Nested methods should be impossible"; - inFactory = element.getModifiers().isFactory(); - inFactoryOrStaticContext = isFactoryOrStaticContext(element.getModifiers()); - DartMethodDefinition x = (DartMethodDefinition) element.getNode(); - currentScopeInfo = ScopeRootInfo.makeScopeInfo(x, !shouldGenerateDeveloperModeChecks()); - rtt.generateRuntimeTypeInfo(x); - - assert currentScopeInfo != null; - inFactory = false; - inFactoryOrStaticContext = false; - currentScopeInfo = null; - } - } else { - globalBlock.getStatements().add(func.makeStmt()); - } - } - - private JsExpression getGetterSetterQualifier(Element element) { - if (isDeclaredAsStaticOrImplicitlyStatic(element)) { - // The mangler makes sure that the mangled version of static - // fields names encode the class name so we do not have to - // read the fields through the class function. - return new JsNameRef(ISOLATE_CURRENT); - } else if (Elements.isTopLevel(element)) { - return null; - } else { - return new JsThisRef(); - } - } - - /** - * Creates a getter that returns a JavaScript property. - */ - private void makePropertyGetter(FieldElement element) { - JsExpression qualifier = getGetterSetterQualifier(element); - JsName fieldJsName = getJsName(element); - JsNameRef ref = AstUtil.newNameRef(qualifier, fieldJsName); - makeGetter(element, ref); - } - - /** - * Creates a getter that returns a constant (simple) JavaScript value. - */ - private void makeConstantValueGetter(FieldElement element, JsExpression value) { - assert element.getModifiers().isFinal(); - makeGetter(element, value); - } - - private void makeGetter(FieldElement element, JsExpression expression) { - String getterName = mangler.createGetterSyntax(element, unitLibrary); - String fieldName = element.getName(); - JsName getterJsName = globalScope.declareName(getterName, getterName, fieldName); - getterJsName.setObfuscatable(false); - JsFunction func = new JsFunction(globalScope, getterJsName); - func.setBody(AstUtil.newBlock(new JsReturn(expression))); - makeMethod(element, func); - } - - /** - * Create a shim method for invoking a method through a field. Invoke the - * getter to get the field value, then apply the shim's arguments to - * the returned closure object. - */ - private void makeMethodCallThroughFieldShim(DartField x) { - FieldElement element = x.getSymbol(); - if (Elements.isTopLevel(element)) { - // Don't bother making a call-though-field shim for global methods. They're always - // statically resolved, so we'll never generate a call to one. - return; - } - - String shimName = mangler.mangleNamedMethod(element.getName(), unitLibrary); - String fieldName = element.getName(); - JsName shimJsName = globalScope.declareName(shimName, shimName, fieldName); - shimJsName.setObfuscatable(false); - JsFunction func = new JsFunction(globalScope, shimJsName); - JsExpression qualifier; - if (element.getModifiers().isStatic()) { - Element enclosingElement = element.getEnclosingElement(); - switch (enclosingElement.getKind()) { - case CLASS: - qualifier = AstUtil.newNameRef(null, - mangler.mangleClassName((ClassElement) enclosingElement)); - break; - case LIBRARY: - qualifier = null; - break; - default: - throw new InternalCompilerException( - "Unhandled type of static element making method shim."); - } - } else { - qualifier = getGetterSetterQualifier(element); - } - String getterName = mangler.createGetterSyntax(element, unitLibrary); - JsExpression expression = AstUtil.newInvocation(AstUtil.newNameRef(qualifier, getterName)); - expression = AstUtil.newNameRef(expression, "apply"); - expression = AstUtil.newInvocation(expression, new JsThisRef(), - AstUtil.newNameRef(null, "arguments")); - func.setBody(AstUtil.newBlock(new JsReturn(expression))); - makeMethod(element, func); - } - - /** - * Creates a getter method that lazily initializes the field (if necessary). - */ - private void makeInitializingGetter(FieldElement element, JsExpression initExpression) { - String getterName = mangler.createGetterSyntax(element, unitLibrary); - String fieldName = element.getName(); - JsName getterJsName = globalScope.declareName(getterName, getterName, fieldName); - getterJsName.setObfuscatable(false); - - JsFunction func = new JsFunction(globalScope, getterJsName); - JsScope scope = new JsScope(globalScope, "temp"); - - // Foo.x$getter = function() { - // var t0 = isolate$current.Foo$x; - // var t1 = $initializing; - // if (t0 === t1) throw "circular initialization"; - // if (t0 !== $uninitialized) return t0; - // isolate$current.Foo$x = t1; - // var t2 = ... // initialization expression - // isolate$current.Foo$x = t2; - // return t2; - // } - - JsExpression fieldQualifier = getGetterSetterQualifier(element); - JsName fieldJsName = getJsName(element); - - JsName t0 = scope.declareTemporary(); - JsName t1 = scope.declareTemporary(); - JsName t2 = scope.declareTemporary(); - - JsVars initializeT0 = AstUtil.newVar( - null, t0, AstUtil.newNameRef(fieldQualifier, fieldJsName)); - JsVars initializeT1 = AstUtil.newVar( - null, t1, new JsNameRef(STATIC_INITIALIZING)); - JsStatement checkIfCircular = new JsIf( - new JsBinaryOperation( - JsBinaryOperator.REF_EQ, - t0.makeRef(), - t1.makeRef()), - new JsThrow(string("circular initialization")), - null); - JsStatement checkIfInitialized = new JsIf( - new JsBinaryOperation( - JsBinaryOperator.REF_NEQ, - t0.makeRef(), - new JsNameRef(STATIC_UNINITIALIZED)), - new JsReturn(t0.makeRef()), - null); - JsStatement markField = AstUtil.newAssignment( - AstUtil.newNameRef(fieldQualifier, fieldJsName), t1.makeRef()).makeStmt(); - JsStatement initializeT2 = AstUtil.newVar( - null, t2, initExpression); - JsStatement initializeField = AstUtil.newAssignment( - AstUtil.newNameRef(fieldQualifier, fieldJsName), t2.makeRef()).makeStmt(); - JsStatement returnT2 = new JsReturn(t2.makeRef()); - - // Construct the method from the statements. - func.setBody(AstUtil.newBlock( - initializeT0, - initializeT1, - checkIfCircular, - checkIfInitialized, - markField, - initializeT2, - initializeField, - returnT2)); - makeMethod(element, func); - } - - /** - * Creates a setter and turns it into a prototype assignment on the - * JS class. - */ - private void makeSetter(FieldElement element) { - String fieldName = element.getName(); - String setterName = mangler.createSetterSyntax(element, unitLibrary); - JsName setterJsName = globalScope.declareName(setterName, setterName, fieldName); - setterJsName.setObfuscatable(false); - JsFunction func = new JsFunction(globalScope, setterJsName); - - JsScope scope = new JsScope(globalScope, "temp"); - JsName parameter = scope.declareTemporary(); - func.getParameters().add(0, new JsParameter(parameter)); - - JsExpression qualifier = getGetterSetterQualifier(element); - - JsName fieldJsName = getJsName(element); - JsNameRef ref = AstUtil.newNameRef(qualifier, fieldJsName); - JsBinaryOperation asg = AstUtil.newAssignment(ref, parameter.makeRef()); - func.setBody(AstUtil.newBlock(new JsExprStmt(asg))); - - makeMethod(element, func); - } - - @Override - public JsNode visitInitializer(DartInitializer x) { - JsExpression e = (JsExpression) generate(x.getValue()); - if (e != null && !x.isInvocation()) { - JsName fieldJsName = getJsName(x.getName().getTargetSymbol()); - assert fieldJsName != null : "Field name must have been resolved."; - JsNameRef field = AstUtil.newNameRef(new JsThisRef(), fieldJsName); - e = AstUtil.newAssignment(field, e); - e.setSourceRef(x); - } - return e != null ? new JsExprStmt(e) : null; - } - - @Override - public JsNode visitFieldDefinition(DartFieldDefinition node) { - assert ElementKind.of(currentHolder).equals(ElementKind.LIBRARY); - for (DartField field : node.getFields()) { - generateTopLevelField(field); - } - return null; - } - - private void generateTopLevelField(DartField field) { - if (field.getSymbol().getModifiers().isAbstractField()) { - generate(field.getAccessor()); - } else { - generate(field); - } - } - - @Override - public JsNode visitField(DartField x) { - makeMethodCallThroughFieldShim(x); - FieldElement element = x.getSymbol(); - Modifiers modifiers = element.getModifiers(); - if (modifiers.isAbstractField()) { - generateAbstractField(element); - return null; - } - - DartExpression initializer = x.getValue(); - JsExprStmt result = null; - - if (initializer != null || Elements.isTopLevel(element)) { - currentScopeInfo = ScopeRootInfo.makeScopeInfo(x, !shouldGenerateDeveloperModeChecks()); - inFactoryOrStaticContext = true; - - // There's an initializer, so emit an assignment statement. - JsNameRef fieldName; - if (isDeclaredAsStaticOrImplicitlyStatic(element)) { - JsExpression qualifier = getGetterSetterQualifier(element); - fieldName = AstUtil.newNameRef(qualifier, translationContext.getNames().getName(element)); - } else { - fieldName = AstUtil.newNameRef(new JsThisRef(), getJsName(element)); - } - - JsExpression initExpr; - if (initializer == null) { - initExpr = undefined(); - } else { - initExpr = (JsExpression) generate(initializer); - } - - boolean emitStaticInitialization = true; - if (x.getModifiers().isFinal() && - (initializer == null || initExpr instanceof JsValueLiteral)) { - makeConstantValueGetter(element, initExpr); - emitStaticInitialization = false; - } else if (initializer == null || initExpr instanceof JsLiteral) { - makePropertyGetter(element); - } else { - makeInitializingGetter(element, initExpr); - initExpr = new JsNameRef(STATIC_UNINITIALIZED); - } - - if (emitStaticInitialization) { - JsBinaryOperation assignment = AstUtil.newAssignment(fieldName, initExpr); - assignment.setSourceRef(x); - result = new JsExprStmt(assignment); - staticInit.add(result); - } - - assert currentScopeInfo != null; - currentScopeInfo = null; - inFactoryOrStaticContext = false; - } else { - makePropertyGetter(element); - } - - if (!element.getModifiers().isFinal()) { - makeSetter(element); - } - return result; - } - - @Override - public JsNode visitFunction(DartFunction x) { - if (x.getBody() == null) { - if (ElementKind.of(currentHolder).equals(ElementKind.CLASS) - && ((ClassElement) currentHolder).isInterface()) { - return null; - } - } - - functionStack.push(x); - jsNewDeclarationsStack.push(new HashSet()); - - // The JsFunction was already created and pushed in visit(DartFunction). - JsFunction jsFunc = translationContext.getMethods().get(x); - - // Generate and set the body. - JsBlock body; - if (x.getBody() == null) { - // The resolution has checked already that it is valid for this method - // to not have a body. - body = new JsBlock(); - } else { - body = (JsBlock) generate(x.getBody()); - } - jsFunc.setBody(body); - - // Create JS parameters - List params = x.getParams(); - List jsParams = jsFunc.getParameters(); - if (!jsFunc.isHoisted()) { - generateAll(params, jsParams, JsParameter.class); - } - - - // Create the runtime type checks that will be inserted later - List checks = Lists.newArrayList(); - - // TODO(zundel): Issue 925: these runtime checks do not work in hoisted functions - // created inside of factory methods if the parameter references type variables. - // A bad reference to $typeArgs caused an error in the closure compiler backend. - boolean omitTypeVariableChecks = false; - if (inFactory) { - Element element = (Element)x.getParent().getSymbol(); - if (!ElementKind.of(element).equals(ElementKind.CONSTRUCTOR)) { - // The code being emitted is something other than the factory method itself. - omitTypeVariableChecks = true; - } - } - - int numParams = params.size(); - for (int i = 0; i < numParams; ++i) { - JsNameRef jsParam = jsParams.get(i).getName().makeRef(); - DartParameter param = params.get(i); - Type paramType = param.getSymbol().getType(); - if (omitTypeVariableChecks && TypeKind.of(paramType).equals(TypeKind.VARIABLE)) { - continue; - } - JsExpression expr = rtt.addTypeCheck(getCurrentClass(), jsParam, paramType, null, param); - if (expr != jsParam) { - // if the expression was returned unchanged, omit the check - checks.add(new JsExprStmt(expr)); - } - } - - - // Add temporary variable declarations, if any. - declareTempsInBlock(body, jsNewDeclarationsStack.pop()); - - DartNode parent = x.getParent(); - assert parent != null; - if (parent instanceof DartMethodDefinition) { - DartMethodDefinition method = (DartMethodDefinition) parent; - if (isFactory(method)) { - rtt.maybeAddTypeParameterToFactory(method, jsFunc); - } - if (Elements.isNonFactoryConstructor((Element) parent.getSymbol())) { - this.addSuperOrRedirectConstructorCall(method); - } - } - - // Call the function prologue setup functions in the reserve order that - // their output need to appear as each adds to the front of the function - // body. - // 3. setup the scope aliases (after default init) - maybeAddFunctionScopeAlias(currentScopeInfo.getScope(x), - translationContext.getMethods().get(x)); - - // 2. call function trace before anything else. - maybeAddFunctionTracing(x); - - // 1. insert parameter type checks at the beginning of the method - body.getStatements().addAll(0, checks); - - functionStack.pop(); - return jsFunc.setSourceRef(x); - } - - /** - * Get the type associated with a type node - * - * @param typeNode a {@link DartTypeNode}, which may be null - * @return a {@link Type} corresponding to the type node or null to indicate unknown - */ - private Type typeOf(DartTypeNode typeNode) { - if (typeNode == null) { - return null; - } - return typeNode.getType(); - } - - private boolean isFactory(DartMethodDefinition method) { - return method.getModifiers().isFactory(); - } - - private void maybeAddFunctionTracing(DartFunction dartFunction) { - // TODO(floitsch): temporary way to enable tracing is by setting a system property. - String tracingCallTarget = System.getProperty("Trace"); - if (tracingCallTarget != null) { - JsFunction function = translationContext.getMethods().get(dartFunction); - - // Example: - // function f(a,b) { ... } - // to: - // function f(a, b) { - // nestingCounter++; - // (nestingCounter, "f(a, b)", a, b); - // try { ... } - // finally { nestingCounter--; } - // } - JsExpression increment = new JsPostfixOperation(JsUnaryOperator.INC, - new JsNameRef(getTraceCounter())); - JsExpression decrement = new JsPostfixOperation(JsUnaryOperator.DEC, - new JsNameRef(getTraceCounter())); - - JsInvocation tracerCall = new JsInvocation(); - tracerCall.setQualifier(new JsNameRef(tracingCallTarget)); - List traceArguments = tracerCall.getArguments(); - traceArguments.add(new JsNameRef(getTraceCounter())); - traceArguments.add(null); // Reserve space for string description. - StringBuffer description = new StringBuffer(); - JsName name = function.getName(); - if (name != null) { - description.append(function.getName().toString()); - } else { - description.append(""); - } - description.append("("); - dartFunction.getParams(); - for (DartParameter param : dartFunction.getParams()) { - JsName paramName = getJsName(param.getSymbol()); - description.append(paramName.toString()); - traceArguments.add(new JsNameRef(paramName)); - } - description.append(")"); - // Update string description in argument list. - traceArguments.set(1, string(description.toString())); - - JsTry countingTry = new JsTry(); - countingTry.setTryBlock(function.getBody()); - countingTry.setFinallyBlock(AstUtil.newBlock(decrement.makeStmt())); - JsBlock newBody = AstUtil.newBlock(increment.makeStmt(), - tracerCall.makeStmt(), - countingTry); - function.setBody(newBody); - } - } - - @Override - public JsNode visitParameter(DartParameter x) { - if (x.getSymbol() != null) { - return new JsParameter(getJsName(x.getSymbol())).setSourceRef(x); - } else { - // TODO(ngeoffray): A parameter in a function type does not have a symbol. - return null; - } - } - - @Override - public JsNode visitBlock(DartBlock x) { - // Basic block handling - JsBlock jsBlock = new JsBlock(); - // TODO(johnlenz): merge redundant JsBlock nodes. - generateAll(x.getStatements(), jsBlock.getStatements(), JsStatement.class); - - // - // For names defined in this scope that are captured by a function - // closure rewrite, inject an object to hold the aliases for the - // value for use by the closure. This simulates lexically scoped names - // in JavaScript and once the closures are hoisted out of the scope - // prevents the capture of value that would otherwise be protected in - // another scope. - // - - // Inject scope alias initialization and clean up. - ScopeRootInfo methodInfo = currentScopeInfo; - if (methodInfo != null) { - DartScope scope = methodInfo.getScope(x); - if (scope.definesClosureReferencedSymbols()) { - // Make sure the alias is defined in the scope. - JsScope currentFunctionScope = getCurrentFunctionScope(); - JsName aliasName = scope.findAliasForJsScope(currentFunctionScope); - // Scope objects are declared (in the JsScope) at first use. By construction scope-objects - // are only created when they are used. Therefore the scope-object must exist in the - // JsScope. - assert aliasName != null; - registerForDeclaration(aliasName); - - // Init and clean up the scope alias - // TODO(johnlenz): this really should be in a finally block, - // debate the runtime cost of doing this, version the possibility of - // a memory leak (It is only really needed if there are closures - // outside this DartScope). - // Alternately, once the closures have been hoisted out, the cleanup - // code can be removed completely. - List list = jsBlock.getStatements(); - JsStatement init = AstUtil.newAssignment( - new JsNameRef(aliasName), new JsObjectLiteral()) - .makeStmt(); - JsStatement cleanup = AstUtil.newAssignment( - new JsNameRef(aliasName), undefined()) - .makeStmt(); - list.add(0, init); - list.add(cleanup); - } - } - return jsBlock.setSourceRef(x); - } - - @Override - public JsNode visitIfStatement(DartIfStatement x) { - JsExpression jsCondition = (JsExpression) generate(x.getCondition()); - jsCondition = rtt.addTypeCheck(getCurrentClass(), jsCondition, typeProvider.getBoolType(), - x.getCondition().getType(), x); - JsStatement jsThenStmt = (JsStatement) generate(x.getThenStatement()); - JsStatement jsElseStmt = null; - if (x.getElseStatement() != null) { - jsElseStmt = (JsStatement) generate(x.getElseStatement()); - } - return new JsIf(jsCondition, jsThenStmt, jsElseStmt).setSourceRef(x); - } - - @Override - public JsNode visitSwitchStatement(DartSwitchStatement x) { - JsSwitch jsSwitch = new JsSwitch(); - jsSwitch.setExpr((JsExpression) generate(x.getExpression())); - generateAll(x.getMembers(), jsSwitch.getCases(), JsSwitchMember.class); - return jsSwitch.setSourceRef(x); - } - - @Override - public JsNode visitCase(DartCase x) { - JsCase jsCase = new JsCase(); - jsCase.setCaseExpr((JsExpression) generate(x.getExpr())); - generateAll(x.getStatements(), jsCase.getStmts(), JsStatement.class); - return jsCase.setSourceRef(x); - } - - @Override - public JsNode visitDefault(DartDefault x) { - JsDefault jsDefault = new JsDefault(); - generateAll(x.getStatements(), jsDefault.getStmts(), JsStatement.class); - return jsDefault.setSourceRef(x); - } - - @Override - public JsNode visitWhileStatement(DartWhileStatement x) { - JsExpression condition = (JsExpression) generate(x.getCondition()); - condition = rtt.addTypeCheck(getCurrentClass(), condition, typeProvider.getBoolType(), - x.getCondition().getType(), x); - JsBlock body = (JsBlock) generate(x.getBody()); - return new JsWhile(condition, body).setSourceRef(x); - } - - @Override - public JsNode visitDoWhileStatement(DartDoWhileStatement x) { - JsExpression condition = (JsExpression) generate(x.getCondition()); - condition = rtt.addTypeCheck(getCurrentClass(), condition, typeProvider.getBoolType(), - x.getCondition().getType(), x); - JsBlock body = (JsBlock) generate(x.getBody()); - return new JsDoWhile(condition, body).setSourceRef(x); - } - - @Override - public JsNode visitForStatement(DartForStatement x) { - // Dart AST normalization removes init expressions. - assert x.getInit() == null; - - JsFor jsFor = new JsFor().setSourceRef(x); - if (x.getCondition() != null) { - JsExpression condExpr = (JsExpression) generate(x.getCondition()); - condExpr = rtt.addTypeCheck(getCurrentClass(), condExpr, typeProvider.getBoolType(), - x.getCondition().getType(), x); - jsFor.setCondition(condExpr); - } - if (x.getIncrement() != null) { - jsFor.setIncrExpr((JsExpression) generate(x.getIncrement())); - } - jsFor.setBody((JsStatement) generate(x.getBody())); - return jsFor.setSourceRef(x); - } - - @Override - public JsNode visitForInStatement(DartForInStatement x) { - DartStatement normalizedNode = x.getNormalizedNode(); - if (normalizedNode == null) { - throw new InternalCompilerException("For-in statement should have been normalized."); - } - return normalizedNode.accept(this); - } - - @Override - public JsNode visitContinueStatement(DartContinueStatement x) { - JsContinue jsContinue = null; - if (x.getTargetSymbol() != null) { - jsContinue = new JsContinue(getJsName(x.getTargetSymbol()).makeRef()); - } else { - jsContinue = new JsContinue(); - } - return jsContinue.setSourceRef(x); - } - - @Override - public JsNode visitBreakStatement(DartBreakStatement x) { - JsBreak jsBreak = null; - if (x.getTargetSymbol() != null) { - jsBreak = new JsBreak(getJsName(x.getTargetSymbol()).makeRef()); - } else { - jsBreak = new JsBreak(); - } - return jsBreak.setSourceRef(x); - } - - @Override - public JsNode visitReturnStatement(DartReturnStatement x) { - JsReturn jsRet = new JsReturn(); - DartExpression returnValue = x.getValue(); - if (returnValue != null) { - JsExpression expr = (JsExpression) generate(returnValue); - DartFunction function = functionStack.peek(); - if (function != null) { - // NOTE: FunctionExpressionInliner might be leaving return statements around - DartTypeNode returnTypeNode = function.getReturnTypeNode(); - Type returnType = null; - if (returnTypeNode == null) { - // check for factory methods, which return the type of their name - returnType = getFactoryReturnType(function); - } - if (returnType == null) { - returnType = typeOf(returnTypeNode); - } - expr = rtt.addTypeCheck(getCurrentClass(), expr, returnType, returnValue.getType(), x); - } - jsRet.setExpr(expr); - } - return jsRet.setSourceRef(x); - } - - /** - * Get the return type of a factory method. - * - * @param function - * @return {@link Type} instance or null if not a factory method or otherwise unavailable - */ - private Type getFactoryReturnType(DartFunction function) { - // TODO: implement - return null; - } - - @Override - public JsNode visitTryStatement(DartTryStatement x) { - JsTry jsTry = new JsTry(); - jsTry.setTryBlock((JsBlock) generate(x.getTryBlock())); - - // TODO(jgw): The Javascript AST allows multiple catch blocks for some reason, - // even though that makes no sense. Sort this out once structured exceptions are - // worked out in Dart. - List catchBlocks = x.getCatchBlocks(); - if (catchBlocks != null && !catchBlocks.isEmpty()) { - // Transform a sequence of catch blocks into nested if-statements. - // Example: - // try { - // } catch (SomeException e1) { - // } catch (OtherException e2) { - // } - // becomes - // try { - // } catch(tmpVar) { - // if (tmpVar instanceof SomeException) { var e1 = tmpVar; - // } else if (tmpVar instanceof OtherException) { var e2 = tmpVar; - // } else { throw tmpVar; } - // } - // - // Note that when no type is given for the Dart exception, it catches always. Then we - // don't need a rethrow. - // The JsCatch scope only contains one variable. There is hence no clash possible. - JsCatch jsCatch = new JsCatch(getCurrentFunctionScope(), "e"); - JsName exceptionVar = jsCatch.getScope().findExistingName("e"); - - jsTry.getCatches().add(jsCatch); - JsBlock jsCatchBody = new JsBlock(); - // Tease out browser built-in exceptions - JsExpression filterBuiltin = AstUtil.newAssignment(exceptionVar.makeRef(), - AstUtil.newInvocation(AstUtil.newNameRef(null, "$transformBrowserException"), - exceptionVar.makeRef())); - jsCatchBody.getStatements().add(filterBuiltin.makeStmt()); - jsCatch.setBody(jsCatchBody); - JsStatement jsElse = new JsThrow(new JsNameRef(exceptionVar)); - - catchVarStack.push(exceptionVar); - for (int i = catchBlocks.size() - 1; i >= 0; i--) { - DartCatchBlock catchBlock = catchBlocks.get(i); - JsBlock jsClauseBody = (JsBlock) generate(catchBlock.getBlock()); - if (catchBlock.getStackTrace() != null) { - // TODO(ngeoffray): do something with the stackTrace. - JsParameter jsStackParam = (JsParameter) generate(catchBlock.getStackTrace()); - registerForDeclaration(jsStackParam.getName()); - } - JsParameter jsClauseParam = (JsParameter) generate(catchBlock.getException()); - JsName jsClauseParamName = jsClauseParam.getName(); - - JsExpression assignment = AstUtil.newAssignment(new JsNameRef(jsClauseParamName), - new JsNameRef(exceptionVar)); - jsClauseBody.getStatements().add(0, assignment.makeStmt()); - // The exception variable is not declared by the catch-block anymore. Register for - // declaration so that it becomes a local variable. - // Note that the name could already be in the list (if two catch-clauses share the same - // name). In this case the declaration-clause will declare the same variable multiple - // times (ex: var e, e, e;). - registerForDeclaration(jsClauseParamName); - - DartParameter exception = catchBlock.getException(); - DartTypeNode exceptionType = exception.getTypeNode(); - if (exceptionType == null) { - // No type has been given. This clause catches everything. - jsElse = jsClauseBody; - continue; - } - - JsExpression instanceCheck = rtt.generateInstanceOfComparison( - getCurrentClass(), - new JsNameRef(exceptionVar), - exceptionType, - exceptionType).setSourceRef(exception); - jsElse = new JsIf(instanceCheck, jsClauseBody, jsElse); - } - jsCatchBody.getStatements().add(jsElse); - catchVarStack.pop(); - } - - if (x.getFinallyBlock() != null) { - JsBlock jsFinallyBlock = (JsBlock) generate(x.getFinallyBlock()); - jsTry.setFinallyBlock(jsFinallyBlock); - } - - // Allow a try block to be a target of a label by surrounding it with a block. - JsNode result = jsTry.setSourceRef(x); - if (x.getParent() instanceof DartLabel) { - result = new JsBlock(jsTry).setSourceRef(x); - } - return result; - } - - @Override - public JsNode visitThrowStatement(DartThrowStatement x) { - JsNameRef error = new JsNameRef("$Dart$ThrowException"); - JsInvocation invoc = AstUtil.newInvocation(error); - JsExpression exception; - if (x.getException() != null) { - exception = (JsExpression) generate(x.getException()); - } else { - // rethrow the exception - JsName name = catchVarStack.peek(); - if (name != null) { - exception = name.makeRef(); - } else { - // TODO(johnlenz): validate this is the correct behavior - throw new InternalCompilerException("invalid rethrow context"); - } - } - invoc.getArguments().add(exception); - return new JsExprStmt(invoc.setSourceRef(x)); - } - - - @Override - public JsNode visitVariableStatement(DartVariableStatement x) { - - // Dart AST Normalization creates one declaration per VAR. - assert x.getVariables().size() == 1; - - JsNode node = generate(x.getVariables().get(0)); - if (node instanceof JsVar) { - JsVars jsVars = new JsVars(); - jsVars.insert((JsVar)node); - return jsVars.setSourceRef(x); - } else { - - // Variables captured by closures may be transformed to property - // assignments. - assert node instanceof JsStatement; - - return node; - } - } - - @Override - public JsNode visitVariable(DartVariable x) { - Symbol targetSymbol = x.getSymbol(); - - // If the name is referenced by a closure use the scope alias. - JsNameRef scopeAliasRef = maybeMakeScopeAliasReference(targetSymbol); - JsNode result = null; - DartExpression value = x.getValue(); - if (scopeAliasRef != null) { - if (value != null) { - JsExpression initExpr = (JsExpression) generate(value); - Type type = getTypeOfIdentifier(x.getName()); - initExpr = rtt.addTypeCheck(getCurrentClass(), initExpr, type, value.getType(), x); - result = AstUtil.newAssignment(scopeAliasRef, initExpr).setSourceRef(x).makeStmt(); - } else { - // we need to put some statement in to keep the expected number - // of values on the stack. - result = translationContext.getProgram().getEmptyStmt(); - } - } else { - JsVars.JsVar jsVar = new JsVars.JsVar(getJsName(targetSymbol)); - if (value != null) { - JsExpression initExpr = (JsExpression) generate(value); - Type type = getTypeOfIdentifier(x.getName()); - initExpr = rtt.addTypeCheck(getCurrentClass(), initExpr, type, value.getType(), x); - jsVar.setInitExpr(initExpr); - } else { - jsVar.setInitExpr(undefined()); - } - result = jsVar.setSourceRef(x); - } - - return result; - } - - @Override - public JsNode visitEmptyStatement(DartEmptyStatement x) { - x.visitChildren(this); - // TODO(johnlenz): Set source info? - return translationContext.getProgram().getEmptyStmt(); - } - - @Override - public JsNode visitSyntheticErrorExpression(DartSyntheticErrorExpression node) { - String name = node.getSource().getName(); - int line = node.getSourceLine(); - int col = node.getSourceColumn(); - throw new AssertionError("Generating JS with parse error at " + name + ":" - + line + ":" + col); - } - - @Override - public JsNode visitSyntheticErrorStatement(DartSyntheticErrorStatement node) { - String name = node.getSource().getName(); - int line = node.getSourceLine(); - int col = node.getSourceColumn(); - throw new AssertionError("Generating JS with parse error at " + name + ":" - + line + ":" + col); - } - - @Override - public JsNode visitLabel(DartLabel x) { - JsStatement jsStmt = (JsStatement) generate(x.getStatement()); - JsLabel jsLabel = new JsLabel(getJsName(x.getSymbol())); - jsLabel.setStmt(jsStmt); - return jsLabel.setSourceRef(x); - } - - @Override - public JsNode visitExprStmt(DartExprStmt x) { - JsNode node = generate(x.getExpression()); - if (node instanceof JsVars) { - // Function statements maybe transformed to var statements. - // TODO(johnlenz): Create a JsFunctionStatement so that those statements - // aren't wrapped in expressions. - // Note(floitsch): When removing this special case please update the comments - // in 'endVisit(DartFunctionExpression, ...)'. - return node; - } else { - JsExpression expr = (JsExpression) node; - return new JsExprStmt(expr).setSourceRef(x); - } - } - - @Override - public JsNode visitConditional(DartConditional x) { - JsExpression testExpr = (JsExpression) generate(x.getCondition()); - testExpr = rtt.addTypeCheck(getCurrentClass(), testExpr, typeProvider.getBoolType(), - x.getCondition().getType(), x); - JsExpression thenExpr = (JsExpression) generate(x.getThenExpression()); - JsExpression elseExpr = (JsExpression) generate(x.getElseExpression()); - return new JsConditional(testExpr, thenExpr, elseExpr).setSourceRef(x); - } - - @Override - public JsNode visitBinaryExpression(DartBinaryExpression x) { - assert x == x.getNormalizedNode(); - - Token operator = x.getOperator(); - - if (operator == Token.IS) { - return generateInstanceOfComparison(x); - } - - DartExpression arg1 = x.getArg1(); - DartExpression arg2 = x.getArg2(); - JsExpression rhs = (JsExpression) generate(arg2); - if (operator == Token.ASSIGN) { - return arg1.accept(new Assignment(x, rhs, arg2.getType())); - } - - assert !operator.isUserDefinableOperator() || !operator.isAssignmentOperator() : x; - - // We can skip shims for non-user-definable operators (NE is a special case because it's not - // user-definable, but still has to be shimmed). - boolean skipShim = (!operator.isUserDefinableOperator() && (operator != Token.NE)); - JsExpression lhs = (JsExpression) generate(arg1); - Token op = x.getOperator(); - - lhs = rtt.addTypeCheck(getCurrentClass(), lhs, getRequiredType(op), arg1.getType(), arg1); - rhs = rtt.addTypeCheck(getCurrentClass(), rhs, getRequiredType(op), arg2.getType(), arg2); - - if (skipShim) { - if (op.isEqualityOperator()) { - op = mapToStrictEquals(op); - // TODO (fabiomfv) - This optimization targets a v8 perf issue. V8 double equals - // comparison to undefined is up to 4 times slower than == null. It seems that it was - // fixed on v8 3.5. once we move to 3.5 and the fix confirmed, this should be revisited. - if (arg2 instanceof DartNullLiteral) { - op = mapToNonStrictEquals(op); - rhs = nulle(); - } - if (arg1 instanceof DartNullLiteral) { - JsExpression tmp = lhs; - lhs = rhs; - rhs = tmp; - op = mapToNonStrictEquals(op); - rhs = nulle(); - } - } - JsExpression binOp = new JsBinaryOperation(mapBinaryOp(op), lhs, rhs); - binOp.setSourceRef(x); - return binOp; - } else { - JsNameRef ref = new JsNameRef(mangler.createOperatorSyntax(operator)); - return AstUtil.newInvocation(ref, lhs, rhs).setSourceRef(x); - } - } - - /** - * Return a type which an operator requires for its operands. - * - * @param op operator - * @return a {@link Type} instance, which will be {@code null} if there are - * no restrictions - */ - private Type getRequiredType(Token op) { - switch (op) { - case OR: - case AND: - return typeProvider.getBoolType(); - // TODO: other operators? - default: - return null; - } - } - - private Type getTypeOfIdentifier(DartIdentifier ident) { - Element element = ident.getReferencedElement(); - DartTypeNode typeNode = null; - if (element == null) { - DartNode parent = ident.getParent(); - if (parent instanceof DartVariable) { - DartVariableStatement varStmt = (DartVariableStatement) parent.getParent(); - typeNode = varStmt.getTypeNode(); - } - } else { - switch (element.getKind()) { - case VARIABLE: - DartVariableStatement varStmt = (DartVariableStatement) element.getNode().getParent(); - typeNode = varStmt.getTypeNode(); - break; - case PARAMETER: - DartParameter param = (DartParameter) element.getNode(); - typeNode = param.getTypeNode(); - break; - case FIELD: - DartFieldDefinition fieldDef = (DartFieldDefinition) element.getNode().getParent(); - typeNode = fieldDef.getTypeNode(); - break; - default: - break; - } - } - if (typeNode != null) { - return typeNode.getType(); - } - return null; - } - - private JsExpression generateInstanceOfComparison(DartBinaryExpression x) { - JsExpression lhs = (JsExpression) generate(x.getArg1()); - DartExpression rhs = x.getArg2(); - boolean isNot = false; - if (rhs instanceof DartUnaryExpression) { - isNot = true; - rhs = ((DartUnaryExpression) rhs).getArg(); - } - JsExpression expr = rtt.generateInstanceOfComparison(getCurrentClass(), - lhs, ((DartTypeExpression) rhs).getTypeNode(), rhs).setSourceRef(x); - if (isNot) { - expr = new JsPrefixOperation(JsUnaryOperator.NOT, expr); - } - return expr; - } - - private JsBinaryOperation assign(JsNameRef op1, JsExpression op2) { - return AstUtil.newAssignment(op1, op2); - } - - private JsBinaryOperation neq(JsExpression op1, JsExpression op2) { - return new JsBinaryOperation(JsBinaryOperator.NEQ, op1, op2); - } - - private JsBinaryOperation or(JsExpression op1, JsExpression op2) { - return new JsBinaryOperation(JsBinaryOperator.OR, op1, op2); - } - - private JsNumberLiteral number(double num) { - return translationContext.getProgram().getNumberLiteral(num); - } - - private JsStringLiteral string(String str) { - return translationContext.getProgram().getStringLiteral(str); - } - - private JsNullLiteral nulle() { - return translationContext.getProgram().getNullLiteral(); - } - - private JsNameRef undefined() { - return translationContext.getProgram().getUndefinedLiteral(); - } - - private JsEmpty empty() { - return translationContext.getProgram().getEmptyStmt(); - } - - @Override - public JsNode visitTypeNode(DartTypeNode x) { - // This backend does not need types. - return null; - } - - @Override - public JsNode visitTypeParameter(DartTypeParameter x) { - // This backend does not need types. - return null; - } - - @Override - public JsNode visitTypeExpression(DartTypeExpression x) { - throw new AssertionError("Unreachable"); - } - - @Override - public JsNode visitUnaryExpression(DartUnaryExpression x) { - assert x == x.getNormalizedNode(); - Token operator = x.getOperator(); - JsNode result; - JsExpression arg = (JsExpression) generate(x.getArg()); - if (operator == Token.SUB) { - JsNameRef ref = - new JsNameRef(mangler.createOperatorSyntax(DartMangler.NEGATE_OPERATOR_NAME)); - result = (AstUtil.newInvocation(ref, arg)); - return result.setSourceRef(x); - } else if (operator.isUserDefinableOperator()) { - JsNameRef ref = new JsNameRef(mangler.createOperatorSyntax(operator)); - result = (AstUtil.newInvocation(ref, arg)); - return result.setSourceRef(x); - } else { - JsUnaryOperator jsUnaryOperator; - switch (operator) { - case INC: - jsUnaryOperator = JsUnaryOperator.INC; - break; - case DEC: - jsUnaryOperator = JsUnaryOperator.DEC; - break; - case NOT: - jsUnaryOperator = JsUnaryOperator.NOT; - arg = rtt.addTypeCheck(getCurrentClass(), arg, typeProvider.getBoolType(), - x.getArg().getType(), x.getArg()); - break; - default: - throw new AssertionError("Unexpected unary operator " + operator.name()); - } - - if (x.isPrefix()) { - result = new JsPrefixOperation(jsUnaryOperator, arg); - } else { - result = new JsPostfixOperation(jsUnaryOperator, arg); - } - - return result.setSourceRef(x); - } - } - - @Override - public JsNode visitPropertyAccess(DartPropertyAccess x) { - return generateLoad(x.getQualifier(), x.getName()).setSourceRef(x); - } - - @Override - public JsNode visitArrayAccess(DartArrayAccess x) { - JsExpression target = (JsExpression) generate(x.getTarget()); - JsExpression key = (JsExpression) generate(x.getKey()); - JsNameRef ref = AstUtil.newNameRef(target, mangler.createOperatorSyntax(Token.INDEX)); - JsInvocation invoke = AstUtil.newInvocation(ref, key); - return invoke.setSourceRef(x); - } - - @Override - public JsNode visitUnqualifiedInvocation(DartUnqualifiedInvocation x) { - DartIdentifier target = x.getTarget(); - Element element = target.getTargetSymbol(); - ElementKind kind = ElementKind.of(element); - JsExpression qualifier; - String mangledName; - MethodElement method = null; - switch (kind) { - case FUNCTION_OBJECT: - mangledName = null; - qualifier = (JsExpression) generate(target); - EnclosingElement enclosingElement = element.getEnclosingElement(); - if (enclosingElement != null && enclosingElement.getKind() == ElementKind.CLASS) { - // Function-object invocations can be made directly, unless they're closures (in which - // case their enclosing-element will be null). - method = (MethodElement) element; - } - break; - case FIELD: - case PARAMETER: - case VARIABLE: - mangledName = null; - qualifier = (JsExpression) generate(target); - break; - - case NONE: - mangledName = mangler.mangleMethod(x.getTarget().getTargetName(), unitLibrary); - qualifier = new JsThisRef(); - break; - - case METHOD: - method = (MethodElement) element; - mangledName = mangler.mangleMethod(method, unitLibrary); - if (element.getModifiers().isStatic()) { - qualifier = referenceName(element.getEnclosingElement(), x.getTarget()); - } else if (Elements.isTopLevel(element)) { - qualifier = null; - } else { - qualifier = new JsThisRef(); - } - break; - - default: - throw new AssertionError("Cannot be an unqualified invocation " + kind); - } - return generateInvocation(x, qualifier, false, mangledName, method); - } - - @Override - public JsNode visitFunctionObjectInvocation(DartFunctionObjectInvocation x) { - DartExpression target = x.getTarget(); - if (target instanceof DartFunctionExpression) { - DartFunctionExpression functionExpression = (DartFunctionExpression) target; - if (functionExpression.getSymbol().getModifiers().isInlinable() && - !shouldGenerateDeveloperModeChecks()) { - // TODO FunctionExpressionInliner conflics with developer mode checks - return new FunctionExpressionInliner(functionExpression, x.getArgs()).call(); - } - } - JsExpression qualifier = (JsExpression) generate(target); - return generateInvocation(x, qualifier, false, null, null); - } - - /** - * Takes a function expression and inlines it with the given arguments, for - * example: - *

{@code
-     *   function(parameter) { return parameter; }(argument)
-     * }
- * becomes: - *
{@code
-     *   ($1 = argument, $1)
-     * }
- */ - private class FunctionExpressionInliner implements Callable { - private final List arguments; - private final List parameters; - private final Map parameterMap = new HashMap(); - private final List statements; - private final JsExpression[] expressions; - - FunctionExpressionInliner(DartFunctionExpression functionExpression, - List arguments) { - final DartFunction function = functionExpression.getFunction(); - this.arguments = arguments; - parameters = function.getParams(); - assert arguments.size() == parameters.size(); - statements = function.getBody().getStatements(); - expressions = new JsExpression[parameters.size() + statements.size()]; - } - - @Override - public JsExpression call() { - int i = 0; - Iterator argumentsIterator = arguments.iterator(); - for (DartParameter parameter : parameters) { - // Assign each argument to a new temporary. - // For example: "arg" becomes: "$i = arg" - expressions[i++] = rewriteArgument(parameter, argumentsIterator.next()); - } - for (DartStatement statement : statements) { - // Inline each statement after rewriting references to the parameters. - // For example: "return parameter_i;" becomes: "$i" - expressions[i++] = rewriteStatement(statement); - } - if (i == 1) { - return expressions[0]; - } else { - return AstUtil.newSequence(expressions); - } - } - - private JsExpression rewriteArgument(DartParameter parameter, DartExpression argument) { - JsName temporary = createTemporary(); - VariableElement element = Elements.makeVariable(temporary.getIdent()); - parameterMap.put(parameter.getSymbol(), element); - translationContext.getNames().setName(element, temporary); - return AstUtil.newAssignment(temporary.makeRef(), (JsExpression) generate(argument)); - } - - private JsExpression rewriteStatement(DartStatement node) { - node.accept(new ParameterRewriter()); - JsNode jsNode = generate(node); - if (jsNode instanceof JsExprStmt) { - return ((JsExprStmt) jsNode).getExpression(); - } else if (jsNode instanceof JsReturn) { - return ((JsReturn) jsNode).getExpr(); - } else { - throw new AssertionError(node); - } - } - - private class ParameterRewriter extends DartNodeTraverser { - @Override - public Void visitIdentifier(DartIdentifier node) { - Element element = parameterMap.get(node.getTargetSymbol()); - if (element != null) { - DartIdentifier identifier = new DartIdentifier(element.getName()); - identifier.setSourceInfo(node); - identifier.setSymbol(element); - node.setNormalizedNode(identifier); - } - return null; - } - } - } - - @Override - public JsNode visitMethodInvocation(DartMethodInvocation x) { - Element element = (Element) x.getTargetSymbol(); - MethodElement method = null; - JsExpression qualifier; - String mangledName; - - if (element == null) { - mangledName = mangler.mangleNamedMethod(x.getFunctionNameString(), unitLibrary); - qualifier = (JsExpression) generate(x.getTarget()); - } else { - switch (element.getKind()) { - case METHOD: { - mangledName = mangler.mangleMethod((MethodElement) element, unitLibrary); - if (element.getModifiers().isStatic()) { - qualifier = referenceName(element.getEnclosingElement(), x.getTarget()); - } else if (Elements.isTopLevel(element)) { - qualifier = null; - } else { - qualifier = (JsExpression) generate(x.getTarget()); - } - method = (MethodElement) element; - break; - } - - case FIELD: { - if(ElementKind.of(x.getTarget().getSymbol()) == ElementKind.LIBRARY) { - // Handled very much like a unqualified invocation - mangledName = null; - qualifier = (JsExpression) generate(x.getFunctionName()); - } else { - mangledName = mangler.mangleNamedMethod(x.getFunctionNameString(), unitLibrary); - qualifier = (JsExpression) generate(x.getTarget()); - } - break; - } - - default: { - throw new AssertionError("Unexpected invocation target."); - } - } - } - - boolean isSuperCall = isSuperCall(x.getTarget().getSymbol()); - return generateInvocation(x, qualifier, isSuperCall, mangledName, method); - } - - private JsExpression generateConstructorInvocation( - DartNewExpression x, JsExpression qualifier, - MethodElement method) { - JsInvocation invoke = (JsInvocation)generateInvocation(x, qualifier, false, null, method); - // TODO(johnlenz): if generateInvocation generates a "noSuchMethod" call. This will add - // useless parameters to the call, this is harmless at the moment. - rtt.mayAddRuntimeTypeToConstrutorOrFactoryCall(getCurrentClass(), x, invoke); - return invoke; - } - - private JsExpression generateInvocation(DartInvocation x, - JsExpression qualifier, - boolean isSuperCall, - String mangledName, - MethodElement method) { - JsInvocation jsInvoke = new JsInvocation(); - - if (method != null) { - if (!generateDirectCallArgs(x, method, jsInvoke)) { - // Call cannot succeed. Generate $nsme() invocation. - return AstUtil.newInvocation(new JsNameRef("$nsme")); - } - } else { - generateNamedCallArgs(x, jsInvoke); - } - - JsExpression explicitReceiver = null; - int argsLength = jsInvoke.getArguments().size(); - qualifier = referenceMethodMember(qualifier, mangledName); - - // If it's a super-call, and we need to adjust the 'this'. - if (isSuperCall) { - qualifier = AstUtil.newNameRef(qualifier, "call"); - } - - if (isSuperCall) { - assert explicitReceiver == null; - explicitReceiver = new JsThisRef(); - } - if (explicitReceiver != null) { - jsInvoke.getArguments().add(0, explicitReceiver); - } - jsInvoke.setQualifier(qualifier); - return jsInvoke.setSourceRef(x); - } - - /** - * @return false if the invocation cannot succeed - */ - private boolean generateDirectCallArgs(DartInvocation x, MethodElement target, - JsInvocation jsInvoke) { - // Direct call. Standard calling convention. - List args = x.getArgs(); - List jsArgs = jsInvoke.getArguments(); - - // Reorder named parameters. - List posArgs = new ArrayList(); - Map namedArgs = new HashMap(); - for (DartExpression arg : args) { - if (arg instanceof DartNamedExpression) { - DartNamedExpression named = (DartNamedExpression) arg; - namedArgs.put(named.getName().getTargetName(), named.getExpression()); - } else { - posArgs.add(arg); - } - } - - int idx = 0, posUsed = 0; - for (VariableElement param : target.getParameters()) { - String name = param.getName(); - if (name != null) { - DartExpression namedArg = namedArgs.remove(name); - if (namedArg != null) { - if (!param.getModifiers().isNamed()) { - // Provided a named argument to a positional parameter. - return false; - } - jsArgs.add((JsExpression) generate(namedArg)); - } else if (idx < posArgs.size()) { - ++posUsed; - jsArgs.add((JsExpression) generate(posArgs.get(idx))); - } else if (param.getDefaultValue() != null) { - assert(param.isNamed()); - jsArgs.add(generateDefaultValue(param.getDefaultValue())); - } else { - if (param.isNamed()) { - jsArgs.add(undefined()); - } else { - return false; - } - } - } - ++idx; - } - - // Caller specified a named argument that wasn't declared in the method definition. - if (!namedArgs.isEmpty()) { - return false; - } - - if (posUsed != posArgs.size()) { - // Unused positional arguments. - return false; - } - - return true; - } - - private JsExpression generateDefaultValue(DartExpression defaultValue) { - if (defaultValue != null) { - if (defaultValue instanceof DartFunctionExpression) { - // This should be caught much earlier and rejected. This check avoids an NPE later. - return nulle(); - } - } - return (JsExpression) generate(defaultValue); - } - - private void generateNamedCallArgs(DartInvocation invoke, JsInvocation jsInvoke) { - // Indirect call. Named-parameter calling convention. - // method(parg_count, { na0:NA0, na1:NA1, ..., count:N }, pa0, pa1, ...); - List args = invoke.getArgs(); - List jsArgs = jsInvoke.getArguments(); - - int namedCount = 0; - for (DartExpression arg : args) { - if (arg instanceof DartNamedExpression) { - ++namedCount; - } - } - - JsExpression argmap; - if (namedCount == 0) { - argmap = new JsNameRef("$noargs"); - } else { - JsObjectLiteral bag = new JsObjectLiteral(); - for (DartExpression arg : args) { - if (arg instanceof DartNamedExpression) { - DartNamedExpression namedExpr = ((DartNamedExpression) arg); - JsExpression targetName = string(getPropNameForNamedParameter(namedExpr)); - JsPropertyInitializer propInit = new JsPropertyInitializer( - targetName, - (JsExpression) generate(namedExpr.getExpression())); - bag.getPropertyInitializers().add(propInit); - } - } - JsPropertyInitializer countProp = new JsPropertyInitializer(string("count"), - number(namedCount)); - bag.getPropertyInitializers().add(countProp); - argmap = bag; - } - - jsArgs.add(number(args.size() - namedCount)); - jsArgs.add(argmap); - for (DartExpression arg : args) { - if (!(arg instanceof DartNamedExpression)) { - jsArgs.add((JsExpression) generate(arg)); - } - } - } - - private JsExpression referenceMethodMember(JsExpression qualifier, - String mangledName) { - if (mangledName != null) { - qualifier = AstUtil.newNameRef(qualifier, mangledName); - } - return qualifier; - } - - @Override - public JsNode visitThisExpression(DartThisExpression x) { - return new JsThisRef().setSourceRef(x); - } - - @Override - public JsNode visitSuperExpression(DartSuperExpression x) { - ClassElement element = x.getSymbol().getClassElement(); - JsNameRef superRef = AstUtil.newPrototypeNameRef(getJsName(element).makeRef()); - return superRef.setSourceRef(x); - } - - @Override - public JsNode visitSuperConstructorInvocation(DartSuperConstructorInvocation x) { - return generateSuperConstructorInvocation(x); - } - - @Override - public JsNode visitNativeBlock(DartNativeBlock x) { - JsBlock jsBlock = new JsBlock(); - - DartMethodDefinition method = - (DartMethodDefinition) currentScopeInfo.getContainingClassMember(); - String name = mangler.mangleNativeMethod(method.getSymbol()); - - JsNameRef nativeRef = new JsNameRef(name); - JsInvocation nativeCall; - if (method.getModifiers().isStatic()) { - nativeCall = AstUtil.newInvocation(nativeRef); - } else { - JsNameRef callRef = AstUtil.newNameRef(nativeRef, "call"); - nativeCall = AstUtil.newInvocation(callRef, new JsThisRef()); - } - - for (DartParameter p : method.getFunction().getParams()) { - nativeCall.getArguments().add(getJsName(p.getSymbol()).makeRef()); - } - - jsBlock.getStatements().add(new JsReturn(nativeCall)); - return jsBlock.setSourceRef(x); - } - - @Override - public JsNode visitNewExpression(DartNewExpression x) { - ConstructorElement element = x.getSymbol(); - JsExpression newExpr; - if (element != null && element.getConstructorType() != null) { - String className = element.getConstructorType().getName(); - // TODO(floitsch): We should have a JsNames instead of creating the string representations. - String name = mangler.createFactorySyntax(className, element.getName(), unitLibrary); - // We add the class name of the holder of the constructor as a qualifier. - JsName classJsName = getJsName(element.getEnclosingElement()); - JsNameRef consName = AstUtil.newNameRef(classJsName.makeRef(), name); - newExpr = generateConstructorInvocation(x, consName, element); - if (x.isConst()) { - newExpr = maybeInternConst(newExpr, Types.constructorType(x).getArguments()); - } - } else { - JsInvocation jsInvocation = AstUtil.newInvocation(new JsNameRef("$nsme2")); - JsStringLiteral ctorName = translationContext.getProgram().getStringLiteral( - x.getConstructor().toSource()); - JsArrayLiteral jsArgsArray = new JsArrayLiteral(); - List expressions = jsArgsArray.getExpressions(); - List dartArgs = x.getArgs(); - for (DartExpression arg : dartArgs) { - expressions.add((JsExpression) generate(arg)); - } - List jsInvocationArguments = jsInvocation.getArguments(); - jsInvocationArguments.add(ctorName); - jsInvocationArguments.add(jsArgsArray); - newExpr = jsInvocation; - } - return newExpr; - } - - - // Compile time constants expressions must be canonicalized. - // We do this with the javascript native "$intern" method. - private JsExpression maybeInternConst(JsExpression newExpr, List typeParams) { - JsInvocation intern = AstUtil.newInvocation(new JsNameRef(INTERN_CONST_FUNCTION), newExpr); - if (typeParams != null && typeParams.size() != 0) { - JsArrayLiteral arr = new JsArrayLiteral(); - for (Type t : typeParams) { - JsExpression typeName; - if (t.getKind() != TypeKind.DYNAMIC) { - typeName = rtt.getRTTClassId((ClassElement)t.getElement()); - } else { - typeName = string(""); - } - arr.getExpressions().add(typeName); - } - intern.getArguments().add(arr); - } - return intern; - } - - private boolean shouldBindThis(ScopeRootInfo.ClosureInfo info) { - if (shouldGenerateDeveloperModeChecks()) { - return true; - } - - return !inFactoryOrStaticContext && info.referencesThis; - } - - private boolean shouldGenerateDeveloperModeChecks() { - return context.getCompilerConfiguration().developerModeChecks(); - } - - @Override - public JsNode visitFunctionExpression(DartFunctionExpression x) { - JsFunction fn = (JsFunction) generate(x.getFunction()); - JsName fnDeclaredName; - JsName hoistedName; - String hoistedRttName = null; - - // TODO(johnlenz): values used in super class init methods are currently - // evaluated twice (once for the init and once for the constructor), but - // this is problematic. We won't need to keep track of the hoisted - // state once the re-evaluation problem is fixed. - boolean fnWasPreviouslyHoisted = fn.isHoisted(); - if (fnWasPreviouslyHoisted) { - fnDeclaredName = fn.getName(); - hoistedName = fn.getName(); - hoistedRttName = mangler.mangleRttLookupMethod(hoistedName.toString(), unitLibrary); - } else { - - // 0) Save off the original name - fnDeclaredName = fn.getName(); - - // 1) Create a global name for this method - hoistedName = makeClosureHoistedJsName(currentHolder, currentScopeInfo, x); - - // 2) Give it a unique name. - fn.setName(hoistedName); - - // 3) Insert it into global scope - fn.rebaseScope(globalScope); - - // 4) Make it statement, if it isn't already - globalBlock.getStatements().add(fn.makeStmt()); - - // 5) Mark the function as hoisted - fn.setHoisted(); - } - - ScopeRootInfo.ClosureInfo info = currentScopeInfo.getClosureInfo(x.getFunction()); - List list = info.getSortedReferencedScopeList(); - - // TODO(jgw): See johnlenz' comment above about re-evaluation. This guard can go away once - // that problem is fixed. - if (!fnWasPreviouslyHoisted) { - // Generate the named-parameter trampoline. - boolean includesClosureScope = !list.isEmpty(); - boolean preserveThis = shouldBindThis(info); - JsFunction tramp = generateNamedParameterTrampoline(x.getFunction(), - hoistedName.makeRef(), - list.size(), preserveThis); - String mangled = mangler.mangleNamedMethod(hoistedName.getIdent(), unitLibrary); - hoistedName = globalScope.declareName(mangled); - tramp.setName(hoistedName); - globalBlock.getStatements().add(tramp.makeStmt()); - - if (x.getParent() != null && !(x.getParent() instanceof DartFunctionObjectInvocation)) { - hoistedRttName = mangler.mangleRttLookupMethod(hoistedName.toString(), unitLibrary); - rtt.generateRuntimeTypeInfo(x, hoistedRttName); - } - } else { - String mangled = mangler.mangleNamedMethod(hoistedName.getIdent(), unitLibrary); - hoistedName = globalScope.declareName(mangled); - hoistedRttName = mangler.mangleRttLookupMethod(hoistedName.toString(), unitLibrary); - } - - if (x.getParent() == null || (x.getParent() instanceof DartFunctionObjectInvocation)) { - hoistedRttName = null; - } - - // 5) Bind the necessary scope references and possibly "this". - JsExpression replacement; - - if (list.isEmpty() && inFactoryOrStaticContext) { - // Simply replace the function - replacement = AstUtil.newInvocation(new JsNameRef("$bind"), new JsNameRef(hoistedName), - hoistedRttName != null ? new JsNameRef(hoistedRttName) : nulle(), undefined()); - } else { - // Replace "function (){}" with "bind(hoistedName, this, scope1, scope2, ...)" - // so that references to class fields can be resolved. - - JsExpression thisRef = undefined(); - // Only bind 'this' if 'this' is referenced - if (shouldBindThis(info)) { - thisRef = new JsThisRef(); - } - - // Replace the definition with a reference to the - // hoisted function, and bind the necessary values - // to it. - int scopeCount = list.size(); - int argCount = fn.getParameters().size() + 2; // +2 => Named-parameter calling convention - String jsBindName = "$bind"; - - JsInvocation invoke = AstUtil.newInvocation(new JsNameRef(jsBindName), - new JsNameRef(hoistedName), - hoistedRttName != null ? new JsNameRef(hoistedRttName) : nulle(), thisRef); - - // Add the scope alias to the bind call and function parameter list - int parameterIndex = 0; - for (DartScope s : list) { - // Add the scope-object as argument to the bind call. The scope-object is referenced - // in the outer function (currentFunctionScope). - JsName aliasJsName = s.getAliasForJsScope(getCurrentFunctionScope()); - invoke.getArguments().add(new JsNameRef(aliasJsName)); - // Add the scope-object as parameter to the hoisted signature. The scope-object is - // referenced from the inner function. - JsName jsName = s.findAliasForJsScope(fn.getScope()); - // Scope objects are declared (in the JsScope) at first use. By construction scope-objects - // are only created when they are used. Therefore the scope-object must exist in the - // JsScope. - assert jsName != null; - // TODO(johnlenz): remove this hoisted check once the constructor/init - // parameters aren't reused. - if (!fnWasPreviouslyHoisted) { - fn.getParameters().add(parameterIndex, new JsParameter(jsName)); - } - parameterIndex += 1; - } - - replacement = invoke; - } - - // 6) If this is a named function expression, then we need to build the scope object. - if (!x.isStatement() && x.getName() != null) { - ScopeRootInfo scopeInfo = currentScopeInfo; - DartScope scope = scopeInfo.getScope(x); - // If the function is not used by name, then we might not need to create a scope. - if (scope.definesClosureReferencedSymbols()) { - // Make sure the alias is defined in the scope. - JsScope currentFunctionScope = getCurrentFunctionScope(); - // This must be the second use of the scope in this function scope. The first use was - // as argument to the bind-invocation above. - JsName aliasName = scope.findAliasForJsScope(currentFunctionScope); - assert aliasName != null; - registerForDeclaration(aliasName); - - // Assume that the initial expression was x = function f() { }. - // Up to this point the function has been hoisted and replaced by a binding call: - // x = bind(hoistedName, this, scope1, ...) - // The variable "replacement" is equal to the bind call. - // - // One of the scopes - say "scope2" - is the FunctionExpressionScope that defines 'f' - // itself. We now need to set up this scope. - // Transform: - // x = bind(hoistedName, this, scope1, ...) into - // x = (scope2 = {}, scope2.f = bind(hoistedName, this, scope1, ...)). - JsExpression init = - AstUtil.newAssignment(new JsNameRef(aliasName), new JsObjectLiteral()); - JsNameRef scopeF = makeScopeAliasNameRef(scope, x.getSymbol()); - JsExpression assig = AstUtil.newAssignment(scopeF, replacement); - replacement = new JsBinaryOperation(JsBinaryOperator.COMMA, init, assig); - // TODO(floitsch): we need to clear the scope object. - } - } - - if (x.isStatement()) { - // If the name is referenced by a closure use the scope alias. - JsNameRef scopeAliasRef = maybeMakeScopeAliasReference(x.getSymbol()); - if (scopeAliasRef != null) { - JsExpression assig = AstUtil.newAssignment(scopeAliasRef, replacement); - // We must not return a statement. The parent has a check and handles JsVars differently. - // By default it actually expects an expression. - return assig.setSourceRef(x); - } else { - // The parent expects an expression, but handles Var statements separately. - assert !hoistedName.equals(fnDeclaredName); - JsVars vars = AstUtil.newVar(x.getName(), fnDeclaredName, replacement); - return vars.setSourceRef(x); - } - } else { - return replacement.setSourceRef(x); - } - } - - private JsName makeClosureHoistedJsName( - Element holder, ScopeRootInfo info, DartFunctionExpression x) { - Element element = info.getContainingElement(); - String closureIdentifier = info.getNextClosureName(); - String closureName = x.getFunctionName(); - String hoistedName = - mangler.createHoistedFunctionName(holder, element, closureIdentifier, closureName); - return globalScope.declareName(hoistedName, hoistedName, closureName); - } - - @Override - public JsNode visitIdentifier(DartIdentifier x) { - DartExpression normalizedNode = x.getNormalizedNode(); - if (normalizedNode != x) { - return normalizedNode.accept(this); - } - - return generateLoad(null, x).setSourceRef(x); - } - - /** - * @return A NameRef to the scoped alias if needed. - */ - private JsNameRef maybeMakeScopeAliasReference(Symbol targetSymbol) { - if (!functionStack.isEmpty()) { - /* - * Currently, you must be inside of a DartFunction in order to be able to generate a - * scope alias. - */ - ScopeRootInfo methodInfo = currentScopeInfo; - if (methodInfo != null) { - DartScope.DartSymbolInfo symbolInfo = methodInfo.getSymbolInfo(targetSymbol); - if (symbolInfo != null && symbolInfo.isReferencedFromClosure()) { - return makeScopeAliasNameRef(symbolInfo.getOwningScope(), targetSymbol); - } - } - } - return null; - } - - private JsNameRef makeScopeAliasNameRef(DartScope scope, Symbol targetSymbol) { - JsName qualifier = scope.getAliasForJsScope(getCurrentFunctionScope()); - return AstUtil.newNameRef(new JsNameRef(qualifier), getJsName(targetSymbol).getIdent()); - } - - @Override - public JsNode visitNullLiteral(DartNullLiteral x) { - // TODO(johnlenz): set source location? - return undefined(); - } - - @Override - public JsNode visitStringLiteral(DartStringLiteral x) { - // TODO(johnlenz): properly set source location? - return string(x.getValue()).setSourceRef(x); - } - - @Override - public JsNode visitStringInterpolation(DartStringInterpolation x) { - List strings = x.getStrings(); - List expressions = x.getExpressions(); - - JsExpression res = null; - Iterator eIter = expressions.iterator(); - boolean first = true; - for (DartStringLiteral lit : strings) { - if (first) { - first = false; - res = (JsExpression) generate(lit); - } else { - assert eIter.hasNext() : "DartStringInterpolation invariant broken."; - JsExpression expr = (JsExpression) generate(eIter.next()); - JsInvocation exprToString = new JsInvocation(); - exprToString.setQualifier(new JsNameRef("$toString")); - exprToString.getArguments().add(expr); - res = new JsBinaryOperation(JsBinaryOperator.ADD, - new JsBinaryOperation(JsBinaryOperator.ADD, res, exprToString), - (JsExpression) generate(lit)).setSourceRef(x); - } - } - assert res != null; - return res; - } - - @Override - public JsNode visitBooleanLiteral(DartBooleanLiteral x) { - // TODO(johnlenz): set source location? - return x.getValue() ? translationContext.getProgram().getTrueLiteral() : translationContext.getProgram().getFalseLiteral(); - } - - @Override - public JsNode visitIntegerLiteral(DartIntegerLiteral x) { - // TODO(johnlenz): set source location? - return number(x.getValue().doubleValue()); - } - - @Override - public JsNode visitDoubleLiteral(DartDoubleLiteral x) { - // TODO(johnlenz): set source location? - return number(x.getValue()); - } - - @Override - public JsNode visitArrayLiteral(DartArrayLiteral x) { - Type elementType = x.getType().getArguments().get(0); - JsArrayLiteral jsArray = new JsArrayLiteral(); - for (DartNode node : x.getExpressions()) { - JsExpression expr = (JsExpression) generate(node); - JsExpression checkedExpr = rtt.addTypeCheck(getCurrentClass(), expr, - elementType, node.getType(), node.getSourceInfo()); - jsArray.getExpressions().add(checkedExpr); - } - jsArray.setSourceRef(x); - JsExpression result = rtt.maybeAddRuntimeTypeForArrayLiteral(getCurrentClass(), x, jsArray); - if (x.isConst()) { - result = this.maybeInternConst(result, x.getType().getArguments()); - } - return result; - } - - @Override - @SuppressWarnings("deprecation") - public JsNode visitMapLiteral(DartMapLiteral x) { - // Map { 'a': 3, 'b': "foo" } to - // (tmp = new Map(), tmp.a = 3, tmp.b = "foo", tmp) - // TODO(floitsch): optimize map-literal creation. - JsName tmpVar = createTemporary(); - // TODO(floitsch): hardcoded reference to "LinkedHashMapImplementation". - // We should instead get the element from the DartMapLiteral x. - String name = "LinkedHashMapImplementation"; - String mangledMap = mangler.mangleClassNameHack(null, name); - String mangledFactory = mangler.createFactorySyntax(name, "", unitLibrary); - JsNameRef runtimeMap = AstUtil.newNameRef(new JsNameRef(mangledMap), mangledFactory); - JsInvocation invoke = AstUtil.newInvocation(runtimeMap); - rtt.maybeAddRuntimeTypeToMapLiteralConstructor(getCurrentClass(), x, invoke); - JsExpression assig = AstUtil.newAssignment(tmpVar.makeRef(), invoke.setSourceRef(x)); - JsExpression result = assig; - Type actualEntryType = x.getType().getArguments().get(1); - for (DartMapLiteralEntry entry : x.getEntries()) { - result = AstUtil.newSequence(result, visitMapLiteralEntry(entry, tmpVar, actualEntryType)); - } - result = AstUtil.newSequence(result, tmpVar.makeRef()); - if (x.isConst()) { - result = this.maybeInternConst(result, x.getType().getArguments()); - } - return result; - } - - private JsExpression visitMapLiteralEntry(DartMapLiteralEntry x, JsName map, Type valueType) { - String addMethod = mangler.createOperatorSyntax(Token.ASSIGN_INDEX); - JsExpression value = (JsExpression) generate(x.getValue()); - value = rtt.addTypeCheck(getCurrentClass(), value, valueType, x.getType(), x.getSourceInfo()); - JsExpression key = (JsExpression) generate(x.getKey()); - JsNameRef methodName = AstUtil.newNameRef(map.makeRef(), addMethod); - return AstUtil.newInvocation(methodName, key, value).setSourceRef(x); - } - - @Override - public JsNode visitMapLiteralEntry(DartMapLiteralEntry x) { - throw new InternalCompilerException("MapLiteralEntries are handled by the 2-arg variant."); - } - - @Override - public JsNode visitNamedExpression(DartNamedExpression node) { - return generate(node.getExpression()); - } - - @Override - public JsNode visitRedirectConstructorInvocation(DartRedirectConstructorInvocation x) { - return generateSuperConstructorInvocation(x); - } - - private JsNode generateSuperConstructorInvocation(DartInvocation x) { - // Must use SuperClass.call(this, ...) to get the correct 'this' context in the callee: - // .$Constructor.call(this, ...). - ConstructorElement element = (ConstructorElement) x.getSymbol(); - Element classElement; - String elementName; - if (element == null) { - classElement = ((ClassElement) currentHolder).getSupertype().getElement(); - elementName = classElement.getName(); - } else { - classElement = element.getEnclosingElement(); - elementName = element.getName(); - } - - // Skip emitting the super calls call if it is Object. - if (classElement.equals(typeProvider.getObjectType().getElement())) { - return null; - } - - // TODO(floitsch): it would be good, if we could get a js-name instead of just a string. - // This way the debugging information would be better. - // We need to generate the JsName (for the initializer/factory) once only and store it - // in some hashtable. Then instead of reusing the mangler, we should reuse those JsNames. - // The debugging information would then contain a link from the property-access to the - // constructor. Without JsName the debugger just assumes we access some random property. - String name = mangler.mangleConstructor(elementName, unitLibrary); - JsNameRef constructorRef = AstUtil.newNameRef(getJsName(classElement).makeRef(), name); - return generateInvocation(x, constructorRef, true, null, element); - } - - private JsBinaryOperator mapBinaryOp(Token operator) { - switch (operator) { - /* Assignment operators. */ - case ASSIGN: return JsBinaryOperator.ASG; - case ASSIGN_BIT_OR: return JsBinaryOperator.ASG_BIT_OR; - case ASSIGN_BIT_XOR: return JsBinaryOperator.ASG_BIT_XOR; - case ASSIGN_BIT_AND: return JsBinaryOperator.ASG_BIT_AND; - case ASSIGN_SHL: return JsBinaryOperator.ASG_SHL; - case ASSIGN_SAR: return JsBinaryOperator.ASG_SHR; - case ASSIGN_ADD: return JsBinaryOperator.ASG_ADD; - case ASSIGN_SUB: return JsBinaryOperator.ASG_SUB; - case ASSIGN_MUL: return JsBinaryOperator.ASG_MUL; - case ASSIGN_DIV: return JsBinaryOperator.ASG_DIV; - case ASSIGN_MOD: return JsBinaryOperator.ASG_MOD; - - /* Binary operators sorted by precedence. */ - case OR: return JsBinaryOperator.OR; - case AND: return JsBinaryOperator.AND; - case BIT_OR: return JsBinaryOperator.BIT_OR; - case BIT_XOR: return JsBinaryOperator.BIT_XOR; - case BIT_AND: return JsBinaryOperator.BIT_AND; - case SHL: return JsBinaryOperator.SHL; - case SAR: return JsBinaryOperator.SHR; - case ADD: return JsBinaryOperator.ADD; - case SUB: return JsBinaryOperator.SUB; - case MUL: return JsBinaryOperator.MUL; - case DIV: return JsBinaryOperator.DIV; - case MOD: return JsBinaryOperator.MOD; - - /* Compare operators sorted by precedence. */ - case EQ: return JsBinaryOperator.EQ; - case NE: return JsBinaryOperator.NEQ; - case EQ_STRICT: return JsBinaryOperator.REF_EQ; - case NE_STRICT: return JsBinaryOperator.REF_NEQ; - case LT: return JsBinaryOperator.LT; - case GT: return JsBinaryOperator.GT; - case LTE: return JsBinaryOperator.LTE; - case GTE: return JsBinaryOperator.GTE; - - // Only used by 'for'. - case COMMA: return JsBinaryOperator.COMMA; - - default: - throw new InternalCompilerException("Invalid binary operator"); - } - } - - private JsUnaryOperator mapUnaryOp(Token operator) { - switch (operator) { - case BIT_NOT: - return JsUnaryOperator.BIT_NOT; - case NOT: - return JsUnaryOperator.NOT; - case SUB: - return JsUnaryOperator.NEG; - case INC: - return JsUnaryOperator.INC; - case DEC: - return JsUnaryOperator.DEC; - default: - throw new InternalCompilerException("Invalid unary operator."); - } - } - - private Token mapToStrictEquals(Token op) { - switch (op) { - case EQ: - return Token.EQ_STRICT; - case NE: - return Token.NE_STRICT; - case EQ_STRICT: - return Token.EQ_STRICT; - case NE_STRICT: - return Token.NE_STRICT; - default: - throw new InternalCompilerException("Invalid equals operator."); - } - } - - private Token mapToNonStrictEquals(Token op) { - switch (op) { - case EQ_STRICT: - return Token.EQ; - case NE_STRICT: - return Token.NE; - case EQ: - return Token.EQ; - case NE: - return Token.NE; - default: - throw new InternalCompilerException("Invalid equals operator."); - } - } - - class Assignment extends DartNodeTraverser { - private final DartNode info; - private final JsExpression rhs; - private final Type rhsType; - - public Assignment(DartNode info, JsExpression rhs, Type rhsType) { - this.info = info; - this.rhs = rhs; - this.rhsType = rhsType; - } - - @Override - public JsNode visitNode(DartNode lhs) { - throw new AssertionError(lhs.getClass().getSimpleName()); - } - - @Override - public JsNode visitIdentifier(DartIdentifier lhs) { - DartExpression normalizedNode = lhs.getNormalizedNode(); - if (lhs != normalizedNode) { - return normalizedNode.accept(this); - } - Type type = getTypeOfIdentifier(lhs); - JsExpression wrapped = rtt.addTypeCheck(getCurrentClass(), rhs, type, rhsType, info); - // On the form e1.name = rhs. - return generateStore(null, lhs, wrapped).setSourceRef(info); - } - - @Override - public JsNode visitPropertyAccess(DartPropertyAccess lhs) { - // On the form e1.name = rhs. - Type type = lhs.getType(); - JsExpression wrapped = rtt.addTypeCheck(getCurrentClass(), rhs, type, rhsType, info); - return generateStore(lhs.getQualifier(), lhs.getName(), wrapped).setSourceRef(info); - } - - @Override - public JsNode visitArrayAccess(DartArrayAccess lhs) { - // On the form e1[key] = argument. - // Generate: e1.$set(key, $0 = argument), $0 - - JsExpression key = (JsExpression) generate(lhs.getKey()); - JsExpression e1 = (JsExpression) generate(lhs.getTarget()); - Type type = lhs.getType(); - JsExpression wrapped = rtt.addTypeCheck(getCurrentClass(), rhs, type, rhsType, info); - JsNameRef $0 = new JsNameRef(createTemporary()); - String $set = mangler.createOperatorSyntax(Token.ASSIGN_INDEX); - // Generate: $0 = rhs - JsExpression e = AstUtil.newAssignment($0, wrapped); - // Generate: e1.$set(key, $0 = rhs) - e = AstUtil.newInvocation(AstUtil.newNameRef(e1, $set), key, e); - // Generate: e, $0 - return new JsBinaryOperation(JsBinaryOperator.COMMA, e, $0).setSourceRef(info); - } - } - - private final JsNode generate(DartNode node) { - if (node != null) { - try { - return node.getNormalizedNode().accept(this); - } catch (AssertionError e) { - reportError(node, e); - // Wrap assertion error to prevent repeated messages for the same error. - throw new RuntimeException(e); - } - } else { - return null; - } - } - - private JsExpression inlineArrayIndexCheck(JsExpression array, JsExpression index) { - return AstUtil.newInvocation(new JsNameRef("$inlineArrayIndexCheck"), array, index); - } - - private void reportError(DartNode node, Throwable exception) { - context.onError(new DartCompilationError(node, JsErrorCode.INTERNAL_ERROR, - exception.getLocalizedMessage())); - } - - private final void generateAll(List nodes, List result, - Class cls) { - for (DartNode node : nodes) { - result.add(cls.cast(generate(node))); - } - } - - JsNameRef referenceName(Symbol symbol, SourceInfo info) { - // If the value if captured by a closure, change the reference to - // use the alias of the value. - JsNameRef jsNode = maybeMakeScopeAliasReference(symbol); - if (jsNode == null) { - jsNode = getJsName(symbol).makeRef(); - } - jsNode.setSourceRef(info); - return jsNode; - } - - @Override - public void visit(List nodes) { - if (nodes != null) { - for (DartNode node : nodes) { - node.accept(this); - } - } - } - - @Override - public JsNode visitAssertion(DartAssertion node) { - if (inDevMode()) { - JsExpression expression = (JsExpression) generate(node.getExpression()); - JsNameRef assertName = new JsNameRef("assert"); - JsInvocation jsInvoke; - jsInvoke = AstUtil.newInvocation(assertName, expression); - return new JsExprStmt(jsInvoke).setSourceRef(node); - } - // Just emit an empty statement if not in checked mode. - return empty(); - } - - private boolean inDevMode() { - return context.getCompilerConfiguration().developerModeChecks(); - } - - @Override - public JsNode visitParenthesizedExpression(DartParenthesizedExpression node) { - return node.getExpression().accept(this); - } - - @Override - public JsNode visitCatchBlock(DartCatchBlock node) { - throw new AssertionError("should never be called directly"); - } - - @Override - public JsNode visitUnit(DartUnit unit) { - throw new AssertionError("should never be called directly"); - /* - unit.visitChildren(this); - // Initialize static fields after declaring every method, getters & - // setters (b/4101270) - // TODO(johnlenz): canonicalize statics values - globalBlock.getStatements().addAll(staticInit); - */ - } - - @Override - public JsNode visitFunctionTypeAlias(DartFunctionTypeAlias node) { - // TODO(codefu): Optimize away if we're never the rhs of a "is" check. - ClassElement classElement = node.getSymbol(); - JsName classJsName = getJsName(classElement); - JsFunction jsClass = new JsFunction(globalScope, classJsName).setSourceRef(node); - jsClass.setIsConstructor(false); - jsClass.setBody(new JsBlock()); - globalBlock.getStatements().add(jsClass.makeStmt()); - - rtt.generateRuntimeTypeInfo(node); - return null; - } - - private JsExpression generateQualifiedFieldAccess(DartNode qualifier, - String accessorName) { - // Generate this.ACCESSOR(); - JsExpression jsQualifier; - if (qualifier == null || (qualifier instanceof DartThisExpression)) { - jsQualifier = new JsThisRef(); - } else { - jsQualifier = (JsExpression) generate(qualifier); - } - - jsQualifier.setSourceRef(qualifier); - JsNameRef nameRef = AstUtil.newNameRef(jsQualifier, accessorName); - return AstUtil.newInvocation(nameRef); - } - - private JsExpression generateUnresolvedAccess(DartNode qualifier, - String accessorName) { - if (qualifier == null) { - return generateQualifiedFieldAccess(qualifier, accessorName); - } - // Generate qualifier.ACCESSOR(); - JsExpression jsQualifier = (JsExpression) generate(qualifier); - jsQualifier.setSourceRef(qualifier); - JsNameRef method = AstUtil.newNameRef(jsQualifier, accessorName); - return AstUtil.newInvocation(method); - } - - private JsInvocation generateSuperFieldAccess(DartNode qualifier, - String accessorName) { - // Generate CLASS.prototype.ACCESSOR.call(this); - ClassElement superClass = ((SuperElement) qualifier.getSymbol()).getClassElement(); - JsExpression jsQualifier = AstUtil.newPrototypeNameRef(getJsName(superClass).makeRef()); - jsQualifier.setSourceRef(qualifier); - JsNameRef method = AstUtil.newNameRef(jsQualifier, accessorName); - method = AstUtil.newNameRef(method, "call"); - JsInvocation jsInvoke = AstUtil.newInvocation(method); - jsInvoke.getArguments().add(0, new JsThisRef()); - return jsInvoke; - } - - private JsInvocation generateStaticFieldAccess(FieldElement element, - DartNode qualifier, - String accessorName) { - // Generate CLASS.ACCESSOR(); - JsExpression jsQualifier = referenceName(element.getEnclosingElement(), qualifier); - jsQualifier.setSourceRef(qualifier); - JsNameRef method = AstUtil.newNameRef(jsQualifier, accessorName); - return AstUtil.newInvocation(method); - } - - private JsInvocation generateLibraryFieldAccess(String accessorName) { - // Generate ACCESSOR(); - return AstUtil.newInvocation(new JsNameRef(accessorName)); - } - - private JsExpression generateFieldAccess(FieldElement field, DartNode qualifier, - String accessorName) { - boolean isSuperCall = (qualifier != null) && isSuperCall(qualifier.getSymbol()); - if (isSuperCall) { - return generateSuperFieldAccess(qualifier, accessorName); - } else if (Elements.isTopLevel(field)) { - return generateLibraryFieldAccess(accessorName); - } else if (field.isStatic()) { - return generateStaticFieldAccess(field, qualifier, accessorName); - } else { - return generateQualifiedFieldAccess(qualifier, accessorName); - } - } - - /* - * A method is accessed as if a closure object - * class A { foo() { return 1; }) - * Function f = A.foo; - */ - private JsExpression generateMethodBoundToVariable(DartIdentifier methodNode, - MethodElement methodElement, DartNode qualifier) { - JsExpression boundMethod; - String mangledName = mangler.mangleNamedMethod(methodElement, unitLibrary); - String mangledGetter = mangler.createGetterSyntax(methodElement, unitLibrary); - boolean isSuperCall = (qualifier != null) && isSuperCall(qualifier.getSymbol()); - if (isSuperCall) { - boundMethod = generateSuperFieldAccess(qualifier, - mangler.createGetterSyntax(methodElement.getName(), unitLibrary)); - } else if (Elements.isTopLevel(methodElement)) { - boundMethod = AstUtil.newInvocation(AstUtil.newNameRef(null, mangledGetter)); - } else if (methodElement.isStatic()) { - if (qualifier == null) { - qualifier = methodElement.getEnclosingElement().getNode(); - assert (qualifier instanceof DartClass); - boundMethod = AstUtil.newNameRef(getJsName(qualifier.getSymbol()).makeRef(), - mangledGetter); - } else { - boundMethod = AstUtil.newNameRef((JsExpression) generate(qualifier), mangledGetter); - } - boundMethod = AstUtil.newInvocation(boundMethod); - } else { - // Should be an invocation on an instance - if (qualifier == null) { - qualifier = DartThisExpression.get(); - } - JsExpression methodQualifier = (JsExpression) generate(qualifier); - ClassElement classElement = (ClassElement) methodElement.getEnclosingElement(); - String className = mangler.mangleClassName(classElement); - JsNameRef prototypeRef = AstUtil.newPrototypeNameRef(new JsNameRef(className)); - JsExpression methodToCall = AstUtil.newNameRef(prototypeRef, mangledName); - JsExpression methodRtt = AstUtil.newNameRef(prototypeRef, - mangler.mangleRttLookupMethod(methodElement, unitLibrary)); - boundMethod = AstUtil.newInvocation(new JsNameRef("$bind"), methodToCall, methodRtt, methodQualifier); - } - boundMethod.setSourceRef(methodNode); - return boundMethod; - } - - private JsExpression generateLoadTemporary(Element element, DartIdentifier node) { - return referenceName(element, node); - } - - private JsExpression generateLoad(DartNode qualifier, DartIdentifier node) { - Element element = node.getTargetSymbol(); - - switch (ElementKind.of(element)) { - case VARIABLE: - case PARAMETER: - case FUNCTION_OBJECT: - // TODO(5089961): we should not generate code for class expressions. - case CLASS: - return generateLoadTemporary(element, node); - - case NONE: - if (qualifier != null && isSuperCall(qualifier.getSymbol())) { - return generateSuperFieldAccess(qualifier, - mangler.createGetterSyntax(node.getTargetName(), unitLibrary)); - } - return generateUnresolvedAccess(qualifier, - mangler.createGetterSyntax(node.getTargetName(), unitLibrary)); - - case FIELD: { - FieldElement field = (FieldElement) element; - String accessorName; - accessorName = mangler.createGetterSyntax(field, unitLibrary); - return generateFieldAccess(field, qualifier, accessorName); - } - - case METHOD: { - MethodElement method = (MethodElement) element; - return generateMethodBoundToVariable(node, method, qualifier); - } - - default: - throw new AssertionError("I do not know how to load: " + ElementKind.of(element)); - } - } - - private JsExpression generateStoreTemporary(Element element, - DartIdentifier node, - JsExpression rhs) { - JsNameRef jsName = referenceName(element, node); - return AstUtil.newAssignment(jsName, rhs); - } - - private JsExpression generateStoreField(JsExpression fieldAccess, - JsExpression rhs) { - if (fieldAccess instanceof JsInvocation) { - JsNameRef $0 = new JsNameRef(createTemporary()); - // Generate: $0 = rhs - JsExpression e = AstUtil.newAssignment($0, rhs); - - // Add ($0 = rhs) as parameter of the field access. - ((JsInvocation) fieldAccess).getArguments().add(e); - // Generate: e1.set$name($0 = rhs), $0 - return new JsBinaryOperation(JsBinaryOperator.COMMA, fieldAccess, $0); - } else { - assert (fieldAccess instanceof JsNameRef); - return AstUtil.newAssignment((JsNameRef) fieldAccess, rhs); - } - } - - private JsExpression generateStore(DartNode qualifier, DartIdentifier node, JsExpression rhs) { - Element element = node.getTargetSymbol(); - - switch (ElementKind.of(element)) { - case VARIABLE: - case PARAMETER: - return generateStoreTemporary(element, node, rhs); - - case NONE: { - JsExpression invoke = - generateUnresolvedAccess(qualifier, - mangler.createSetterSyntax(node.getTargetName(), unitLibrary)); - return generateStoreField(invoke, rhs); - } - - case FIELD: { - FieldElement field = (FieldElement) element; - String accessorName; - - accessorName = mangler.createSetterSyntax(field, unitLibrary); - - JsExpression invoke = generateFieldAccess(field, qualifier, accessorName); - return generateStoreField(invoke, rhs); - } - - default: - throw new AssertionError("I do not know how to store into: " + ElementKind.of(element)); - } - } - - @Override - public JsNode visitParameterizedTypeNode(DartParameterizedTypeNode node) { - return node.getExpression().accept(this); - } - - @Override - public JsNode visitImportDirective(DartImportDirective node) { - throw new AssertionError("should never be called directly"); - } - - @Override - public JsNode visitLibraryDirective(DartLibraryDirective node) { - throw new AssertionError("should never be called directly"); - } - - @Override - public JsNode visitNativeDirective(DartNativeDirective node) { - throw new AssertionError("should never be called directly"); - } - - @Override - public JsNode visitResourceDirective(DartResourceDirective node) { - throw new AssertionError("should never be called directly"); - } - - @Override - public JsNode visitSourceDirective(DartSourceDirective node) { - throw new AssertionError("should never be called directly"); - } - - @Override - public DartClassMember getCurrentClassMember() { - if (this.currentScopeInfo != null) { - return currentScopeInfo.getContainingClassMember(); - } - return null; - } - - private ClassElement getCurrentClass() { - if (currentHolder.getKind() == ElementKind.CLASS) { - return (ClassElement) currentHolder; - } - return null; - } - } - - GenerateJavascriptAST(DartUnit unit, CoreTypeProvider typeProvider, DartCompilerContext context) { - this.unit = unit; - this.context = context; - this.typeProvider = typeProvider; - } - - public void translateNode(TranslationContext translationContext, DartNode node, - JsBlock blockStatics) { - GenerateJavascriptVisitor generator = - new GenerateJavascriptVisitor(unit, context, translationContext, - typeProvider); - // Generate the Javascript AST. - node.accept(generator); - // Set aside the static initializations - generator.addStaticInitsToBlock(blockStatics); - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/GenerateNamesAndScopes.java b/compiler/java/com/google/dart/compiler/backend/js/GenerateNamesAndScopes.java deleted file mode 100644 index 771f984ca04..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/GenerateNamesAndScopes.java +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.ast.DartClass; -import com.google.dart.compiler.ast.DartContext; -import com.google.dart.compiler.ast.DartField; -import com.google.dart.compiler.ast.DartFunction; -import com.google.dart.compiler.ast.DartFunctionExpression; -import com.google.dart.compiler.ast.DartLabel; -import com.google.dart.compiler.ast.DartMethodDefinition; -import com.google.dart.compiler.ast.DartParameter; -import com.google.dart.compiler.ast.DartVariable; -import com.google.dart.compiler.backend.js.ast.JsFunction; -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsScope; -import com.google.dart.compiler.common.Symbol; -import com.google.dart.compiler.resolver.ConstructorElement; -import com.google.dart.compiler.resolver.Elements; -import com.google.dart.compiler.resolver.FieldElement; -import com.google.dart.compiler.resolver.LibraryElement; -import com.google.dart.compiler.resolver.MethodElement; - -import java.util.Deque; -import java.util.LinkedList; - -/** - * This visitor generates Javascript scopes and names for all the Dart nodes, filling in the - * node->name map in 'names'. - */ -class GenerateNamesAndScopes extends NormalizedVisitor { - - /** - * A JsScope used to manage fields and methods. A MemberJsScope can become - * parentless. - */ - private static class MemberJsScope extends JsScope { - private MemberJsScope(JsScope parent, String description) { - super(parent, description); - } - - @Override - protected void detachFromParent() { - super.detachFromParent(); - } - } - - private final Deque scopes = new LinkedList(); - private DartClass currentClass = null; - private int labelUniqifier = 0; // to resolve label name collisions. - private int varUniqifier = 0; // to resolve variable name collisions. - - private final TranslationContext translationContext; - private final LibraryElement unitLibrary; - - private JsScope getGlobalScope() { - return translationContext.getProgram().getScope(); - } - - public GenerateNamesAndScopes(TranslationContext data, LibraryElement unitLibrary) { - this.translationContext = data; - this.unitLibrary = unitLibrary; - scopes.push(getGlobalScope()); - } - - @Override - public boolean visit(DartClass x, DartContext ctx) { - assert currentClass == null; - // Global variables are declared lazily. We don't declare the class now. - currentClass = x; - // We add the member scope into the hierarchy, so that the resolution works on unqualified - // identifiers. Once the resolution is done, we can rip out the scope from the hierarchy. - scopes.push(new MemberJsScope(scopes.peek(), x.getClassName())); - return true; - } - - @Override - public boolean visit(DartField x, DartContext ctx) { - FieldElement element = x.getSymbol(); - String mangledFieldName = translationContext.getMangler().mangleField(element, unitLibrary); - JsName fieldName = declare(x.getSymbol(), mangledFieldName, element.getName()); - fieldName.setObfuscatable(false); - return true; - } - - public boolean generateConstructorName(DartMethodDefinition x) { - ConstructorElement element = (ConstructorElement) x.getSymbol(); - String name = translationContext.getMangler().mangleConstructor(element.getName(), unitLibrary); - JsName jsName = function(x.getSymbol(), name, element.getName(), x.getFunction()); - // Constructors are globally accessible. - jsName.setObfuscatable(false); - return true; - } - - @Override - public boolean visit(DartMethodDefinition x, DartContext ctx) { - MethodElement element = x.getSymbol(); - if (Elements.isNonFactoryConstructor(element)) { - return generateConstructorName(x); - } - if (x.getModifiers().isFactory()) { - String className = ((ConstructorElement) element).getConstructorType().getName(); - String name = translationContext.getMangler().createFactorySyntax(className, element.getName(), unitLibrary); - JsName jsName = function(x.getSymbol(), name, element.getName(), x.getFunction()); - // Factories are globally accessible. - jsName.setObfuscatable(false); - return true; - } - - String mangledName = translationContext.getMangler().mangleMethod(element, unitLibrary); - JsName methodName = function(x.getSymbol(), mangledName, element.getName(), x.getFunction()); - methodName.setObfuscatable(false); - return true; - } - - @Override - public boolean visit(DartFunctionExpression x, DartContext ctx) { - function(x.getSymbol(), x.getFunctionName(), x.getFunctionName(), x.getFunction()); - return true; - } - - @Override - public boolean visit(DartParameter x, DartContext ctx) { - // TODO(ngeoffray): A parameter in a function type does not have a symbol. - if (x.getSymbol() != null) { - declareExclusively(x.getSymbol(), x.getParameterName()); - } - return true; - } - - @Override - public boolean visit(DartVariable x, DartContext ctx) { - declareExclusively(x.getSymbol(), x.getVariableName()); - return true; - } - - @Override - public boolean visit(DartLabel x, DartContext ctx) { - declareExclusively(x.getSymbol(), String.format("L%X", labelUniqifier++)); - return true; - } - - @Override - public void endVisit(DartMethodDefinition x, DartContext ctx) { - scopes.pop(); - } - - @Override - public void endVisit(DartFunctionExpression x, DartContext ctx) { - scopes.pop(); - } - - @Override - public void endVisit(DartClass x, DartContext ctx) { - currentClass = null; - // Rip out the member scope. Members are always accessed through an object and don't clash - // with other variables. - GenerateNamesAndScopes.MemberJsScope memberScope = (GenerateNamesAndScopes.MemberJsScope) scopes.pop(); - memberScope.rebaseChildScopes(memberScope.getParent()); - memberScope.detachFromParent(); - translationContext.getMemberScopes().put(x.getSymbol(), memberScope); - } - - private JsName function(Symbol symbol, String name, String originalName, DartFunction func) { - JsName jsName = name != null ? declareExclusively(symbol, name, originalName) : null; - JsFunction jsFunc = new JsFunction(scopes.peek(), jsName); - jsFunc.setFromDart(true); - scopes.push(jsFunc.getScope()); - translationContext.getMethods().put(func, jsFunc); - return jsName; - } - - private JsName declare(Symbol x, String name, String originalName) { - return declareInScope(scopes.peek(), x, name, originalName); - } - - private JsName declareExclusively(Symbol x, String name, String originalName) { - return declareExclusivelyInScope(scopes.peek(), x, name, originalName); - } - - private JsName declareExclusively(Symbol x, String name) { - return declareExclusivelyInScope(scopes.peek(), x, name, name); - } - - private static final int BIG_PRIME_UNDER_0XFFFFF = 985531; - - /** - * Create a unique name for this variable in this scope. - * - * Try to keep this from being a linear scan of the namespace, and keep - * it under 5 hex digits (over 1,000,000 unique suffixes). - * - */ - private JsName declareExclusivelyInScope(JsScope scope, Symbol x, - String name, String originalName) { - String mappedName = name; - int offset = 0; - while (scope.findExistingName(mappedName) != null) { - mappedName = String.format("%s_%X", mappedName, varUniqifier); - varUniqifier = (varUniqifier + offset++) % BIG_PRIME_UNDER_0XFFFFF; - } - return declareInScope(scope, x, mappedName, originalName); - } - - private JsName declareInScope(JsScope scope, Symbol x, String name, String originalName) { - JsName jsName = scope.declareName(name, name, originalName); - jsName.getClass(); // Fast null check. - x.getClass(); // Fast null check. - translationContext.getNames().setName(x, jsName); - return jsName; - } -} \ No newline at end of file diff --git a/compiler/java/com/google/dart/compiler/backend/js/JavascriptBackend.java b/compiler/java/com/google/dart/compiler/backend/js/JavascriptBackend.java deleted file mode 100644 index c33143c38c5..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JavascriptBackend.java +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.common.io.CharStreams; -import com.google.common.io.Closeables; -import com.google.dart.compiler.DartCompilerContext; -import com.google.dart.compiler.DartSource; -import com.google.dart.compiler.LibrarySource; -import com.google.dart.compiler.ast.LibraryNode; -import com.google.dart.compiler.ast.LibraryUnit; -import com.google.dart.compiler.backend.js.analysis.TreeShaker; -import com.google.dart.compiler.metrics.CompilerMetrics; -import com.google.dart.compiler.resolver.CoreTypeProvider; - -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; -import java.util.Collection; - -/** - * A compiler backend that produces raw Javascript. - */ -public class JavascriptBackend extends AbstractJsBackend { - - public static final String EXTENSION_APP_JS_COMPLETE = EXTENSION_APP_JS + ".complete"; - - /** - * Wraps an Appendable and keeps track of the current offset as line/columns. - */ - static class CountingAppendable implements Appendable { - - private int line = 0; - private int column = 0; - private Appendable out; - private long charCount = 0; - - CountingAppendable(Appendable out) { - this.out = out; - } - - @Override - public Appendable append(CharSequence csq) throws IOException { - incCount(csq, 0, csq.length()); - return out.append(csq); - } - - @Override - public Appendable append(char c) throws IOException { - incCount(c); - return out.append(c); - } - - @Override - public Appendable append(CharSequence csq, int start, int end) - throws IOException { - incCount(csq, start, end); - return out.append(csq, start, end); - } - - private void incCount(CharSequence cs, int start, int end) { - for (int i = 0; i < cs.length(); i++) { - incCount(cs.charAt(i)); - } - } - - private void incCount(char c) { - ++charCount; - if (c == '\n') { - line++; - column = 0; - } else { - column++; - } - } - } - - private static class DepsWritingCallback implements DepsCallback { - private final DartCompilerContext context; - private CountingAppendable out; - DepsWritingCallback( - DartCompilerContext context, - CountingAppendable out) { - this.out = out; - this.context = context; - } - - @Override - public void visitNative(LibraryUnit libUnit, LibraryNode node) - throws IOException { - DartSource nativeSrc = libUnit.getSource().getSourceFor(node.getText()); - Reader r = nativeSrc.getSourceReader(); - long charsWrittenForFile = CharStreams.copy(r, out); - } - - @Override - public void visitPart(Part part) throws IOException { - DartSource src = part.unit.getSource(); - assert(src != null); - Reader r = context.getArtifactReader(src, part.part, EXTENSION_JS); - if (r == null) { - return; - } - - long partSize = 0; - boolean failed = true; - try { - partSize = CharStreams.copy(r, out); - failed = false; - } finally { - Closeables.close(r, failed); - } - } - - public long getCharsWritten() { - return out.charCount; - } - } - - private static long packageLibs(Writer w, - DartCompilerContext context) throws IOException { - final CountingAppendable out = new CountingAppendable(w); - - DepsWritingCallback callback = new DepsWritingCallback(context, out); - DependencyBuilder.build(context.getAppLibraryUnit(), callback); - return callback.getCharsWritten(); - } - - @Override - public void packageApp(LibrarySource app, - Collection libraries, - DartCompilerContext context, - CoreTypeProvider typeProvider) - throws IOException { - - LibraryUnit appLibraryUnit = context.getAppLibraryUnit(); - boolean hasEntryPoint = appLibraryUnit.getElement().getEntryPoint() != null; - - String completeArtifactName = EXTENSION_APP_JS; - if (hasEntryPoint) { - // Apps with entry points will be reduced so we write into a different file name - completeArtifactName = EXTENSION_APP_JS_COMPLETE; - } - - Writer out = context.getArtifactWriter(app, "", completeArtifactName); - long outputFileSize = 0; - boolean failed = true; - try { - // Emit the concatenated Javascript sources in dependency order. - outputFileSize = packageLibs(out, context); - outputFileSize += writeEntryPointCall(getMangledEntryPoint(context), out); - failed = false; - } finally { - Closeables.close(out, failed); - } - - - if (hasEntryPoint) { - Writer artifactWriter = context.getArtifactWriter(app, "", EXTENSION_APP_JS); - try { - failed = true; - outputFileSize = TreeShaker.reduce(app, context, completeArtifactName, artifactWriter); - failed = false; - } finally { - Closeables.close(artifactWriter, failed); - } - } - - CompilerMetrics compilerMetrics = context.getCompilerMetrics(); - if (compilerMetrics != null) { - compilerMetrics.packagedJsApplication(outputFileSize, -1); - } - } - - @Override - public String getAppExtension() { - return EXTENSION_APP_JS; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsConstructExpressionVisitor.java b/compiler/java/com/google/dart/compiler/backend/js/JsConstructExpressionVisitor.java deleted file mode 100644 index 8d70657a31e..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsConstructExpressionVisitor.java +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.ast.JsArrayAccess; -import com.google.dart.compiler.backend.js.ast.JsArrayLiteral; -import com.google.dart.compiler.backend.js.ast.JsContext; -import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsFunction; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.google.dart.compiler.backend.js.ast.JsNew; -import com.google.dart.compiler.backend.js.ast.JsObjectLiteral; -import com.google.dart.compiler.backend.js.ast.JsVisitable; -import com.google.dart.compiler.backend.js.ast.JsVisitor; - -/** - * Searches for method invocations in constructor expressions that would not - * normally be surrounded by parentheses. - */ -public class JsConstructExpressionVisitor extends JsVisitor { - - public static boolean exec(JsExpression expression) { - if (JsPrecedenceVisitor.exec(expression) < JsPrecedenceVisitor.PRECEDENCE_NEW) { - return true; - } - JsConstructExpressionVisitor visitor = new JsConstructExpressionVisitor(); - visitor.accept(expression); - return visitor.containsInvocation; - } - - private boolean containsInvocation = false; - - private JsConstructExpressionVisitor() { - } - - /** - * We only look at the array expression since the index has its own scope. - */ - @Override - public boolean visit(JsArrayAccess x, JsContext ctx) { - accept(x.getArrayExpr()); - return false; - } - - /** - * Array literals have their own scoping. - */ - @Override - public boolean visit(JsArrayLiteral x, JsContext ctx) { - return false; - } - - /** - * Functions have their own scoping. - */ - @Override - public boolean visit(JsFunction x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsInvocation x, JsContext ctx) { - containsInvocation = true; - return false; - } - - @Override - public boolean visit(JsNameRef x, JsContext ctx) { - if (!x.isLeaf()) { - accept(x.getQualifier()); - } - return false; - } - - /** - * New constructs bind to the nearest set of parentheses. - */ - @Override - public boolean visit(JsNew x, JsContext ctx) { - return false; - } - - /** - * Object literals have their own scope. - */ - @Override - public boolean visit(JsObjectLiteral x, JsContext ctx) { - return false; - } - - /** - * We only look at nodes that would not normally be surrounded by parentheses. - */ - @Override - protected T doAccept(T node) { - // Assign to Object to prevent 'inconvertible types' compile errors due - // to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6548436 - // reproducible in jdk1.6.0_02. - Object o = node; - if (o instanceof JsExpression) { - JsExpression expression = (JsExpression) o; - int precedence = JsPrecedenceVisitor.exec(expression); - // Only visit expressions that won't automatically be surrounded by - // parentheses - if (precedence < JsPrecedenceVisitor.PRECEDENCE_NEW) { - return node; - } - } - return super.doAccept(node); - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsErrorCode.java b/compiler/java/com/google/dart/compiler/backend/js/JsErrorCode.java deleted file mode 100644 index abdde376fbc..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsErrorCode.java +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.ErrorCode; -import com.google.dart.compiler.ErrorSeverity; -import com.google.dart.compiler.SubSystem; - -/** - * {@link ErrorCode}s for JavaScript backend. - */ -public enum JsErrorCode implements ErrorCode { - INTERNAL_ERROR("internal error: %s"); - private final ErrorSeverity severity; - private final String message; - - /** - * Initialize a newly created error code to have the given message and ERROR severity. - */ - private JsErrorCode(String message) { - this(ErrorSeverity.ERROR, message); - } - - /** - * Initialize a newly created error code to have the given severity and message. - */ - private JsErrorCode(ErrorSeverity severity, String message) { - this.severity = severity; - this.message = message; - } - - public String getMessage() { - return message; - } - - public ErrorSeverity getErrorSeverity() { - return severity; - } - - public SubSystem getSubSystem() { - return SubSystem.JS_BACKEND; - } - - @Override - public boolean needsRecompilation() { - return true; - } -} \ No newline at end of file diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsFirstExpressionVisitor.java b/compiler/java/com/google/dart/compiler/backend/js/JsFirstExpressionVisitor.java deleted file mode 100644 index 6fb4dc4f82b..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsFirstExpressionVisitor.java +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.ast.JsArrayAccess; -import com.google.dart.compiler.backend.js.ast.JsArrayLiteral; -import com.google.dart.compiler.backend.js.ast.JsBinaryOperation; -import com.google.dart.compiler.backend.js.ast.JsConditional; -import com.google.dart.compiler.backend.js.ast.JsContext; -import com.google.dart.compiler.backend.js.ast.JsExprStmt; -import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsFunction; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.google.dart.compiler.backend.js.ast.JsNew; -import com.google.dart.compiler.backend.js.ast.JsObjectLiteral; -import com.google.dart.compiler.backend.js.ast.JsPostfixOperation; -import com.google.dart.compiler.backend.js.ast.JsPrefixOperation; -import com.google.dart.compiler.backend.js.ast.JsRegExp; -import com.google.dart.compiler.backend.js.ast.JsVisitor; - -/** - * Determines if an expression statement needs to be surrounded by parentheses. - * - * The statement or the left-most expression needs to be surrounded by - * parentheses if the left-most expression is an object literal or a function - * object. Function declarations do not need parentheses. - * - * For example the following require parentheses:
- *
    - *
  • { key : 'value'}
  • - *
  • { key : 'value'}.key
  • - *
  • function () {return 1;}()
  • - *
  • function () {return 1;}.prototype
  • - *
- * - * The following do not require parentheses:
- *
    - *
  • var x = { key : 'value'}
  • - *
  • "string" + { key : 'value'}.key
  • - *
  • function func() {}
  • - *
  • function() {}
  • - *
- */ -public class JsFirstExpressionVisitor extends JsVisitor { - - public static boolean exec(JsExprStmt statement) { - JsFirstExpressionVisitor visitor = new JsFirstExpressionVisitor(); - JsExpression expression = statement.getExpression(); - // Pure function declarations do not need parentheses - if (expression instanceof JsFunction) { - return false; - } - visitor.accept(statement.getExpression()); - return visitor.needsParentheses; - } - - private boolean needsParentheses = false; - - private JsFirstExpressionVisitor() { - } - - @Override - public boolean visit(JsArrayAccess x, JsContext ctx) { - accept(x.getArrayExpr()); - return false; - } - - @Override - public boolean visit(JsArrayLiteral x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsBinaryOperation x, JsContext ctx) { - accept(x.getArg1()); - return false; - } - - @Override - public boolean visit(JsConditional x, JsContext ctx) { - accept(x.getTestExpression()); - return false; - } - - @Override - public boolean visit(JsFunction x, JsContext ctx) { - needsParentheses = true; - return false; - } - - @Override - public boolean visit(JsInvocation x, JsContext ctx) { - accept(x.getQualifier()); - return false; - } - - @Override - public boolean visit(JsNameRef x, JsContext ctx) { - if (!x.isLeaf()) { - accept(x.getQualifier()); - } - return false; - } - - @Override - public boolean visit(JsNew x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsObjectLiteral x, JsContext ctx) { - needsParentheses = true; - return false; - } - - @Override - public boolean visit(JsPostfixOperation x, JsContext ctx) { - accept(x.getArg()); - return false; - } - - @Override - public boolean visit(JsPrefixOperation x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsRegExp x, JsContext ctx) { - return false; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsNameProvider.java b/compiler/java/com/google/dart/compiler/backend/js/JsNameProvider.java deleted file mode 100644 index d8469e20630..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsNameProvider.java +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2011, the Dart project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsProgram; -import com.google.dart.compiler.backend.js.ast.JsScope; -import com.google.dart.compiler.common.Symbol; -import com.google.dart.compiler.resolver.ClassElement; -import com.google.dart.compiler.resolver.ElementKind; - -import java.util.HashMap; -import java.util.Map; - -/** - * A helper class for managing global names. - * @author johnlenz@google.com (John Lenz) - */ -class JsNameProvider { - private final DartMangler mangler; - private Map names = new HashMap(); - private JsScope globalScope; - - JsNameProvider(JsProgram program, DartMangler mangler) { - this.globalScope = program.getScope(); - this.mangler = mangler; - } - - /** - * Returns the JsName for the given element. If the element is global and - * hasn't been declared yet, it is done now. - */ - JsName getName(Symbol symbol) { - JsName jsName = names.get(symbol); - if (jsName != null) { - assert !jsName.getShortIdent().equals("Object$Dart"); - return jsName; - } - assert ElementKind.of(symbol).equals(ElementKind.CLASS) - || ElementKind.of(symbol).equals(ElementKind.FUNCTION_TYPE_ALIAS) - : "Only classes or typedefs can be lazily declared. Undeclared: " - + symbol.getOriginalSymbolName(); - ClassElement classElement = (ClassElement) symbol; - String name = classElement.getName(); - String nativeName = classElement.getNativeName(); - if (nativeName == null) { - String mangledClassName = mangler.mangleClassName(classElement); - jsName = globalScope.declareName(mangledClassName, mangledClassName, name); - } else { - jsName = globalScope.declareName(nativeName); - } - // Class names are globally accessible. - jsName.setObfuscatable(false); - names.put(symbol, jsName); - assert !jsName.getShortIdent().equals("Object$Dart") : "unexpected " + ((ClassElement) symbol).getNode().getSource().getName(); - return jsName; - } - - void setName(Symbol symbol, JsName name) { - names.put(symbol, name); - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsNamer.java b/compiler/java/com/google/dart/compiler/backend/js/JsNamer.java deleted file mode 100644 index 41e99061eda..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsNamer.java +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.ast.JsProgram; - -/** - * A namer runs through a program and renames the short names of JsNames. - * Namers must assign short names that don't clash and that are valid - * JS-identifiers. Nested JsScopes must not shadow JsNames from outer - * scopes. - * If a JsName is marked as non-obfuscatable then it must retain its short - * name. - */ -public interface JsNamer { - /** - * Names the shortNames of all JsNames of the program so that they are valid - * JS-identifiers and that there are no clashes and no shadowing. - */ - public void exec(JsProgram program); -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsNormalizer.java b/compiler/java/com/google/dart/compiler/backend/js/JsNormalizer.java deleted file mode 100644 index 5eeadf69bd1..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsNormalizer.java +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.ast.JsBinaryOperation; -import com.google.dart.compiler.backend.js.ast.JsBinaryOperator; -import com.google.dart.compiler.backend.js.ast.JsContext; -import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsModVisitor; -import com.google.dart.compiler.backend.js.ast.JsPostfixOperation; -import com.google.dart.compiler.backend.js.ast.JsPrefixOperation; -import com.google.dart.compiler.backend.js.ast.JsProgram; -import com.google.dart.compiler.backend.js.ast.JsUnaryOperation; -import com.google.dart.compiler.backend.js.ast.JsUnaryOperator; - -/** - * Fixes any semantic errors introduced by JS AST gen. - * - *
    - *
  • Creating clinit calls can put comma expressions as lvalues; the modifying - * operation must be moved inside the comma expression to the last argument.
  • - *
- */ -public class JsNormalizer { - - /** - * Resolves any unresolved JsNameRefs. - */ - private static class JsNormalizing extends JsModVisitor { - - @Override - public void endVisit(JsBinaryOperation x, JsContext ctx) { - maybeShuffleModifyingBinary(x, ctx); - } - - @Override - public void endVisit(JsPostfixOperation x, JsContext ctx) { - maybeShuffleModifyingUnary(x, ctx); - } - - @Override - public void endVisit(JsPrefixOperation x, JsContext ctx) { - maybeShuffleModifyingUnary(x, ctx); - } - - /** - * Due to the way clinits are constructed, you can end up with a comma - * operation as the argument to a modifying operation, which is illegal. - * Juggle things to put the operator inside of the comma expression. - */ - private void maybeShuffleModifyingBinary(JsBinaryOperation x, JsContext ctx) { - JsBinaryOperator myOp = x.getOperator(); - JsExpression lhs = x.getArg1(); - - if (myOp.isAssignment() && (lhs instanceof JsBinaryOperation)) { - // Find the rightmost comma operation - JsBinaryOperation curLhs = (JsBinaryOperation) lhs; - assert (curLhs.getOperator() == JsBinaryOperator.COMMA); - while (curLhs.getArg2() instanceof JsBinaryOperation) { - curLhs = (JsBinaryOperation) curLhs.getArg2(); - assert (curLhs.getOperator() == JsBinaryOperator.COMMA); - } - // curLhs is now the rightmost comma operation; slide our operation in - x.setArg1(curLhs.getArg2()); - curLhs.setArg2(x); - // replace myself with the comma expression - ctx.replaceMe(lhs); - } - } - - /** - * Due to the way clinits are constructed, you can end up with a comma - * operation as the argument to a modifying operation, which is illegal. - * Juggle things to put the operator inside of the comma expression. - */ - private void maybeShuffleModifyingUnary(JsUnaryOperation x, JsContext ctx) { - JsUnaryOperator myOp = x.getOperator(); - JsExpression arg = x.getArg(); - if (myOp.isModifying() && (arg instanceof JsBinaryOperation)) { - // Find the rightmost comma operation - JsBinaryOperation curArg = (JsBinaryOperation) arg; - assert (curArg.getOperator() == JsBinaryOperator.COMMA); - while (curArg.getArg2() instanceof JsBinaryOperation) { - curArg = (JsBinaryOperation) curArg.getArg2(); - assert (curArg.getOperator() == JsBinaryOperator.COMMA); - } - // curArg is now the rightmost comma operation; slide our operation in - x.setArg(curArg.getArg2()); - curArg.setArg2(x); - // replace myself with the comma expression - ctx.replaceMe(arg); - } - } - } - - public static void exec(JsProgram program) { - new JsNormalizer(program).execImpl(); - } - - private final JsProgram program; - - private JsNormalizer(JsProgram program) { - this.program = program; - } - - private void execImpl() { - JsNormalizing normalizer = new JsNormalizing(); - normalizer.accept(program); - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsParserException.java b/compiler/java/com/google/dart/compiler/backend/js/JsParserException.java deleted file mode 100644 index 79b53c1d69e..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsParserException.java +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -/** - * Indicates inability to parse JavaScript source. - */ -public class JsParserException extends Exception { - - /** - * Represents the location of a parser exception. - */ - public static class SourceDetail { - private final String fileName; - private final int line; - private final int lineOffset; - private final String lineSource; - - public SourceDetail(int line, String lineSource, int lineOffset, String fileName) { - this.line = line; - this.lineSource = lineSource; - this.lineOffset = lineOffset; - this.fileName = fileName; - } - - public String getFileName() { - return fileName; - } - - public int getLine() { - return line; - } - - public int getLineOffset() { - return lineOffset; - } - - public String getLineSource() { - return lineSource; - } - } - - private static String createMessageWithDetail(String msg, SourceDetail sourceDetail) { - if (sourceDetail == null) { - return msg; - } - StringBuffer sb = new StringBuffer(); - sb.append(sourceDetail.getFileName()); - sb.append('('); - sb.append(sourceDetail.getLine()); - sb.append(')'); - sb.append(": "); - sb.append(msg); - if (sourceDetail.getLineSource() != null) { - sb.append("\n> "); - sb.append(sourceDetail.getLineSource()); - sb.append("\n> "); - for (int i = 0, n = sourceDetail.getLineOffset(); i < n; ++i) { - sb.append('-'); - } - sb.append('^'); - } - return sb.toString(); - } - - private final SourceDetail sourceDetail; - - public JsParserException(String msg) { - this(msg, null); - } - - public JsParserException(String msg, int line, String lineSource, int lineOffset, String fileName) { - this(msg, new SourceDetail(line, lineSource, lineOffset, fileName)); - } - - public JsParserException(String msg, SourceDetail sourceDetail) { - super(createMessageWithDetail(msg, sourceDetail)); - this.sourceDetail = sourceDetail; - } - - /** - * Provides additional source detail in some cases. - * - * @return additional detail regarding the error, or null if no - * additional detail is available - */ - public SourceDetail getSourceDetail() { - return sourceDetail; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsPrecedenceVisitor.java b/compiler/java/com/google/dart/compiler/backend/js/JsPrecedenceVisitor.java deleted file mode 100644 index 4b306872f7e..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsPrecedenceVisitor.java +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.ast.JsArrayAccess; -import com.google.dart.compiler.backend.js.ast.JsArrayLiteral; -import com.google.dart.compiler.backend.js.ast.JsBinaryOperation; -import com.google.dart.compiler.backend.js.ast.JsBlock; -import com.google.dart.compiler.backend.js.ast.JsBooleanLiteral; -import com.google.dart.compiler.backend.js.ast.JsBreak; -import com.google.dart.compiler.backend.js.ast.JsCase; -import com.google.dart.compiler.backend.js.ast.JsCatch; -import com.google.dart.compiler.backend.js.ast.JsConditional; -import com.google.dart.compiler.backend.js.ast.JsContext; -import com.google.dart.compiler.backend.js.ast.JsContinue; -import com.google.dart.compiler.backend.js.ast.JsDebugger; -import com.google.dart.compiler.backend.js.ast.JsDefault; -import com.google.dart.compiler.backend.js.ast.JsDoWhile; -import com.google.dart.compiler.backend.js.ast.JsEmpty; -import com.google.dart.compiler.backend.js.ast.JsExprStmt; -import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsFor; -import com.google.dart.compiler.backend.js.ast.JsForIn; -import com.google.dart.compiler.backend.js.ast.JsFunction; -import com.google.dart.compiler.backend.js.ast.JsIf; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsLabel; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.google.dart.compiler.backend.js.ast.JsNew; -import com.google.dart.compiler.backend.js.ast.JsNullLiteral; -import com.google.dart.compiler.backend.js.ast.JsNumberLiteral; -import com.google.dart.compiler.backend.js.ast.JsObjectLiteral; -import com.google.dart.compiler.backend.js.ast.JsParameter; -import com.google.dart.compiler.backend.js.ast.JsPostfixOperation; -import com.google.dart.compiler.backend.js.ast.JsPrefixOperation; -import com.google.dart.compiler.backend.js.ast.JsProgram; -import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer; -import com.google.dart.compiler.backend.js.ast.JsRegExp; -import com.google.dart.compiler.backend.js.ast.JsReturn; -import com.google.dart.compiler.backend.js.ast.JsStringLiteral; -import com.google.dart.compiler.backend.js.ast.JsSwitch; -import com.google.dart.compiler.backend.js.ast.JsThisRef; -import com.google.dart.compiler.backend.js.ast.JsThrow; -import com.google.dart.compiler.backend.js.ast.JsTry; -import com.google.dart.compiler.backend.js.ast.JsVars; -import com.google.dart.compiler.backend.js.ast.JsVisitor; -import com.google.dart.compiler.backend.js.ast.JsWhile; -import com.google.dart.compiler.backend.js.ast.JsVars.JsVar; - -/** - * Precedence indices from "JavaScript - The Definitive Guide" 4th Edition (page - * 57) - * - * Precedence 17 is for indivisible primaries that either don't have children, - * or provide their own delimiters. - * - * Precedence 16 is for really important things that have their own AST classes. - * - * Precedence 15 is for the new construct. - * - * Precedence 14 is for unary operators. - * - * Precedences 12 through 4 are for non-assigning binary operators. - * - * Precedence 3 is for the tertiary conditional. - * - * Precedence 2 is for assignments. - * - * Precedence 1 is for comma operations. - */ -class JsPrecedenceVisitor extends JsVisitor { - - static final int PRECEDENCE_NEW = 15; - - public static int exec(JsExpression expression) { - JsPrecedenceVisitor visitor = new JsPrecedenceVisitor(); - visitor.accept(expression); - if (visitor.answer < 0) { - throw new RuntimeException("Precedence must be >= 0!"); - } - return visitor.answer; - } - - private int answer = -1; - - private JsPrecedenceVisitor() { - } - - @Override - public boolean visit(JsArrayAccess x, JsContext ctx) { - answer = 16; - return false; - } - - @Override - public boolean visit(JsArrayLiteral x, JsContext ctx) { - answer = 17; // primary - return false; - } - - @Override - public boolean visit(JsBinaryOperation x, JsContext ctx) { - answer = x.getOperator().getPrecedence(); - return false; - } - - @Override - public boolean visit(JsBlock x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsBooleanLiteral x, JsContext ctx) { - answer = 17; // primary - return false; - } - - @Override - public boolean visit(JsBreak x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsCase x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsCatch x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsConditional x, JsContext ctx) { - answer = 3; - return false; - } - - @Override - public boolean visit(JsContinue x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsDebugger x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsDefault x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsDoWhile x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsEmpty x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsExprStmt x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsFor x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsForIn x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsFunction x, JsContext ctx) { - answer = 17; // primary - return false; - } - - @Override - public boolean visit(JsIf x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsInvocation x, JsContext ctx) { - answer = 16; - return false; - } - - @Override - public boolean visit(JsLabel x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsNameRef x, JsContext ctx) { - if (x.isLeaf()) { - answer = 17; // primary - } else { - answer = 16; // property access - } - return false; - } - - @Override - public boolean visit(JsNew x, JsContext ctx) { - answer = PRECEDENCE_NEW; - return false; - } - - @Override - public boolean visit(JsNullLiteral x, JsContext ctx) { - answer = 17; // primary - return false; - } - - @Override - public boolean visit(JsNumberLiteral x, JsContext ctx) { - answer = 17; // primary - return false; - } - - @Override - public boolean visit(JsObjectLiteral x, JsContext ctx) { - answer = 17; // primary - return false; - } - - @Override - public boolean visit(JsParameter x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsPostfixOperation x, JsContext ctx) { - answer = x.getOperator().getPrecedence(); - return false; - } - - @Override - public boolean visit(JsPrefixOperation x, JsContext ctx) { - answer = x.getOperator().getPrecedence(); - return false; - } - - @Override - public boolean visit(JsProgram x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsPropertyInitializer x, JsContext ctx) { - answer = 17; // primary - return false; - } - - @Override - public boolean visit(JsRegExp x, JsContext ctx) { - answer = 17; // primary - return false; - } - - @Override - public boolean visit(JsReturn x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsStringLiteral x, JsContext ctx) { - answer = 17; // primary - return false; - } - - @Override - public boolean visit(JsSwitch x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsThisRef x, JsContext ctx) { - answer = 17; // primary - return false; - } - - @Override - public boolean visit(JsThrow x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsTry x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsVar x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsVars x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } - - @Override - public boolean visit(JsWhile x, JsContext ctx) { - throw new RuntimeException("Only expressions have precedence."); - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsPrettyNamer.java b/compiler/java/com/google/dart/compiler/backend/js/JsPrettyNamer.java deleted file mode 100644 index 4d18fdbf1be..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsPrettyNamer.java +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsProgram; -import com.google.dart.compiler.backend.js.ast.JsRootScope; -import com.google.dart.compiler.backend.js.ast.JsScope; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -/** - * A namer that uses short, readable idents to maximize reability. - */ -public class JsPrettyNamer implements JsNamer { - - public JsPrettyNamer() { - this.program = null; - } - - @Override - public void exec(JsProgram program) { - new JsPrettyNamer(program).execImpl(); - } - - /** - * Communicates to a parent scope all the idents used by all child scopes. - */ - private Set childIdents = null; - - private final JsProgram program; - - /** - * A map containing the next integer to try as an identifier suffix for a - * given JsScope. - */ - private IdentityHashMap> startIdentForScope = - new IdentityHashMap>(); - - protected JsPrettyNamer(JsProgram program) { - this.program = program; - } - - private void execImpl() { - visit(program.getRootScope()); - } - - private boolean isLegal(JsScope scope, Set childIdents, String newIdent) { - if (JsReservedIdentifiers.isKeyword(newIdent)) { - return false; - } - if (childIdents.contains(newIdent)) { - // one of my children already claimed this ident - return false; - } - /* - * Never obfuscate a name into an identifier that conflicts with an existing - * unobfuscatable name! It's okay if it conflicts with an existing - * obfuscatable name; that name will get obfuscated out of the way. - */ - return (scope.findExistingUnobfuscatableName(newIdent) == null); - } - - private void visit(JsScope scope) { - HashMap startIdent = startIdentForScope.get(scope); - if (startIdent == null) { - startIdent = new HashMap(); - startIdentForScope.put(scope, startIdent); - } - - // Save off the childIdents which is currently being computed for my parent. - Set myChildIdents = childIdents; - - /* - * Visit my children first. Reset childIdents so that my children will get a - * clean slate: I do not communicate to my children. - */ - childIdents = new HashSet(); - List children = scope.getChildren(); - for (Iterator it = children.iterator(); it.hasNext();) { - visit(it.next()); - } - - JsRootScope rootScope = program.getRootScope(); - if (scope == rootScope) { - return; - } - - // Visit all my idents. - for (Iterator it = scope.getAllNames(); it.hasNext();) { - JsName name = it.next(); - if (!name.isObfuscatable()) { - // Unobfuscatable names become themselves. - name.setShortIdent(name.getIdent()); - continue; - } - - String newIdent = name.getShortIdent(); - if (!isLegal(scope, childIdents, newIdent)) { - String checkIdent; - - // Start searching using a suffix hint stored in the scope. - // We still do a search in case there is a collision with - // a user-provided identifier - Integer s = startIdent.get(newIdent); - int suffix = (s == null) ? 0 : s.intValue(); - do { - checkIdent = newIdent + "_" + suffix++; - } while (!isLegal(scope, childIdents, checkIdent)); - startIdent.put(newIdent, suffix); - name.setShortIdent(checkIdent); - } else { - // nothing to do; the short name is already good - } - childIdents.add(name.getShortIdent()); - } - myChildIdents.addAll(childIdents); - childIdents = myChildIdents; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsRequiresSemiVisitor.java b/compiler/java/com/google/dart/compiler/backend/js/JsRequiresSemiVisitor.java deleted file mode 100644 index b099959ad1a..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsRequiresSemiVisitor.java +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.ast.JsBlock; -import com.google.dart.compiler.backend.js.ast.JsBreak; -import com.google.dart.compiler.backend.js.ast.JsContext; -import com.google.dart.compiler.backend.js.ast.JsDebugger; -import com.google.dart.compiler.backend.js.ast.JsDoWhile; -import com.google.dart.compiler.backend.js.ast.JsEmpty; -import com.google.dart.compiler.backend.js.ast.JsExprStmt; -import com.google.dart.compiler.backend.js.ast.JsFor; -import com.google.dart.compiler.backend.js.ast.JsForIn; -import com.google.dart.compiler.backend.js.ast.JsIf; -import com.google.dart.compiler.backend.js.ast.JsLabel; -import com.google.dart.compiler.backend.js.ast.JsReturn; -import com.google.dart.compiler.backend.js.ast.JsStatement; -import com.google.dart.compiler.backend.js.ast.JsSwitch; -import com.google.dart.compiler.backend.js.ast.JsThrow; -import com.google.dart.compiler.backend.js.ast.JsTry; -import com.google.dart.compiler.backend.js.ast.JsVars; -import com.google.dart.compiler.backend.js.ast.JsVisitor; -import com.google.dart.compiler.backend.js.ast.JsWhile; - -/** - * Determines if a statement at the end of a block requires a semicolon. - * - * For example, the following statements require semicolons:
- *
    - *
  • if (cond);
  • - *
  • while (cond);
  • - *
- * - * The following do not require semicolons:
- *
    - *
  • return 1
  • - *
  • do {} while(true)
  • - *
- */ -public class JsRequiresSemiVisitor extends JsVisitor { - - public static boolean exec(JsStatement lastStatement) { - JsRequiresSemiVisitor visitor = new JsRequiresSemiVisitor(); - visitor.accept(lastStatement); - return visitor.needsSemicolon; - } - - private boolean needsSemicolon = false; - - private JsRequiresSemiVisitor() { - } - - @Override - public boolean visit(JsBlock x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsBreak x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsDebugger x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsDoWhile x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsEmpty x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsExprStmt x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsFor x, JsContext ctx) { - if (x.getBody() instanceof JsEmpty) { - needsSemicolon = true; - } - return false; - } - - @Override - public boolean visit(JsForIn x, JsContext ctx) { - if (x.getBody() instanceof JsEmpty) { - needsSemicolon = true; - } - return false; - } - - @Override - public boolean visit(JsIf x, JsContext ctx) { - JsStatement thenStmt = x.getThenStmt(); - JsStatement elseStmt = x.getElseStmt(); - JsStatement toCheck = thenStmt; - if (elseStmt != null) { - toCheck = elseStmt; - } - if (toCheck instanceof JsEmpty) { - needsSemicolon = true; - } else { - // Must recurse to determine last statement (possible if-else chain). - accept(toCheck); - } - return false; - } - - @Override - public boolean visit(JsLabel x, JsContext ctx) { - if (x.getStmt() instanceof JsEmpty) { - needsSemicolon = true; - } - return false; - } - - @Override - public boolean visit(JsReturn x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsSwitch x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsThrow x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsTry x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsVars x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsWhile x, JsContext ctx) { - if (x.getBody() instanceof JsEmpty) { - needsSemicolon = true; - } - return false; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsReservedIdentifiers.java b/compiler/java/com/google/dart/compiler/backend/js/JsReservedIdentifiers.java deleted file mode 100644 index 56ae5428a3d..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsReservedIdentifiers.java +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import java.util.HashSet; -import java.util.Set; - -/** - * Determines whether or not a particular string is a JavaScript keyword or not. - */ -public class JsReservedIdentifiers { - - private static Set javaScriptKeywords; - private static Set reservedGlobalSymbols; - private static Set reservedPropertySymbols; - - static { - javaScriptKeywords = new HashSet(); - reservedGlobalSymbols = new HashSet(); - reservedPropertySymbols = new HashSet(); - initJavaScriptKeywords(); - initReservedGlobalSymbols(); - initReservedPropertySymbols(); - } - - public static boolean isKeyword(String s) { - return javaScriptKeywords.contains(s); - } - - private static void initJavaScriptKeywords() { - String[] keywords = new String[] { - // These are current keywords - "break", "delete", "function", "return", "typeof", "case", "do", "if", "switch", "var", - "catch", "else", "in", "this", "void", "continue", "false", "instanceof", "throw", - "while", "debugger", "finally", "new", "true", "with", "default", "for", - "null", "try", - - // These are future keywords - "abstract", "double", "goto", "native", "static", "boolean", "enum", "implements", - "package", "super", "byte", "export", "import", "private", "synchronized", "char", - "extends", "int", "protected", "throws", "class", "final", "interface", "public", - "transient", "const", "float", "long", "short", "volatile" - }; - - for (int i = 0; i < keywords.length; i++) { - javaScriptKeywords.add(keywords[i]); - } - } - - /** - * @return a set containing all known reserved global identifiers. This set must not be modified. - */ - public static Set getReservedGlobalSymbols() { - return reservedGlobalSymbols; - } - - /** - * Returns true if the string s can not be used as a global identifier. The check includes - * JavaScript keywords (as they must not be used either). - * @param s - * @return true if the given String must not be used as a global identifier. - */ - public static boolean isReservedGlobalSymbol(String s) { - return isKeyword(s) || reservedGlobalSymbols.contains(s); - } - - private static void initReservedGlobalSymbols() { - // Section references are from Ecma-262 - // (http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf) - String[] commonBuiltins = new String[] { - // 15.1.1 Value Properties of the Global Object - "NaN", "Infinity", "undefined", - - // 15.1.2 Function Properties of the Global Object - "eval", "parseInt", "parseFloat", "isNan", "isFinite", - - // 15.1.3 URI Handling Function Properties - "decodeURI", "decodeURIComponent", - "encodeURI", - "encodeURIComponent", - - // 15.1.4 Constructor Properties of the Global Object - "Object", "Function", "Array", "String", "Boolean", "Number", "Date", - "RegExp", "Error", "EvalError", "RangeError", "ReferenceError", - "SyntaxError", "TypeError", "URIError", - - // 15.1.5 Other Properties of the Global Object - "Math", - - // 10.1.6 Activation Object - "arguments", - - // B.2 Additional Properties (non-normative) - "escape", "unescape", - - // Window props (https://developer.mozilla.org/en/DOM/window) - "applicationCache", "closed", "Components", "content", "controllers", - "crypto", "defaultStatus", "dialogArguments", "directories", - "document", "frameElement", "frames", "fullScreen", "globalStorage", - "history", "innerHeight", "innerWidth", "length", - "location", "locationbar", "localStorage", "menubar", - "mozInnerScreenX", "mozInnerScreenY", "mozScreenPixelsPerCssPixel", - "name", "navigator", "opener", "outerHeight", "outerWidth", - "pageXOffset", "pageYOffset", "parent", "personalbar", "pkcs11", - "returnValue", "screen", "scrollbars", "scrollMaxX", "scrollMaxY", - "self", "sessionStorage", "sidebar", "status", "statusbar", "toolbar", - "top", "window", - - // Window methods (https://developer.mozilla.org/en/DOM/window) - "alert", "addEventListener", "atob", "back", "blur", "btoa", - "captureEvents", "clearInterval", "clearTimeout", "close", "confirm", - "disableExternalCapture", "dispatchEvent", "dump", - "enableExternalCapture", "escape", "find", "focus", "forward", - "GeckoActiveXObject", "getAttention", "getAttentionWithCycleCount", - "getComputedStyle", "getSelection", "home", "maximize", "minimize", - "moveBy", "moveTo", "open", "openDialog", "postMessage", "print", - "prompt", "QueryInterface", "releaseEvents", "removeEventListener", - "resizeBy", "resizeTo", "restore", "routeEvent", "scroll", "scrollBy", - "scrollByLines", "scrollByPages", "scrollTo", "setInterval", - "setResizeable", "setTimeout", "showModalDialog", "sizeToContent", - "stop", "uuescape", "updateCommands", "XPCNativeWrapper", - "XPCSafeJSOjbectWrapper", - - // Mozilla Window event handlers, same cite - "onabort", "onbeforeunload", "onchange", "onclick", "onclose", - "oncontextmenu", "ondragdrop", "onerror", "onfocus", "onhashchange", - "onkeydown", "onkeypress", "onkeyup", "onload", "onmousedown", - "onmousemove", "onmouseout", "onmouseover", "onmouseup", - "onmozorientation", "onpaint", "onreset", "onresize", "onscroll", - "onselect", "onsubmit", "onunload", - - // Safari Web Content Guide - // http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/SafariWebContent.pdf - // WebKit Window member data, from WebKit DOM Reference - // (http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/WebKitDOMRef/DOMWindow_idl/Classes/DOMWindow/index.html) - // TODO(fredsa) Many, many more functions and member data to add - "ontouchcancel", "ontouchend", "ontouchmove", "ontouchstart", - "ongesturestart", "ongesturechange", "ongestureend", - - // extra window methods - "uneval", - - // keywords https://developer.mozilla.org/en/New_in_JavaScript_1.7, - // https://developer.mozilla.org/en/New_in_JavaScript_1.8.1 - "getPrototypeOf", "let", "yield", - - // "future reserved words" - "abstract", "int", "short", "boolean", "interface", "static", "byte", - "long", "char", "final", "native", "synchronized", "float", "package", - "throws", "goto", "private", "transient", "implements", "protected", - "volatile", "double", "public", - - // IE methods - // (http://msdn.microsoft.com/en-us/library/ms535873(VS.85).aspx#) - "attachEvent", "clientInformation", "clipboardData", "createPopup", - "dialogHeight", "dialogLeft", "dialogTop", "dialogWidth", - "onafterprint", "onbeforedeactivate", "onbeforeprint", - "oncontrolselect", "ondeactivate", "onhelp", "onresizeend", - - // Common browser-defined identifiers not defined in ECMAScript - "event", "external", "Debug", "Enumerator", "Global", "Image", - "ActiveXObject", "VBArray", "Components", - - // Functions commonly defined on Object - "toString", "getClass", "constructor", "prototype", "valueOf", - - // Client-side JavaScript identifiers, which are needed for linkers - // that don't ensure GWT's window != $wnd, document != $doc, etc. - // Taken from the Rhino book, pg 715 - "Anchor", "Applet", "Attr", "Canvas", "CanvasGradient", - "CanvasPattern", "CanvasRenderingContext2D", "CDATASection", - "CharacterData", "Comment", "CSS2Properties", "CSSRule", - "CSSStyleSheet", "Document", "DocumentFragment", "DocumentType", - "DOMException", "DOMImplementation", "DOMParser", "Element", "Event", - "ExternalInterface", "FlashPlayer", "Form", "Frame", "History", - "HTMLCollection", "HTMLDocument", "HTMLElement", "IFrame", "Image", - "Input", "JSObject", "KeyEvent", "Link", "Location", "MimeType", - "MouseEvent", "Navigator", "Node", "NodeList", "Option", "Plugin", - "ProcessingInstruction", "Range", "RangeException", "Screen", "Select", - "Table", "TableCell", "TableRow", "TableSelection", "Text", "TextArea", - "UIEvent", "Window", "XMLHttpRequest", "XMLSerializer", - "XPathException", "XPathResult", "XSLTProcessor", - - // These keywords trigger the loading of the java-plugin. For the - // next-generation plugin, this results in starting a new Java process. - "java", "Packages", "netscape", "sun", "JavaObject", "JavaClass", - "JavaArray", "JavaMember", - - // GWT-defined identifiers - "$wnd", "$doc", "$entry", "$moduleName", "$moduleBase", "$gwt_version", "$sessionId", - - // Identifiers used by JsStackEmulator; later set to obfuscatable - "$stack", "$stackDepth", "$location", - - // TODO: prove why this is necessary or remove it - "call" - }; - for (int i = 0; i < commonBuiltins.length; i++) { - reservedGlobalSymbols.add(commonBuiltins[i]); - } - } - - /** - * Returns true if the given string can not be used as property symbol. The check excludes - * keywords as JavaScript allow keywords as properties. - * @param s - * @return true if the given string must not be used as a property. - */ - public static boolean isReservedPropertySymbol(String s) { - return reservedPropertySymbols.contains(s); - } - - private static void initReservedPropertySymbols() { - // TODO(floitsch): fill in reserved property symbols. - reservedPropertySymbols.add("__PROTO__"); - reservedPropertySymbols.add("prototype"); - } - - private JsReservedIdentifiers() { - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsSourceGenerationVisitor.java b/compiler/java/com/google/dart/compiler/backend/js/JsSourceGenerationVisitor.java deleted file mode 100644 index ebb836a7228..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsSourceGenerationVisitor.java +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.ast.JsBlock; -import com.google.dart.compiler.backend.js.ast.JsContext; -import com.google.dart.compiler.backend.js.ast.JsProgram; -import com.google.dart.compiler.backend.js.ast.JsProgramFragment; -import com.google.dart.compiler.util.TextOutput; - -/** - * Generates JavaScript source from an AST. - */ -public class JsSourceGenerationVisitor extends JsToStringGenerationVisitor { - - public JsSourceGenerationVisitor(TextOutput out) { - super(out); - } - - @Override - public boolean visit(JsProgram x, JsContext ctx) { - // Descend naturally. - return true; - } - - @Override - public boolean visit(JsProgramFragment x, JsContext ctx) { - // Descend naturally. - return true; - } - - @Override - public boolean visit(JsBlock x, JsContext ctx) { - printJsBlock(x, false, true); - return false; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/JsToStringGenerationVisitor.java b/compiler/java/com/google/dart/compiler/backend/js/JsToStringGenerationVisitor.java deleted file mode 100644 index ed0666c9d97..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/JsToStringGenerationVisitor.java +++ /dev/null @@ -1,1354 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.common.collect.Lists; -import com.google.dart.compiler.backend.js.ast.HasName; -import com.google.dart.compiler.backend.js.ast.JsArrayAccess; -import com.google.dart.compiler.backend.js.ast.JsArrayLiteral; -import com.google.dart.compiler.backend.js.ast.JsBinaryOperation; -import com.google.dart.compiler.backend.js.ast.JsBinaryOperator; -import com.google.dart.compiler.backend.js.ast.JsBlock; -import com.google.dart.compiler.backend.js.ast.JsBooleanLiteral; -import com.google.dart.compiler.backend.js.ast.JsBreak; -import com.google.dart.compiler.backend.js.ast.JsCase; -import com.google.dart.compiler.backend.js.ast.JsCatch; -import com.google.dart.compiler.backend.js.ast.JsConditional; -import com.google.dart.compiler.backend.js.ast.JsContext; -import com.google.dart.compiler.backend.js.ast.JsContinue; -import com.google.dart.compiler.backend.js.ast.JsDebugger; -import com.google.dart.compiler.backend.js.ast.JsDefault; -import com.google.dart.compiler.backend.js.ast.JsDoWhile; -import com.google.dart.compiler.backend.js.ast.JsEmpty; -import com.google.dart.compiler.backend.js.ast.JsExprStmt; -import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsFor; -import com.google.dart.compiler.backend.js.ast.JsForIn; -import com.google.dart.compiler.backend.js.ast.JsFunction; -import com.google.dart.compiler.backend.js.ast.JsIf; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsLabel; -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.google.dart.compiler.backend.js.ast.JsNew; -import com.google.dart.compiler.backend.js.ast.JsNullLiteral; -import com.google.dart.compiler.backend.js.ast.JsNumberLiteral; -import com.google.dart.compiler.backend.js.ast.JsObjectLiteral; -import com.google.dart.compiler.backend.js.ast.JsOperator; -import com.google.dart.compiler.backend.js.ast.JsParameter; -import com.google.dart.compiler.backend.js.ast.JsPostfixOperation; -import com.google.dart.compiler.backend.js.ast.JsPrefixOperation; -import com.google.dart.compiler.backend.js.ast.JsProgram; -import com.google.dart.compiler.backend.js.ast.JsProgramFragment; -import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer; -import com.google.dart.compiler.backend.js.ast.JsRegExp; -import com.google.dart.compiler.backend.js.ast.JsReturn; -import com.google.dart.compiler.backend.js.ast.JsStatement; -import com.google.dart.compiler.backend.js.ast.JsStringLiteral; -import com.google.dart.compiler.backend.js.ast.JsSwitch; -import com.google.dart.compiler.backend.js.ast.JsThisRef; -import com.google.dart.compiler.backend.js.ast.JsThrow; -import com.google.dart.compiler.backend.js.ast.JsTry; -import com.google.dart.compiler.backend.js.ast.JsUnaryOperator; -import com.google.dart.compiler.backend.js.ast.JsVars; -import com.google.dart.compiler.backend.js.ast.JsVisitable; -import com.google.dart.compiler.backend.js.ast.JsVisitor; -import com.google.dart.compiler.backend.js.ast.JsWhile; -import com.google.dart.compiler.backend.js.ast.JsVars.JsVar; -import com.google.dart.compiler.common.HasSourceInfo; -import com.google.dart.compiler.util.TextOutput; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.regex.Pattern; - -/** - * Produces text output from a JavaScript AST. - */ -public class JsToStringGenerationVisitor extends JsVisitor { - - private static final char[] CHARS_BREAK = "break".toCharArray(); - private static final char[] CHARS_CASE = "case".toCharArray(); - private static final char[] CHARS_CATCH = "catch".toCharArray(); - private static final char[] CHARS_CONTINUE = "continue".toCharArray(); - private static final char[] CHARS_DEBUGGER = "debugger".toCharArray(); - private static final char[] CHARS_DEFAULT = "default".toCharArray(); - private static final char[] CHARS_DO = "do".toCharArray(); - private static final char[] CHARS_ELSE = "else".toCharArray(); - private static final char[] CHARS_FALSE = "false".toCharArray(); - private static final char[] CHARS_FINALLY = "finally".toCharArray(); - private static final char[] CHARS_FOR = "for".toCharArray(); - private static final char[] CHARS_FUNCTION = "function".toCharArray(); - private static final char[] CHARS_IF = "if".toCharArray(); - private static final char[] CHARS_IN = "in".toCharArray(); - private static final char[] CHARS_NEW = "new".toCharArray(); - private static final char[] CHARS_NULL = "null".toCharArray(); - private static final char[] CHARS_RETURN = "return".toCharArray(); - private static final char[] CHARS_SWITCH = "switch".toCharArray(); - private static final char[] CHARS_THIS = "this".toCharArray(); - private static final char[] CHARS_THROW = "throw".toCharArray(); - private static final char[] CHARS_TRUE = "true".toCharArray(); - private static final char[] CHARS_TRY = "try".toCharArray(); - private static final char[] CHARS_VAR = "var".toCharArray(); - private static final char[] CHARS_WHILE = "while".toCharArray(); - private static final char[] HEX_DIGITS = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - - /** - * How many lines of code to print inside of a JsBlock when printing terse. - */ - private static final int JSBLOCK_LINES_TO_PRINT = 3; - - /** - * A variable name is valid if it contains only letters, numbers, _, $ and - * does not begin with a number. There are actually other valid variable - * names, such as ones that contain escaped Unicode characters, but we - * surround those names with quotes in property initializers to be safe. - */ - private static final Pattern VALID_NAME_PATTERN = Pattern.compile("[a-zA-Z_$][\\w$]*"); - - public static String javaScriptString(String value) { - return javaScriptString(value, false); - } - - /** - * Generate JavaScript code that evaluates to the supplied string. Adapted - * from {@link ScriptRuntime#escapeString(String)} - * . The difference is that we quote with either " or ' depending on - * which one is used less inside the string. - */ - public static String javaScriptString(String value, boolean forceDoubleQuote) { - char[] chars = value.toCharArray(); - final int n = chars.length; - int quoteCount = 0; - int aposCount = 0; - for (int i = 0; i < n; ++i) { - switch (chars[i]) { - case '"': - ++quoteCount; - break; - case '\'': - ++aposCount; - break; - } - } - - StringBuffer result = new StringBuffer(value.length() + 16); - - char quoteChar = (quoteCount < aposCount || forceDoubleQuote) ? '"' : '\''; - result.append(quoteChar); - - for (int i = 0; i < n; ++i) { - char c = chars[i]; - - if (' ' <= c && c <= '~' && c != quoteChar && c != '\\') { - // an ordinary print character (like C isprint()) - result.append(c); - continue; - } - - int escape = -1; - switch (c) { - case '\b': - escape = 'b'; - break; - case '\f': - escape = 'f'; - break; - case '\n': - escape = 'n'; - break; - case '\r': - escape = 'r'; - break; - case '\t': - escape = 't'; - break; - case '"': - escape = '"'; - break; // only reach here if == quoteChar - case '\'': - escape = '\''; - break; // only reach here if == quoteChar - case '\\': - escape = '\\'; - break; - } - - if (escape >= 0) { - // an \escaped sort of character - result.append('\\'); - result.append((char) escape); - } else { - /* - * Emit characters from 0 to 31 that don't have a single character - * escape sequence in octal where possible. This saves one or two - * characters compared to the hexadecimal format '\xXX'. - * - * These short octal sequences may only be used at the end of the string - * or where the following character is a non-digit. Otherwise, the - * following character would be incorrectly interpreted as belonging to - * the sequence. - */ - if (c < ' ' && (i == n - 1 || chars[i + 1] < '0' || chars[i + 1] > '9')) { - result.append('\\'); - if (c > 0x7) { - result.append((char) ('0' + (0x7 & (c >> 3)))); - } - result.append((char) ('0' + (0x7 & c))); - } else { - int hexSize; - if (c < 256) { - // 2-digit hex - result.append("\\x"); - hexSize = 2; - } else { - // Unicode. - result.append("\\u"); - hexSize = 4; - } - // append hexadecimal form of ch left-padded with 0 - for (int shift = (hexSize - 1) * 4; shift >= 0; shift -= 4) { - int digit = 0xf & (c >> shift); - result.append(HEX_DIGITS[digit]); - } - } - } - } - result.append(quoteChar); - escapeClosingTags(result); - String resultString = result.toString(); - return resultString; - } - - /** - * Escapes any closing XML tags embedded in str, which could - * potentially cause a parse failure in a browser, for example, embedding a - * closing <script> tag. - * - * @param str an unescaped literal; May be null - */ - private static void escapeClosingTags(StringBuffer str) { - if (str == null) { - return; - } - - int index = 0; - - while ((index = str.indexOf(" globalBlocks = new HashSet(); - private final TextOutput p; - private ArrayList statementEnds = new ArrayList(); - private ArrayList statementStarts = new ArrayList(); - - public JsToStringGenerationVisitor(TextOutput out) { - this.p = out; - } - - @Override - public boolean visit(JsArrayAccess x, JsContext ctx) { - JsExpression arrayExpr = x.getArrayExpr(); - _parenPush(x, arrayExpr, false); - accept(arrayExpr); - _parenPop(x, arrayExpr, false); - _lsquare(); - accept(x.getIndexExpr()); - _rsquare(); - return false; - } - - @Override - public boolean visit(JsArrayLiteral x, JsContext ctx) { - _lsquare(); - boolean sep = false; - for (Object element : x.getExpressions()) { - JsExpression arg = (JsExpression) element; - sep = _sepCommaOptSpace(sep); - _parenPushIfCommaExpr(arg); - accept(arg); - _parenPopIfCommaExpr(arg); - } - _rsquare(); - return false; - } - - @Override - public boolean visit(JsBinaryOperation x, JsContext ctx) { - JsBinaryOperator op = x.getOperator(); - JsExpression arg1 = x.getArg1(); - _parenPush(x, arg1, !op.isLeftAssociative()); - accept(arg1); - if (op.isKeyword()) { - _parenPopOrSpace(x, arg1, !op.isLeftAssociative()); - } else { - _parenPop(x, arg1, !op.isLeftAssociative()); - _spaceOpt(); - } - p.print(op.getSymbol()); - JsExpression arg2 = x.getArg2(); - if (_spaceCalc(op, arg2)) { - _parenPushOrSpace(x, arg2, op.isLeftAssociative()); - } else { - _spaceOpt(); - _parenPush(x, arg2, op.isLeftAssociative()); - } - accept(arg2); - _parenPop(x, arg2, op.isLeftAssociative()); - return false; - } - - @Override - public boolean visit(JsBlock x, JsContext ctx) { - printJsBlock(x, true, true); - return false; - } - - @Override - public boolean visit(JsBooleanLiteral x, JsContext ctx) { - if (x.getValue()) { - _true(); - } else { - _false(); - } - return false; - } - - @Override - public boolean visit(JsBreak x, JsContext ctx) { - _break(); - - JsNameRef label = x.getLabel(); - if (label != null) { - _space(); - _nameRef(label); - } - - return false; - } - - @Override - public boolean visit(JsCase x, JsContext ctx) { - _case(); - _space(); - accept(x.getCaseExpr()); - _colon(); - _newlineOpt(); - - indent(); - for (Object element : x.getStmts()) { - JsStatement stmt = (JsStatement) element; - needSemi = true; - accept(stmt); - if (needSemi) { - _semi(); - } - _newlineOpt(); - } - outdent(); - needSemi = false; - return false; - } - - @Override - public boolean visit(JsCatch x, JsContext ctx) { - _spaceOpt(); - _catch(); - _spaceOpt(); - _lparen(); - _nameDef(x.getParameter().getName()); - - // Optional catch condition. - // - JsExpression catchCond = x.getCondition(); - if (catchCond != null) { - _space(); - _if(); - _space(); - accept(catchCond); - } - - _rparen(); - _spaceOpt(); - accept(x.getBody()); - - return false; - } - - @Override - public boolean visit(JsConditional x, JsContext ctx) { - // Associativity: for the then and else branches, it is safe to insert - // another - // ternary expression, but if the test expression is a ternary, it should - // get parentheses around it. - { - JsExpression testExpression = x.getTestExpression(); - _parenPush(x, testExpression, true); - accept(testExpression); - _parenPop(x, testExpression, true); - } - _questionMark(); - { - JsExpression thenExpression = x.getThenExpression(); - _parenPush(x, thenExpression, false); - accept(thenExpression); - _parenPop(x, thenExpression, false); - } - _colon(); - { - JsExpression elseExpression = x.getElseExpression(); - _parenPush(x, elseExpression, false); - accept(elseExpression); - _parenPop(x, elseExpression, false); - } - return false; - } - - @Override - public boolean visit(JsContinue x, JsContext ctx) { - _continue(); - - JsNameRef label = x.getLabel(); - if (label != null) { - _space(); - _nameRef(label); - } - - return false; - } - - @Override - public boolean visit(JsDebugger x, JsContext ctx) { - _debugger(); - return false; - } - - @Override - public boolean visit(JsDefault x, JsContext ctx) { - _default(); - _colon(); - - indent(); - for (Object element : x.getStmts()) { - JsStatement stmt = (JsStatement) element; - needSemi = true; - accept(stmt); - if (needSemi) { - _semi(); - } - _newlineOpt(); - } - outdent(); - needSemi = false; - return false; - } - - @Override - public boolean visit(JsDoWhile x, JsContext ctx) { - _do(); - _nestedPush(x.getBody(), true); - accept(x.getBody()); - _nestedPop(x.getBody()); - if (needSemi) { - _semi(); - _newlineOpt(); - } else { - _spaceOpt(); - needSemi = true; - } - _while(); - _spaceOpt(); - _lparen(); - accept(x.getCondition()); - _rparen(); - return false; - } - - @Override - public boolean visit(JsEmpty x, JsContext ctx) { - return false; - } - - @Override - public boolean visit(JsExprStmt x, JsContext ctx) { - boolean surroundWithParentheses = JsFirstExpressionVisitor.exec(x); - if (surroundWithParentheses) { - _lparen(); - } - JsExpression expr = x.getExpression(); - accept(expr); - if (surroundWithParentheses) { - _rparen(); - } - return false; - } - - @Override - public boolean visit(JsFor x, JsContext ctx) { - _for(); - _spaceOpt(); - _lparen(); - - // The init expressions or var decl. - // - if (x.getInitExpr() != null) { - accept(x.getInitExpr()); - } else if (x.getInitVars() != null) { - accept(x.getInitVars()); - } - - _semi(); - - // The loop test. - // - if (x.getCondition() != null) { - _spaceOpt(); - accept(x.getCondition()); - } - - _semi(); - - // The incr expression. - // - if (x.getIncrExpr() != null) { - _spaceOpt(); - accept(x.getIncrExpr()); - } - - _rparen(); - _nestedPush(x.getBody(), false); - accept(x.getBody()); - _nestedPop(x.getBody()); - return false; - } - - @Override - public boolean visit(JsForIn x, JsContext ctx) { - _for(); - _spaceOpt(); - _lparen(); - - if (x.getIterVarName() != null) { - _var(); - _space(); - _nameDef(x.getIterVarName()); - - if (x.getIterExpr() != null) { - _spaceOpt(); - _assignment(); - _spaceOpt(); - accept(x.getIterExpr()); - } - } else { - // Just a name ref. - // - accept(x.getIterExpr()); - } - - _space(); - _in(); - _space(); - accept(x.getObjExpr()); - - _rparen(); - _nestedPush(x.getBody(), false); - accept(x.getBody()); - _nestedPop(x.getBody()); - return false; - } - - // function foo(a, b) { - // stmts... - // } - // - @Override - public boolean visit(JsFunction x, JsContext ctx) { - _function(); - - // Functions can be anonymous. - // - if (x.getName() != null) { - _space(); - _nameOf(x); - } - - _lparen(); - boolean sep = false; - for (Object element : x.getParameters()) { - JsParameter param = (JsParameter) element; - sep = _sepCommaOptSpace(sep); - accept(param); - } - _rparen(); - - accept(x.getBody()); - needSemi = true; - return false; - } - - @Override - public boolean visit(JsIf x, JsContext ctx) { - _if(); - _spaceOpt(); - _lparen(); - accept(x.getIfExpr()); - _rparen(); - JsStatement thenStmt = x.getThenStmt(); - _nestedPush(thenStmt, false); - accept(thenStmt); - _nestedPop(thenStmt); - JsStatement elseStmt = x.getElseStmt(); - if (elseStmt != null) { - if (needSemi) { - _semi(); - _newlineOpt(); - } else { - _spaceOpt(); - needSemi = true; - } - _else(); - boolean elseIf = elseStmt instanceof JsIf; - if (!elseIf) { - _nestedPush(elseStmt, true); - } else { - _space(); - } - accept(elseStmt); - if (!elseIf) { - _nestedPop(elseStmt); - } - } - return false; - } - - @Override - public boolean visit(JsInvocation x, JsContext ctx) { - JsExpression qualifier = x.getQualifier(); - _parenPush(x, qualifier, false); - accept(qualifier); - _parenPop(x, qualifier, false); - - _lparen(); - boolean sep = false; - for (Object element : x.getArguments()) { - JsExpression arg = (JsExpression) element; - sep = _sepCommaOptSpace(sep); - _parenPushIfCommaExpr(arg); - accept(arg); - _parenPopIfCommaExpr(arg); - } - _rparen(); - return false; - } - - @Override - public boolean visit(JsLabel x, JsContext ctx) { - _nameOf(x); - _colon(); - _spaceOpt(); - accept(x.getStmt()); - return false; - } - - @Override - public boolean visit(JsNameRef x, JsContext ctx) { - JsExpression q = x.getQualifier(); - if (q != null) { - _parenPush(x, q, false); - if (q instanceof JsNumberLiteral) { - /** - * Fix for Issue #3796. "42.foo" is not allowed, but "(42).foo" is. - */ - _lparen(); - } - accept(q); - if (q instanceof JsNumberLiteral) { - _rparen(); - } - _parenPop(x, q, false); - _dot(); - } - _nameRef(x); - return false; - } - - @Override - public boolean visit(JsNew x, JsContext ctx) { - _new(); - _space(); - - JsExpression ctorExpr = x.getConstructorExpression(); - boolean needsParens = JsConstructExpressionVisitor.exec(ctorExpr); - if (needsParens) { - _lparen(); - } - accept(ctorExpr); - if (needsParens) { - _rparen(); - } - - /* - * If a constructor call has no arguments, it may simply be replaced with - * "new Constructor" with no parentheses. - */ - List args = x.getArguments(); - if (args.size() > 0) { - _lparen(); - boolean sep = false; - for (JsExpression arg : args) { - sep = _sepCommaOptSpace(sep); - _parenPushIfCommaExpr(arg); - accept(arg); - _parenPopIfCommaExpr(arg); - } - _rparen(); - } - - return false; - } - - @Override - public boolean visit(JsNullLiteral x, JsContext ctx) { - _null(); - return false; - } - - @Override - public boolean visit(JsNumberLiteral x, JsContext ctx) { - double dvalue = x.getValue(); - long lvalue = (long) dvalue; - if (lvalue == dvalue) { - p.print(Long.toString(lvalue)); - } else { - p.print(Double.toString(dvalue)); - } - return false; - } - - @Override - public boolean visit(JsObjectLiteral x, JsContext ctx) { - _lbrace(); - boolean sep = false; - for (Object element : x.getPropertyInitializers()) { - sep = _sepCommaOptSpace(sep); - JsPropertyInitializer propInit = (JsPropertyInitializer) element; - printLabel : { - JsExpression labelExpr = propInit.getLabelExpr(); - // labels can be either string, integral, or decimal literals - if (labelExpr instanceof JsStringLiteral) { - String propName = ((JsStringLiteral) labelExpr).getValue(); - if (VALID_NAME_PATTERN.matcher(propName).matches() - && !JsReservedIdentifiers.isKeyword(propName)) { - p.print(propName); - break printLabel; - } - } - accept(labelExpr); - } - _colon(); - JsExpression valueExpr = propInit.getValueExpr(); - _parenPushIfCommaExpr(valueExpr); - accept(valueExpr); - _parenPopIfCommaExpr(valueExpr); - } - _rbrace(); - return false; - } - - @Override - public boolean visit(JsParameter x, JsContext ctx) { - _nameOf(x); - return false; - } - - @Override - public boolean visit(JsPostfixOperation x, JsContext ctx) { - JsUnaryOperator op = x.getOperator(); - JsExpression arg = x.getArg(); - // unary operators always associate correctly (I think) - _parenPush(x, arg, false); - accept(arg); - _parenPop(x, arg, false); - p.print(op.getSymbol()); - return false; - } - - @Override - public boolean visit(JsPrefixOperation x, JsContext ctx) { - JsUnaryOperator op = x.getOperator(); - p.print(op.getSymbol()); - JsExpression arg = x.getArg(); - if (_spaceCalc(op, arg)) { - _space(); - } - // unary operators always associate correctly (I think) - _parenPush(x, arg, false); - accept(arg); - _parenPop(x, arg, false); - return false; - } - - @Override - public boolean visit(JsProgram x, JsContext ctx) { - p.print(""); - return false; - } - - @Override - public boolean visit(JsProgramFragment x, JsContext ctx) { - p.print(""); - return false; - } - - @Override - public boolean visit(JsPropertyInitializer x, JsContext ctx) { - // Since there are separators, we actually print the property init - // in visit(JsObjectLiteral). - // - return false; - } - - @Override - public boolean visit(JsRegExp x, JsContext ctx) { - _slash(); - p.print(x.getPattern()); - _slash(); - String flags = x.getFlags(); - if (flags != null) { - p.print(flags); - } - return false; - } - - @Override - public boolean visit(JsReturn x, JsContext ctx) { - _return(); - JsExpression expr = x.getExpr(); - if (expr != null) { - _space(); - accept(expr); - } - return false; - } - - @Override - public boolean visit(JsStringLiteral x, JsContext ctx) { - printStringLiteral(x.getValue()); - return false; - } - - @Override - public boolean visit(JsSwitch x, JsContext ctx) { - _switch(); - _spaceOpt(); - _lparen(); - accept(x.getExpr()); - _rparen(); - _spaceOpt(); - _blockOpen(); - acceptList(x.getCases()); - _blockClose(); - return false; - } - - @Override - public boolean visit(JsThisRef x, JsContext ctx) { - _this(); - return false; - } - - @Override - public boolean visit(JsThrow x, JsContext ctx) { - _throw(); - _space(); - accept(x.getExpr()); - return false; - } - - @Override - public boolean visit(JsTry x, JsContext ctx) { - _try(); - _spaceOpt(); - accept(x.getTryBlock()); - - acceptList(x.getCatches()); - - JsBlock finallyBlock = x.getFinallyBlock(); - if (finallyBlock != null) { - _spaceOpt(); - _finally(); - _spaceOpt(); - accept(finallyBlock); - } - - return false; - } - - @Override - public boolean visit(JsVar x, JsContext ctx) { - _nameOf(x); - JsExpression initExpr = x.getInitExpr(); - if (initExpr != null) { - _spaceOpt(); - _assignment(); - _spaceOpt(); - _parenPushIfCommaExpr(initExpr); - accept(initExpr); - _parenPopIfCommaExpr(initExpr); - } - return false; - } - - @Override - public boolean visit(JsVars x, JsContext ctx) { - _var(); - _space(); - boolean sep = false; - for (JsVar var : x) { - sep = _sepCommaOptSpace(sep); - accept(var); - } - return false; - } - - @Override - public boolean visit(JsWhile x, JsContext ctx) { - _while(); - _spaceOpt(); - _lparen(); - accept(x.getCondition()); - _rparen(); - _nestedPush(x.getBody(), false); - accept(x.getBody()); - _nestedPop(x.getBody()); - return false; - } - - // CHECKSTYLE_NAMING_OFF - protected void _newline() { - p.newline(); - } - - protected void _newlineOpt() { - p.newlineOpt(); - } - - protected void printJsBlock(JsBlock x, boolean truncate, boolean finalNewline) { - boolean needBraces = !x.isGlobalBlock(); - - if (needBraces) { - // Open braces. - // - _blockOpen(); - } - - int count = 0; - for (Iterator iter = x.getStatements().iterator(); iter.hasNext(); ++count) { - boolean isGlobal = x.isGlobalBlock() || globalBlocks.contains(x); - - if (truncate && count > JSBLOCK_LINES_TO_PRINT) { - p.print("[...]"); - _newlineOpt(); - break; - } - JsStatement stmt = iter.next(); - needSemi = true; - boolean shouldRecordPositions = isGlobal && !(stmt instanceof JsBlock); - boolean stmtIsGlobalBlock = false; - if (isGlobal) { - if (stmt instanceof JsBlock) { - // A block inside a global block is still considered global - stmtIsGlobalBlock = true; - globalBlocks.add((JsBlock) stmt); - } - } - if (shouldRecordPositions) { - statementStarts.add(p.getPosition()); - } - accept(stmt); - if (stmtIsGlobalBlock) { - globalBlocks.remove(stmt); - } - if (needSemi) { - /* - * Special treatment of function decls: If they are the only item in a - * statement (i.e. not part of an assignment operation), just give them - * a newline instead of a semi. - */ - boolean functionStmt = - stmt instanceof JsExprStmt && ((JsExprStmt) stmt).getExpression() instanceof JsFunction; - /* - * Special treatment of the last statement in a block: only a few - * statements at the end of a block require semicolons. - */ - boolean lastStatement = !iter.hasNext() && needBraces && !JsRequiresSemiVisitor.exec(stmt); - if (functionStmt) { - if (lastStatement) { - _newlineOpt(); - } else { - _newline(); - } - } else { - if (lastStatement) { - _semiOpt(); - } else { - _semi(); - } - _newlineOpt(); - } - } - if (shouldRecordPositions) { - assert (statementStarts.size() == statementEnds.size() + 1); - statementEnds.add(p.getPosition()); - } - } - - if (needBraces) { - // _blockClose() modified - p.indentOut(); - p.print('}'); - if (finalNewline) { - _newlineOpt(); - } - } - needSemi = false; - } - - private void _assignment() { - p.print('='); - } - - private void _blockClose() { - p.indentOut(); - p.print('}'); - _newlineOpt(); - } - - private void _blockOpen() { - p.print('{'); - p.indentIn(); - _newlineOpt(); - } - - private void _break() { - p.print(CHARS_BREAK); - } - - private void _case() { - p.print(CHARS_CASE); - } - - private void _catch() { - p.print(CHARS_CATCH); - } - - private void _colon() { - p.print(':'); - } - - private void _continue() { - p.print(CHARS_CONTINUE); - } - - private void _debugger() { - p.print(CHARS_DEBUGGER); - } - - private void _default() { - p.print(CHARS_DEFAULT); - } - - private void _do() { - p.print(CHARS_DO); - } - - private void _dot() { - p.print('.'); - } - - private void _else() { - p.print(CHARS_ELSE); - } - - private void _false() { - p.print(CHARS_FALSE); - } - - private void _finally() { - p.print(CHARS_FINALLY); - } - - private void _for() { - p.print(CHARS_FOR); - } - - private void _function() { - p.print(CHARS_FUNCTION); - } - - private void _if() { - p.print(CHARS_IF); - } - - private void _in() { - p.print(CHARS_IN); - } - - private void _lbrace() { - p.print('{'); - } - - private void _lparen() { - p.print('('); - } - - private void _lsquare() { - p.print('['); - } - - private void _nameDef(JsName name) { - p.print(name.getShortIdent()); - } - - private void _nameOf(HasName hasName) { - _nameDef(hasName.getName()); - } - - private void _nameRef(JsNameRef nameRef) { - p.print(nameRef.getShortIdent()); - } - - private boolean _nestedPop(JsStatement statement) { - boolean pop = !(statement instanceof JsBlock); - if (pop) { - p.indentOut(); - } - return pop; - } - - private boolean _nestedPush(JsStatement statement, boolean needSpace) { - boolean push = !(statement instanceof JsBlock); - if (push) { - if (needSpace) { - _space(); - } - p.indentIn(); - _newlineOpt(); - } else { - _spaceOpt(); - } - return push; - } - - private void _new() { - p.print(CHARS_NEW); - } - - private void _null() { - p.print(CHARS_NULL); - } - - private boolean _parenCalc(JsExpression parent, JsExpression child, boolean wrongAssoc) { - int parentPrec = JsPrecedenceVisitor.exec(parent); - int childPrec = JsPrecedenceVisitor.exec(child); - return (parentPrec > childPrec || (parentPrec == childPrec && wrongAssoc)); - } - - private boolean _parenPop(JsExpression parent, JsExpression child, boolean wrongAssoc) { - boolean doPop = _parenCalc(parent, child, wrongAssoc); - if (doPop) { - _rparen(); - } - return doPop; - } - - private boolean _parenPopIfCommaExpr(JsExpression x) { - boolean doPop = - x instanceof JsBinaryOperation - && ((JsBinaryOperation) x).getOperator() == JsBinaryOperator.COMMA; - if (doPop) { - _rparen(); - } - return doPop; - } - - private boolean _parenPopOrSpace(JsExpression parent, JsExpression child, boolean wrongAssoc) { - boolean doPop = _parenCalc(parent, child, wrongAssoc); - if (doPop) { - _rparen(); - } else { - _space(); - } - return doPop; - } - - private boolean _parenPush(JsExpression parent, JsExpression child, boolean wrongAssoc) { - boolean doPush = _parenCalc(parent, child, wrongAssoc); - if (doPush) { - _lparen(); - } - return doPush; - } - - private boolean _parenPushIfCommaExpr(JsExpression x) { - boolean doPush = - x instanceof JsBinaryOperation - && ((JsBinaryOperation) x).getOperator() == JsBinaryOperator.COMMA; - if (doPush) { - _lparen(); - } - return doPush; - } - - private boolean _parenPushOrSpace(JsExpression parent, JsExpression child, boolean wrongAssoc) { - boolean doPush = _parenCalc(parent, child, wrongAssoc); - if (doPush) { - _lparen(); - } else { - _space(); - } - return doPush; - } - - private void _questionMark() { - p.print('?'); - } - - private void _rbrace() { - p.print('}'); - } - - private void _return() { - p.print(CHARS_RETURN); - } - - private void _rparen() { - p.print(')'); - } - - private void _rsquare() { - p.print(']'); - } - - private void _semi() { - p.print(';'); - } - - private void _semiOpt() { - p.printOpt(';'); - } - - private boolean _sepCommaOptSpace(boolean sep) { - if (sep) { - p.print(','); - _spaceOpt(); - } - return true; - } - - private void _slash() { - p.print('/'); - } - - private void _space() { - p.print(' '); - } - - /** - * Decide whether, if op is printed followed by arg, - * there needs to be a space between the operator and expression. - * - * @return true if a space needs to be printed - */ - private boolean _spaceCalc(JsOperator op, JsExpression arg) { - if (op.isKeyword()) { - return true; - } - if (arg instanceof JsBinaryOperation) { - JsBinaryOperation binary = (JsBinaryOperation) arg; - /* - * If the binary operation has a higher precedence than op, then it won't - * be parenthesized, so check the first argument of the binary operation. - */ - if (binary.getOperator().getPrecedence() > op.getPrecedence()) { - return _spaceCalc(op, binary.getArg1()); - } - return false; - } - if (arg instanceof JsPrefixOperation) { - JsOperator op2 = ((JsPrefixOperation) arg).getOperator(); - return (op == JsBinaryOperator.SUB || op == JsUnaryOperator.NEG) - && (op2 == JsUnaryOperator.DEC || op2 == JsUnaryOperator.NEG) - || (op == JsBinaryOperator.ADD && op2 == JsUnaryOperator.INC); - } - if (arg instanceof JsNumberLiteral) { - JsNumberLiteral literal = (JsNumberLiteral) arg; - return (op == JsBinaryOperator.SUB || op == JsUnaryOperator.NEG) && (literal.getValue() < 0); - } - return false; - } - - private void _spaceOpt() { - p.printOpt(' '); - } - - private void _switch() { - p.print(CHARS_SWITCH); - } - - private void _this() { - p.print(CHARS_THIS); - } - - private void _throw() { - p.print(CHARS_THROW); - } - - private void _true() { - p.print(CHARS_TRUE); - } - - private void _try() { - p.print(CHARS_TRY); - } - - private void _var() { - p.print(CHARS_VAR); - } - - private void _while() { - p.print(CHARS_WHILE); - } - - // CHECKSTYLE_NAMING_ON - - private void indent() { - p.indentIn(); - } - - private void outdent() { - p.indentOut(); - } - - private void printStringLiteral(String value) { - String resultString = javaScriptString(value); - p.print(resultString); - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/NormalizedVisitor.java b/compiler/java/com/google/dart/compiler/backend/js/NormalizedVisitor.java deleted file mode 100644 index 9ca13af9647..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/NormalizedVisitor.java +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.ast.DartContext; -import com.google.dart.compiler.ast.DartNode; -import com.google.dart.compiler.ast.DartVisitable; -import com.google.dart.compiler.ast.DartVisitor; - -/** - * A visitor that always visits the normalized node. - */ -class NormalizedVisitor extends DartVisitor { - @Override - protected void doTraverse(DartVisitable visitable, DartContext ctx) { - DartNode node = (DartNode) visitable; - super.doTraverse(node.getNormalizedNode(), ctx); - } -} \ No newline at end of file diff --git a/compiler/java/com/google/dart/compiler/backend/js/Normalizer.java b/compiler/java/com/google/dart/compiler/backend/js/Normalizer.java deleted file mode 100644 index 5813042645d..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/Normalizer.java +++ /dev/null @@ -1,1034 +0,0 @@ -// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.common.collect.Lists; -import com.google.dart.compiler.InternalCompilerException; -import com.google.dart.compiler.ast.DartArrayAccess; -import com.google.dart.compiler.ast.DartBinaryExpression; -import com.google.dart.compiler.ast.DartBlock; -import com.google.dart.compiler.ast.DartCase; -import com.google.dart.compiler.ast.DartClass; -import com.google.dart.compiler.ast.DartClassMember; -import com.google.dart.compiler.ast.DartContext; -import com.google.dart.compiler.ast.DartDefault; -import com.google.dart.compiler.ast.DartDoWhileStatement; -import com.google.dart.compiler.ast.DartExprStmt; -import com.google.dart.compiler.ast.DartExpression; -import com.google.dart.compiler.ast.DartForInStatement; -import com.google.dart.compiler.ast.DartForStatement; -import com.google.dart.compiler.ast.DartFunction; -import com.google.dart.compiler.ast.DartFunctionExpression; -import com.google.dart.compiler.ast.DartFunctionObjectInvocation; -import com.google.dart.compiler.ast.DartIdentifier; -import com.google.dart.compiler.ast.DartIfStatement; -import com.google.dart.compiler.ast.DartInitializer; -import com.google.dart.compiler.ast.DartIntegerLiteral; -import com.google.dart.compiler.ast.DartLabel; -import com.google.dart.compiler.ast.DartMethodDefinition; -import com.google.dart.compiler.ast.DartMethodInvocation; -import com.google.dart.compiler.ast.DartModVisitor; -import com.google.dart.compiler.ast.DartNewExpression; -import com.google.dart.compiler.ast.DartNode; -import com.google.dart.compiler.ast.DartNodeTraverser; -import com.google.dart.compiler.ast.DartParameter; -import com.google.dart.compiler.ast.DartParenthesizedExpression; -import com.google.dart.compiler.ast.DartPropertyAccess; -import com.google.dart.compiler.ast.DartRedirectConstructorInvocation; -import com.google.dart.compiler.ast.DartReturnStatement; -import com.google.dart.compiler.ast.DartStatement; -import com.google.dart.compiler.ast.DartSuperConstructorInvocation; -import com.google.dart.compiler.ast.DartSwitchMember; -import com.google.dart.compiler.ast.DartSwitchStatement; -import com.google.dart.compiler.ast.DartThrowStatement; -import com.google.dart.compiler.ast.DartTypeNode; -import com.google.dart.compiler.ast.DartUnaryExpression; -import com.google.dart.compiler.ast.DartUnit; -import com.google.dart.compiler.ast.DartVariable; -import com.google.dart.compiler.ast.DartVariableStatement; -import com.google.dart.compiler.ast.DartWhileStatement; -import com.google.dart.compiler.ast.Modifiers; -import com.google.dart.compiler.parser.Token; -import com.google.dart.compiler.resolver.ClassElement; -import com.google.dart.compiler.resolver.ConstructorElement; -import com.google.dart.compiler.resolver.CoreTypeProvider; -import com.google.dart.compiler.resolver.Element; -import com.google.dart.compiler.resolver.ElementKind; -import com.google.dart.compiler.resolver.Elements; -import com.google.dart.compiler.resolver.EnclosingElement; -import com.google.dart.compiler.resolver.FieldElement; -import com.google.dart.compiler.resolver.LabelElement; -import com.google.dart.compiler.resolver.MethodElement; -import com.google.dart.compiler.resolver.SyntheticDefaultConstructorElement; -import com.google.dart.compiler.resolver.VariableElement; -import com.google.dart.compiler.type.InterfaceType; -import com.google.dart.compiler.type.Types; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Normalization phase of Dart compiler. Rewrites the AST to simplify later - * phases. - *
    - *
  • Split 'type' declarations such as "int a = 0, b = 0" - *
  • Introduce block statements for control structures such as IF, WHILE, and - * FOR - *
  • normalize case statements, including adding FallThroughError throws - *
  • pull initializers out of FOR loops - *
  • remove useless statement labels - *
  • remove parenthesized expression nodes - *
- */ -public class Normalizer { - - public DartUnit exec(DartUnit unit, CoreTypeProvider typeProvider) { - new ParenNormalizer().accept(unit); - new BlockNormalizer(typeProvider).accept(unit); - new ForLoopInitNormalizer().accept(unit); - // Now that the have been inserted and the For VAR has been - // pulled out. It is easy to split up the VAR declarations. - new VarNormalizer().accept(unit); - unit.accept(new NormalizerVisitor()); - // debugPrint(unit); - return unit; - } - - @SuppressWarnings("unused") - private void debugPrint(DartUnit unit) { - DartNodeTraverser debugPrinter = new DartNodeTraverser() { - @Override - public Void visitClassMember(DartClassMember node) { - System.err.println(node); - return super.visitClassMember(node); - } - - @Override - public Void visitNode(DartNode node) { - DartNode normalizedNode = node.getNormalizedNode(); - if (node != normalizedNode) { - System.err.println("orig: " + node); - System.err.println("norm: " + normalizedNode); - System.err.println(); - } - return super.visitNode(node); - } - }; - unit.accept(debugPrinter); - } - - /** - * Minimize the complexity of adding statements to the AST by inserting BLOCK - * nodes where there can be statements, after this pass there are only - * three statement holders: BLOCK, FOR, and LABEL. - *

- * This also simplifies scope handling. - *

- * The complexity of dealing with LABEL statements is reduced by minimizing - * the number of places that a label can be used to four statement types: - * BLOCK, FOR, WHILE, and DO-WHILE. - * BLOCK could also be removed by using "label:do { statement } while (false);" - * should we choose to. - */ - private static class BlockNormalizer extends DartModVisitor { - - private final ConstructorElement fallThroughError; - - private static ConstructorElement getFallThroughError( - CoreTypeProvider typeProvider) { - ClassElement element = typeProvider.getFallThroughError().getElement(); - // TODO(fabiomfv): remove local resolution once we settle on the approach. - ConstructorElement constructor = element.lookupConstructor(""); - if (constructor == null) { - throw new InternalCompilerException("FallThroughError does not have unnamed constructor."); - } - return constructor; - } - - public BlockNormalizer(CoreTypeProvider typeProvider) { - fallThroughError = getFallThroughError(typeProvider); - } - - @Override - public void endVisit(DartLabel x, DartContext ctx) { - DartStatement body = x.getStatement(); - if (body instanceof DartVariableStatement) { - // TODO(johnlenz): I'm assuming labelled statements don't introduce - // a new scope. - // Don't push a single VAR into a BLOCK, the label can't be referenced - // so drop it entirely. - ctx.replaceMe(body); - } else if (!(body instanceof DartBlock) && !canContinueControlStructure(body)) { - DartIdentifier label = x.getLabel(); - DartLabel replacement = new DartLabel(label, maybeAddBlock(body)); - LabelElement element = (LabelElement) x.getSymbol(); - element.setNode(replacement); - replacement.setSymbol(element); - replacement.setSourceInfo(x); - ctx.replaceMe(replacement); - } - } - - /** - * @return Whether this is a control structure that can be used - * with a named "continue" statement. - */ - private boolean canContinueControlStructure(DartStatement stmt) { - if (stmt instanceof DartForStatement - || stmt instanceof DartWhileStatement - || stmt instanceof DartDoWhileStatement) { - return true; - } - return false; - } - - @Override - public void endVisit(DartForStatement x, DartContext ctx) { - DartStatement body = x.getBody(); - if (!(body instanceof DartBlock)) { - DartStatement init = x.getInit(); - DartExpression condition = x.getCondition(); - DartExpression increment = x.getIncrement(); - - DartStatement replacement = new DartForStatement( - init, condition, increment, maybeAddBlock(body)); - replacement.setSourceInfo(x); - ctx.replaceMe(replacement); - } - } - - @Override - public void endVisit(DartIfStatement x, DartContext ctx) { - DartStatement thenStmt = x.getThenStatement(); - DartStatement elseStmt = x.getElseStatement(); - if (!(thenStmt instanceof DartBlock) || !(elseStmt instanceof DartBlock)) { - DartExpression condition = x.getCondition(); - - // TODO(johnlenz): Preserve source location? - DartIfStatement replacement = new DartIfStatement( - condition, - maybeAddBlock(thenStmt), - (elseStmt != null) ? maybeAddBlock(elseStmt) : null); - replacement.setSourceInfo(x); - ctx.replaceMe(replacement); - } - } - - @Override - public void endVisit(DartWhileStatement x, DartContext ctx) { - DartStatement body = x.getBody(); - if (!(body instanceof DartBlock)) { - DartExpression condition = x.getCondition(); - - // TODO(johnlenz): Preserve source location? - DartWhileStatement replacement = new DartWhileStatement( - condition, maybeAddBlock(body)); - replacement.setSourceInfo(x); - ctx.replaceMe(replacement); - } - } - - @Override - public void endVisit(DartDoWhileStatement x, DartContext ctx) { - DartStatement body = x.getBody(); - if (!(body instanceof DartBlock)) { - DartExpression condition = x.getCondition(); - - // TODO(johnlenz): Preserve source location? - DartDoWhileStatement replacement = new DartDoWhileStatement( - condition, maybeAddBlock(body)); - replacement.setSourceInfo(x); - ctx.replaceMe(replacement); - } - } - - /** - * Normalize case statements. There are two main things to be accomplished: - *

    - *
  1. add throw new FallThroughError at the end of non-empty cases which - * may fall through to the next block - *
  2. wrap individual statements or empty cases in blocks - *
- * - * For example: - *
-     * case 1:
-     * case 2: ...
-     * 
- * becomes - *
-     * case 1: {}
-     * case 2: ...
-     * 
- * while this: - *
-     * case 1: {}
-     * case 2: ...
-     * 
- * becomes - *
-     * case 1: { throw new FallThroughError(); }
-     * case 2: ...
-     * 
- * The last case (and any empty labels that fall through into it) does not get - * a throw added, but does get changed to an empty block. - * - * @param caseStmt the "case: stmt;*" block being normalized - * @param ctx {@link DartContext} - */ - @Override - public void endVisit(DartCase caseStmt, DartContext ctx) { - List stmts = caseStmt.getStatements(); - if (stmts.size() == 0) { - replaceWithBlock(stmts, Lists.newArrayList(stmts)); - return; - } - - // unpack an outer block if present - List innerStatements = stmts; - if (stmts.get(0) instanceof DartBlock) { - innerStatements = ((DartBlock) stmts.get(0)).getStatements(); - } - - // check if we need to add a throw - boolean needsThrow = !isLastSwitchMember(caseStmt); - if (needsThrow) { - // TODO(jat): should we only look at the last statement? - // DartParser.parseCaseStatemets seems to stop as soon as it hits an - // AbruptCompletingStatement. - for (DartStatement stmt : innerStatements) { - if (stmt.isAbruptCompletingStatement()) { - needsThrow = false; - break; - } - } - } - - // if we don't need to modify the block, nothing to do - if (!needsThrow && stmts.get(0) instanceof DartBlock) { - return; - } - - // copy the list of statements and add a throw - List newStmts = Lists.newArrayList(innerStatements); - if (needsThrow) { - newStmts.add(buildThrow(fallThroughError)); - } - caseStmt.setNormalizedNode(new DartCase(caseStmt.getExpr(), caseStmt.getLabel(), newStmts)); - replaceWithBlock(stmts, newStmts); - } - - /** - * Check to see if the supplied switch member is the last one in the switch - * statement, or is allowed to fall through to the last one. - * - * @param member - * @return true if the specified member is the last one in the switch - * statement or is allowed to fall through to the l - */ - private boolean isLastSwitchMember(DartSwitchMember member) { - /* - * We are replacing empty switch members with empty blocks as we go, but - * that is ok because we start from the end here. - */ - DartSwitchStatement switchStmt = (DartSwitchStatement) member.getParent(); - List members = switchStmt.getMembers(); - int i = members.size() - 1; - if (members.get(i) == member) { - // last switch member - return true; - } - // now we only want ones that are empty and have no non-empty switch members - // between them and the last member - while (i >= 0) { - DartSwitchMember curMember = members.get(i); - if (curMember.getStatements().size() > 0) { - // non-empty, so no earlier members can fall through - return false; - } - if (curMember == member) { - return true; - } - i--; - } - return false; - } - - /** - * Create a throw new ExceptionCtor() statement. - * - * @param exceptionCtor constructor to use to create exception instance - * @param args zero or more arguments for the supplied constructor - * @return a {@link DartStatement} representing a throw of the supplied - * exception - */ - private static DartStatement buildThrow(ConstructorElement exceptionCtor, - DartExpression... args) { - // Create AST nodes representing 'throw new FallThroughException();'. - DartNewExpression newExpr = new DartNewExpression(new DartTypeNode(new DartIdentifier( - exceptionCtor.getName())), Arrays.asList(args), false); - newExpr.setSymbol(exceptionCtor); - return new DartThrowStatement(newExpr); - } - - /** - * @param stmts - * @param newStmts - */ - private void replaceWithBlock(List stmts, List newStmts) { - DartBlock block = new DartBlock(newStmts); - stmts.clear(); - stmts.add(block); - } - - @Override - public void endVisit(DartDefault member, DartContext ctx) { - // default labels must be last, so they do not need to throw FallThroughErrors - // So, all we need to do is make sure they are blocks - List stmts = member.getStatements(); - if (stmts.size() == 0 || !(stmts.get(0) instanceof DartBlock)) { - replaceWithBlock(stmts, Lists.newArrayList(stmts)); - } - } - - private DartBlock maybeAddBlock(DartStatement statement) { - if (statement instanceof DartBlock) { - return (DartBlock)statement; - } - return new DartBlock(Lists.newArrayList(statement)); - } - } - - /** - * Extract the any initializer statements out of the FOR loop. This is done - * to minimize the amount of code that needs to be special cased for handling - * expressions in a FOR loop. - */ - private static class ForLoopInitNormalizer extends DartModVisitor { - @Override - public boolean visit(DartLabel x, DartContext ctx) { - // Pulled any FOR loop initializer expressions up above the label, - // we do this in the visit to allow the DartForStatement to handle - // the unlabelled case. - - LabeledForVisitor labelVisitor = new LabeledForVisitor(); - labelVisitor.accept(x); - if (labelVisitor.forInit != null) { - // FOR loop initializer need to be scoped, put them in a block. - List stmts = Lists.newArrayList(labelVisitor.forInit, x); - DartBlock replacement = new DartBlock(stmts); - ctx.replaceMe(replacement); - - // The removed expression hasn't be visited yet, do it now so it isn't - // skipped. - accept(replacement); - } - return true; - } - - @Override - public void endVisit(DartForStatement x, DartContext ctx) { - DartStatement init = x.getInit(); - if (init != null) { - DartStatement body = x.getBody(); - DartExpression condition = x.getCondition(); - DartExpression increment = x.getIncrement(); - - DartStatement newFor = new DartForStatement( - null, condition, increment, body); - newFor.setSourceInfo(x); - - // FOR loop initializer need to be scoped, put them in a block. - DartStatement replacementBlock = new DartBlock( - Lists.newArrayList(init, newFor)); - - ctx.replaceMe(replacementBlock); - } - } - - private static class LabeledForVisitor extends DartModVisitor { - DartStatement forInit = null; - - @Override - public boolean visit(DartForStatement x, DartContext ctx) { - if (x.getInit() != null) { - DartStatement init = x.getInit(); - if (init != null) { - DartStatement body = x.getBody(); - DartExpression condition = x.getCondition(); - DartExpression increment = x.getIncrement(); - - // TODO(johnlenz): Preserve source location? - DartStatement newFor = new DartForStatement( - null, condition, increment, body); - newFor.setSourceInfo(x); - ctx.replaceMe(newFor); - } - forInit = init; - } - return false; - } - - @Override - public boolean visit(DartLabel x, DartContext ctx) { - DartStatement stmt = x.getStatement(); - return (stmt instanceof DartLabel) || (stmt instanceof DartForStatement); - } - } - } - - /** - * Remove parenthesized expression nodes. This simplifies all of the rest of - * the normalizers by not requiring them to deal with this special case. - */ - private static class ParenNormalizer extends DartModVisitor { - @Override - public void endVisit(DartParenthesizedExpression x, DartContext ctx) { - ctx.replaceMe(x.getExpression()); - } - } - - /** - * Split VAR declarations so that there is only one VAR declaration per - * statement. This simplifies rewriting of VAR statements. - */ - private static class VarNormalizer extends DartModVisitor { - @Override - public void endVisit(DartVariableStatement x, DartContext ctx) { - List vars = x.getVariables(); - if (vars.size() > 1) { - for (DartVariable v : vars) { - DartVariableStatement stmt = new DartVariableStatement( - Lists.newArrayList(v), x.getTypeNode()); - stmt.setSourceInfo(v); - ctx.insertBefore(stmt); - } - ctx.removeMe(); - } - } - } - - /** - * The actual normalization. - */ - private static class NormalizerVisitor extends DartNodeTraverser { - // Collects names to avoid conflicts with synthesized variables. - private final Set usedNames = new HashSet(); - - @Override - public DartNode visitClassMember(DartClassMember node) { - usedNames.clear(); - return super.visitClassMember(node); - } - - @Override - public DartNode visitForInStatement(DartForInStatement node) { - node.visitChildren(this); - - // Normalize for (var? name in expression) { ... } into: - // { - // var i = expression.iterator(); - // while (i.hasNext()) { - // var? name = i.next(); - // ... - // } - // } - List topLevelStatements = new ArrayList(); - - // Generate the call to expression.iterator(). - DartMethodInvocation iteratorCall = call(node.getIterable(), "iterator"); - - // Create and add the iterator variable to the statements. - DartVariableStatement iteratorVariable = makeTempVariable(0, iteratorCall); - topLevelStatements.add(iteratorVariable); - - // Generate the call to i.hasNext(); - DartIdentifier iterator = ref(iteratorVariable); - DartMethodInvocation hasNext = call(iterator, "hasNext"); - - // Generate the call to i.next(); - iterator = ref(iteratorVariable); - DartMethodInvocation next = call(iterator, "next"); - - DartStatement setup = normalizeForInSetup(node, next); - DartWhileStatement whileStatement = whileStmt(hasNext, setup, node.getBody()); - topLevelStatements.add(whileStatement); - - DartBlock newBlock = new DartBlock(topLevelStatements); - node.setNormalizedNode(newBlock); - return node; - } - - private DartStatement normalizeForInSetup(DartForInStatement node, DartExpression next) { - if (node.introducesVariable()) { - // Since we're going to change the variable to have an initializer expression, - // we have to create a new variable statement around it too. Make sure it has - // the right type and modifiers. - DartVariableStatement variableStatement = node.getVariableStatement(); - DartVariable oldVariable = variableStatement.getVariables().get(0); - DartVariable newVariable = new DartVariable(oldVariable.getName(), next); - newVariable.setSymbol(oldVariable.getSymbol()); - return new DartVariableStatement(Lists.newArrayList(newVariable), - variableStatement.getTypeNode(), variableStatement.getModifiers()); - } else { - return exprStmt(assign(node.getIdentifier(), next)); - } - } - - @Override - public DartNode visitClass(DartClass node) { - final ClassElement classElement = node.getSymbol(); - // Ensure implicit default constructor with method. - if (Elements.needsImplicitDefaultConstructor(classElement)) { - DartMethodDefinition method = createImplicitDefaultConstructor(classElement); - // TODO - We should really normalize the class itself. - node.getMembers().add(method); - } - return super.visitClass(node); - } - - private DartMethodDefinition createImplicitDefaultConstructor(final ClassElement classElement) { - assert (Elements.needsImplicitDefaultConstructor(classElement)); - DartFunction function = new DartFunction(Collections.emptyList(), - new DartBlock(Collections.emptyList()), null); - final DartMethodDefinition method = - DartMethodDefinition.create(new DartIdentifier(""), function, Modifiers.NONE, null); - method.setSymbol(new SyntheticDefaultConstructorElement(method, classElement, null)); - return method; - } - - @Override - public DartExpression visitBinaryExpression(DartBinaryExpression node) { - node.visitChildren(this); - Token operator = node.getOperator(); - if (operator.isAssignmentOperator() && operator != Token.ASSIGN) { - node.setNormalizedNode(normalizeCompoundAssignment(mapAssignableOp(operator), false, - node.getArg1().getNormalizedNode(), - node.getArg2().getNormalizedNode())); - } - return node; - } - - @Override - public DartExpression visitUnaryExpression(DartUnaryExpression node) { - node.visitChildren(this); - Token operator = node.getOperator(); - if (operator.isCountOperator()) { - DartExpression lhs = node.getArg().getNormalizedNode(); - DartIntegerLiteral rhs = DartIntegerLiteral.one(); - node.setNormalizedNode(normalizeCompoundAssignment(mapAssignableOp(operator), - !node.isPrefix(), lhs, rhs)); - } - return node; - } - - static class NeedsImplicitSuperInvocationDeterminant extends DartNodeTraverser { - private boolean needsSuperInvocation = true; - - @Override - public Void visitSuperConstructorInvocation(DartSuperConstructorInvocation node) { - needsSuperInvocation = false; - return super.visitSuperConstructorInvocation(node); - } - - @Override - public Void visitRedirectConstructorInvocation(DartRedirectConstructorInvocation node) { - needsSuperInvocation = false; - return super.visitRedirectConstructorInvocation(node); - } - - @Override - public Void visitMethodDefinition(DartMethodDefinition node) { - // Ignore everything except the initializers - for (DartInitializer initializer : node.getInitializers()) { - initializer.accept(this); - } - return null; - } - } - - @Override - public DartMethodDefinition visitMethodDefinition(DartMethodDefinition node) { - super.visitMethodDefinition(node); - if (Elements.isNonFactoryConstructor(node.getSymbol())) { - normalizeParameterInitializer(node); - } - - return node; - } - - @Override - public DartNode visitNewExpression(DartNewExpression node) { - ConstructorElement symbol = node.getSymbol(); - if (symbol == null) { - InterfaceType constructorType = Types.constructorType(node); - if (!constructorType.getElement().isDynamic() && node.getArgs().isEmpty()) { - // HACK use proper normalized node - ClassElement classToInstantiate = constructorType.getElement(); - if (classToInstantiate.getDefaultClass() != null) { - classToInstantiate = classToInstantiate.getDefaultClass().getElement(); - } - - if (classToInstantiate != null - && Elements.needsImplicitDefaultConstructor(classToInstantiate)) { - DartMethodDefinition implicitDefaultConstructor = - createImplicitDefaultConstructor(classToInstantiate); - node.setSymbol(implicitDefaultConstructor.getSymbol()); - } - } - } - - return super.visitNewExpression(node); - } - - @Override - public DartNode visitSwitchStatement(DartSwitchStatement node) { - node.getExpression().accept(this); - for (DartNode member : node.getMembers()) { - member.accept(this); - } - return node; - } - - // Normalize parameter initializer. - // transforms: class A { A(this.x) { } } - // into: class A { A(this.x) : this.x = x { } - private void normalizeParameterInitializer(DartMethodDefinition node) { - List nInit = new ArrayList(); - for (DartParameter param : node.getFunction().getParams()) { - FieldElement fieldElement = param.getSymbol().getParameterInitializerElement(); - if (fieldElement != null) { - DartIdentifier left = new DartIdentifier(param.getParameterName()); - left.setSymbol(fieldElement); - left.setSourceInfo(param); - Element ve = Elements.makeVariable(param.getParameterName()); - DartParameter nParam = new DartParameter(param.getName(), param.getTypeNode(), - param.getFunctionParameters(), param.getDefaultExpr(), param.getModifiers()); - nParam.setSymbol(ve); - param.setNormalizedNode(nParam); - DartIdentifier right = new DartIdentifier(param.getParameterName()); - right.setSymbol(ve); - right.setSourceInfo(param); - DartInitializer di = new DartInitializer(left, right); - di.setSourceInfo(param); - nInit.add(di); - } - } - - EnclosingElement enclosingElement = node.getSymbol().getEnclosingElement(); - if (ElementKind.of(enclosingElement) == ElementKind.CLASS) { - ClassElement classElement = (ClassElement) enclosingElement; - if (!classElement.isObject()) { - NeedsImplicitSuperInvocationDeterminant superLocator = new NeedsImplicitSuperInvocationDeterminant(); - node.accept(superLocator); - if (superLocator.needsSuperInvocation) { - DartSuperConstructorInvocation superInvocation = new DartSuperConstructorInvocation( - new DartIdentifier(""), Collections.emptyList()); - // Set constructor element - actual constructor with all named parameters or synthetic. - ConstructorElement superConstructorElement = null; - { - ClassElement superTypeElement = classElement.getSupertype().getElement(); - List constructors = superTypeElement.getConstructors(); - for (ConstructorElement constructor : constructors) { - if (hasOnlyNamedParameters(constructor)) { - superConstructorElement = constructor; - break; - } - } - if (superConstructorElement == null) { - superConstructorElement = - new SyntheticDefaultConstructorElement(null, superTypeElement, null); - } - superInvocation.setSymbol(superConstructorElement); - } - // Add implicit "super" invocation. - nInit.add(new DartInitializer(null, superInvocation)); - } - } - } - - if (!nInit.isEmpty()) { - if (!node.getInitializers().isEmpty()) { - nInit.addAll(0, node.getInitializers()); - } - - DartMethodDefinition nConstructor = DartMethodDefinition.create( - node.getName(), node.getFunction(), node.getModifiers(), nInit); - nConstructor.setSymbol(node.getSymbol()); - nConstructor.setSourceInfo(node.getSourceInfo()); - node.setNormalizedNode(nConstructor); - } - } - - /** - * @return true if given constructor has only named (i.e. optional) parameters. - */ - private static boolean hasOnlyNamedParameters(ConstructorElement constructor) { - for (VariableElement parameter : constructor.getParameters()) { - if (!parameter.isNamed()) { - return false; - } - } - return true; - } - - private DartExpression normalizeCompoundAssignment(Token operator, - boolean isPostfix, - DartExpression operand1, - DartExpression operand2) { - return operand1.accept(new CompoundAssignmentNormalizer(operator, isPostfix, operand2)); - } - - private String makeTempName(int i) { - String name; - do { - name = "$" + i; - i++; - } while (usedNames.contains(name)); - usedNames.add(name); - return name; - } - - private DartVariableStatement makeTempVariable(int i, DartExpression init) { - String variableName = makeTempName(i); - DartIdentifier variableIdentifier = new DartIdentifier(variableName); - DartVariable variable = new DartVariable(variableIdentifier, init); - VariableElement element = Elements.variableElement(variable, - variableName, - Modifiers.NONE); - variable.setSymbol(element); - return new DartVariableStatement(Lists.newArrayList(variable), null); - } - - private class Let { - private final List arguments; - final DartParameter[] parameters; - - Let(DartExpression... arguments) { - this.arguments = Arrays.asList(arguments); - parameters = new DartParameter[arguments.length]; - for (int i = 0; i < arguments.length; i++) { - parameters[i] = makeTempParameter(i); - } - } - - DartExpression expression() { - DartBlock body = new DartBlock(Arrays.asList(body())); - return call(makeFunctionExpression(body), arguments); - } - - private DartFunctionExpression makeFunctionExpression(DartBlock body) { - DartFunction function = new DartFunction(Arrays.asList(parameters), body , null); - DartFunctionExpression expression = new DartFunctionExpression(null, function, false); - MethodElement element = - Elements.methodFromFunctionExpression(expression, Modifiers.NONE.makeInlinable()); - expression.setSymbol(element); - for (DartParameter parameter : parameters) { - Elements.addParameter(element, parameter.getSymbol()); - } - return expression; - } - - DartExpression p(int i) { - return ref(parameters[i]); - } - - DartStatement[] body() { - return new DartStatement[0]; - } - - private DartParameter makeTempParameter(int i) { - String name = makeTempName(i); - DartIdentifier identifier = new DartIdentifier(name); - DartParameter parameter = new DartParameter(identifier, null, null, null, Modifiers.NONE); - VariableElement element = Elements.parameterElement(parameter, name, Modifiers.NONE); - parameter.setSymbol(element); - return parameter; - } - } - - private class CompoundAssignmentNormalizer extends DartNodeTraverser { - final Token operator; - final boolean isPostfix; - final DartExpression rhs; - - CompoundAssignmentNormalizer(Token operator, boolean isPostfix, - DartExpression rhs) { - this.operator = operator; - this.isPostfix = isPostfix; - this.rhs = rhs; - } - - @Override - public DartExpression visitNode(DartNode lhs) { - throw new AssertionError(lhs); - } - - @Override - public DartExpression visitIdentifier(DartIdentifier id) { - return rewriteExpression(id); - } - - private DartExpression rewriteExpression(final DartExpression lhs) { - if (!isPostfix) { - // Turns: lhs += rhs - // Into: lhs = lhs + rhs - // Turns: ++lhs - // Into: lhs = lhs + 1 - return assign(lhs, bin(operator, lhs, rhs)); - } else { - // Turns: lhs++ - // Into: function($2) { id = $2 + 1; return $2; }(lhs) - return new Let(lhs) { - @Override DartStatement[] body() { - return statements(exprStmt(assign(lhs, bin(operator, p(0), rhs))), - retrn(p(0))); - } - }.expression(); - } - } - - @Override - public DartExpression visitPropertyAccess(DartPropertyAccess access) { - Element element = access.getTargetSymbol(); - if (element != null && element.getModifiers().isStatic()) { - return rewriteExpression(access); - } - final DartIdentifier name = access.getName(); - return new RewriteAccess((DartExpression) access.getQualifier()) { - @Override - DartExpression operand1() { - return access(p(0), name); - } - }.expression(); - } - - @Override - public DartExpression visitArrayAccess(DartArrayAccess access) { - DartExpression target = access.getTarget(); - DartExpression key = access.getKey(); - // TODO(5408710): Evaluation order of target vs. key? (order passed to constructor) - return new RewriteAccess(target, key) { - @Override - DartExpression operand1() { - return arrayAccess(p(0), p(1)); - } - }.expression(); - } - - private abstract class RewriteAccess extends Let { - public RewriteAccess(DartExpression... arguments) { - super(arguments); - } - - abstract DartExpression operand1(); - - @Override - DartStatement[] body() { - final DartExpression operand1 = operand1(); - if (isPostfix) { - // Turns: this[0.0]-- - // Into: function($0, $1) { - // return function($2) { $0[$1] = $2 - 1; return $2; }($0[$1]); - // }(this, 0.0) - Let let = new Let(operand1) { - @Override DartStatement[] body() { - return statements(exprStmt(assign(operand1, bin(operator, p(0), rhs))), - retrn(p(0))); - } - }; - return statements(retrn(let.expression())); - } else { - // Turns: this[0.0] += $0 - // Into: function($3, $4) { return $3[$4] = $3[$4] + $0; }(this, 0.0) - // Turns: ++this[0.0] - // Into: function($3, $4) { return $3[$4] = $3[$4] + 1; }(this, 0.0) - return statements(retrn(assign(operand1, bin(operator, operand1, rhs)))); - } - } - } - } - - private DartStatement[] statements(DartStatement... statements) { - return statements; - } - - private DartWhileStatement whileStmt(DartExpression condition, DartStatement... statements) { - return new DartWhileStatement(condition, new DartBlock(Arrays.asList(statements))); - } - - private DartExpression call(DartFunctionExpression function, List args) { - return new DartFunctionObjectInvocation(function, args); - } - - private DartMethodInvocation call(DartExpression receiver, String name) { - return new DartMethodInvocation(receiver, - new DartIdentifier(name), - Collections.emptyList()); - } - - private DartArrayAccess arrayAccess(DartExpression target, DartExpression key) { - return new DartArrayAccess(target, key); - } - - private DartReturnStatement retrn(DartExpression value) { - return new DartReturnStatement(value); - } - - private DartBinaryExpression bin(Token operator, DartExpression lhs, DartExpression rhs) { - return new DartBinaryExpression(operator, lhs, rhs); - } - - private DartBinaryExpression assign(DartExpression lhs, DartExpression rhs) { - return bin(Token.ASSIGN, lhs, rhs); - } - - private DartExprStmt exprStmt(DartExpression expression) { - return new DartExprStmt(expression); - } - - private DartPropertyAccess access(DartExpression qualifier, DartIdentifier name) { - return new DartPropertyAccess(qualifier, name); - } - - private DartExpression ref(DartParameter parameter) { - DartIdentifier identifier = new DartIdentifier(parameter.getParameterName()); - identifier.setSymbol(parameter.getSymbol()); - return identifier; - } - - private DartIdentifier ref(DartVariableStatement variableStatement) { - DartVariable variable = variableStatement.getVariables().get(0); - DartIdentifier identifier = new DartIdentifier(variable.getVariableName()); - identifier.setSymbol(variable.getSymbol()); - return identifier; - } - - private Token mapAssignableOp(Token operator) { - switch (operator) { - case ASSIGN_BIT_OR: return Token.BIT_OR; - case ASSIGN_BIT_XOR: return Token.BIT_XOR; - case ASSIGN_BIT_AND: return Token.BIT_AND; - case ASSIGN_SHL: return Token.SHL; - case ASSIGN_SAR: return Token.SAR; - case ASSIGN_ADD: return Token.ADD; - case ASSIGN_SUB: return Token.SUB; - case ASSIGN_MUL: return Token.MUL; - case ASSIGN_DIV: return Token.DIV; - case ASSIGN_MOD: return Token.MOD; - case ASSIGN_TRUNC: return Token.TRUNC; - case INC: return Token.ADD; - case DEC: return Token.SUB; - - default: - throw new InternalCompilerException("Invalid assignment operator"); - } - } - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java b/compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java deleted file mode 100644 index 3f3cafb7207..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java +++ /dev/null @@ -1,1277 +0,0 @@ -// Copyright 2012, the Dart project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.dart.compiler.backend.js; - -import static com.google.dart.compiler.util.AstUtil.and; -import static com.google.dart.compiler.util.AstUtil.assign; -import static com.google.dart.compiler.util.AstUtil.call; -import static com.google.dart.compiler.util.AstUtil.comma; -import static com.google.dart.compiler.util.AstUtil.nameref; -import static com.google.dart.compiler.util.AstUtil.neq; -import static com.google.dart.compiler.util.AstUtil.newAssignment; -import static com.google.dart.compiler.util.AstUtil.newInvocation; -import static com.google.dart.compiler.util.AstUtil.newNameRef; -import static com.google.dart.compiler.util.AstUtil.newQualifiedNameRef; -import static com.google.dart.compiler.util.AstUtil.newVar; -import static com.google.dart.compiler.util.AstUtil.not; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.dart.compiler.InternalCompilerException; -import com.google.dart.compiler.ast.DartArrayLiteral; -import com.google.dart.compiler.ast.DartClass; -import com.google.dart.compiler.ast.DartClassMember; -import com.google.dart.compiler.ast.DartFunctionExpression; -import com.google.dart.compiler.ast.DartFunctionTypeAlias; -import com.google.dart.compiler.ast.DartMapLiteral; -import com.google.dart.compiler.ast.DartMethodDefinition; -import com.google.dart.compiler.ast.DartNewExpression; -import com.google.dart.compiler.ast.DartParameter; -import com.google.dart.compiler.ast.DartTypeNode; -import com.google.dart.compiler.backend.js.ast.JsArrayAccess; -import com.google.dart.compiler.backend.js.ast.JsArrayLiteral; -import com.google.dart.compiler.backend.js.ast.JsBlock; -import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsFunction; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.google.dart.compiler.backend.js.ast.JsParameter; -import com.google.dart.compiler.backend.js.ast.JsProgram; -import com.google.dart.compiler.backend.js.ast.JsReturn; -import com.google.dart.compiler.backend.js.ast.JsScope; -import com.google.dart.compiler.backend.js.ast.JsStatement; -import com.google.dart.compiler.backend.js.ast.JsStringLiteral; -import com.google.dart.compiler.backend.js.ast.JsThisRef; -import com.google.dart.compiler.common.SourceInfo; -import com.google.dart.compiler.common.Symbol; -import com.google.dart.compiler.resolver.ClassElement; -import com.google.dart.compiler.resolver.ConstructorElement; -import com.google.dart.compiler.resolver.CoreTypeProvider; -import com.google.dart.compiler.resolver.DynamicElement; -import com.google.dart.compiler.resolver.Element; -import com.google.dart.compiler.resolver.ElementKind; -import com.google.dart.compiler.resolver.EnclosingElement; -import com.google.dart.compiler.resolver.FunctionAliasElementImplementation; -import com.google.dart.compiler.resolver.LibraryElement; -import com.google.dart.compiler.resolver.MethodElement; -import com.google.dart.compiler.resolver.VariableElement; -import com.google.dart.compiler.type.FunctionAliasType; -import com.google.dart.compiler.type.FunctionType; -import com.google.dart.compiler.type.InterfaceType; -import com.google.dart.compiler.type.Type; -import com.google.dart.compiler.type.TypeKind; -import com.google.dart.compiler.type.TypeVariable; -import com.google.dart.compiler.type.Types; -import com.google.dart.compiler.util.AstUtil; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * A helper class that contains the logic necessary for injecting runtime type references. - * - * @author johnlenz@google.com (John Lenz) - */ -public class RuntimeTypeInjector { - private final boolean emitTypeChecks; - private final TraversalContextProvider context; - private final JsBlock globalBlock; - private final JsScope globalScope; - // Maps builtin types to Javascript types implementations. - private final Map builtInTypeChecks; - private CoreTypeProvider typeProvider; - private final TranslationContext translationContext; - private final Types types; - private final DartMangler mangler; - private final LibraryElement unitLibrary; - private static final String RTT_DYNAMIC_LOOKUP = "RTT.dynamicType.$lookupRTT"; - private static final String RTT_NAMED_PARAMETER = "named"; - - RuntimeTypeInjector( - TraversalContextProvider context, - CoreTypeProvider typeProvider, - TranslationContext translationContext, - boolean emitTypeChecks, DartMangler mangler, - LibraryElement unitLibrary) { - this.context = context; - this.translationContext = translationContext; - JsProgram program = translationContext.getProgram(); - this.globalBlock = program.getGlobalBlock(); - this.globalScope = program.getScope(); - this.builtInTypeChecks = makeBuiltinTypes(typeProvider); - this.typeProvider = typeProvider; - this.emitTypeChecks = emitTypeChecks; - this.mangler = mangler; - this.unitLibrary = unitLibrary; - types = Types.getInstance(typeProvider); - } - - private Map makeBuiltinTypes(CoreTypeProvider typeProvider) { - Map builtinTypes = Maps.newHashMap(); - builtinTypes.put(typeProvider.getBoolType().getElement(), "$isBool"); - builtinTypes.put(typeProvider.getIntType().getElement(), "$isNum"); - builtinTypes.put(typeProvider.getDoubleType().getElement(), "$isNum"); - builtinTypes.put(typeProvider.getStringType().getElement(), "$isString"); - return builtinTypes; - } - - /** - * Generate the code necessary to allow for runtime type checks - */ - void generateRuntimeTypeInfo(DartClass x) { - generateRuntimeTypeInfoMethods(x); - - ClassElement classElement = x.getSymbol(); - if (!classElement.isInterface()) { - injectInterfaceMarkers(classElement, x); - } - } - - /** - * Generate the code necessary to allow for runtime type checks of dart typedefs - */ - void generateRuntimeTypeInfo(DartFunctionTypeAlias x) { - generateRTTLookupMethod(x); - } - - /** - * Generate the code necessary to allow for runtime type checks of dart class methods - */ - void generateRuntimeTypeInfo(DartMethodDefinition x) { - generateRTTLookupMethod(x); - } - - /** - * Generate the code necessary to allow for runtime type checks of dart function expressions - */ - void generateRuntimeTypeInfo(DartFunctionExpression x, String lookupName) { - generateRTTLookupMethod(x, lookupName); - } - - private void injectInterfaceMarkers(ClassElement classElement, SourceInfo srcRef) { - JsProgram program = translationContext.getProgram(); - JsName classJsName = translationContext.getNames().getName(classElement); - for (InterfaceType iface : getAllInterfaces(classElement)) { - JsStatement assignment = (JsStatement) newAssignment( - newNameRef( - newNameRef(new JsNameRef(classJsName), "prototype"), - "$implements$" + translationContext.getMangler().mangleClassName(iface.getElement())), - program.getNumberLiteral(1)).makeStmt().setSourceRef(srcRef); - globalBlock.getStatements().add(assignment); - } - } - - private Set getAllInterfaces(ClassElement classElement) { - // TODO(johnlenz): All interfaces here should not include the super class implemented interfaces - // those are handled by the super-class definition. - Set interfaces = Sets.newLinkedHashSet(); - if (classElement.getType() == null) { - throw new InternalCompilerException("type is null on ClassElement " + classElement); - } - // A class needs to implement its own implied interface so the "is" - // implementation works properly. - interfaces.add(classElement.getType()); - - InterfaceType current = classElement.getType(); - if (current != null) { - addAllInterfaces(interfaces, current); - } - return interfaces; - } - - private void addAllInterfaces(Set interfaces, InterfaceType t) { - interfaces.add(t); - for (InterfaceType current : t.getElement().getInterfaces()) { - addAllInterfaces(interfaces, current); - } - } - - /** - * Insert the function or method necessary to implement runtime type information - * for the provided class. - */ - private void generateRuntimeTypeInfoMethods(DartClass x) { - // 1) create static type information lookup function - generateRTTLookupMethod(x); - - // 2) create a method to fill in the type information for the class - ClassElement classElement = x.getSymbol(); - if (hasRTTImplements(classElement)) { - generateRTTImplementsMethod(x); - } - - // 3) create "addTo" method for use by classes or interfaces that inherit from this class - generateRTTAddToMethod(x); - } - - private void generateRTTLookupMethod(DartClass x) { - ClassElement classElement = x.getSymbol(); - boolean hasTypeParams = hasTypeParameters(classElement); - - // 1) create static type information construction function - // function Foo$lookupOrCreateRTT(typeargs) { - // return $createRTT(name, Foo$RTTimplements, typeargs) ; - // } - - // Build the function - JsFunction lookupFn = new JsFunction(globalScope); - lookupFn.setBody(new JsBlock()); - List body = lookupFn.getBody().getStatements(); - JsScope scope = new JsScope(globalScope, "temp"); - - JsProgram program = translationContext.getProgram(); - - JsInvocation invokeCreate = call(null, - newQualifiedNameRef("RTT.create"), getRTTClassId(classElement)); - List callArgs = invokeCreate.getArguments(); - if (hasRTTImplements(classElement)) { - callArgs.add(getRTTImplementsMethodName(classElement)); - } else { - // need a placeholder param if the typeArgs are needed. - callArgs.add(program.getNullLiteral()); - } - - JsName typeArgs = scope.declareName("typeArgs"); - lookupFn.getParameters().add(new JsParameter(typeArgs)); - if (hasTypeParams) { - callArgs.add(typeArgs.makeRef()); - } else { - callArgs.add(program.getNullLiteral()); - } - - JsName named = scope.declareName(RTT_NAMED_PARAMETER); - lookupFn.getParameters().add(new JsParameter(named)); - callArgs.add(named.makeRef()); - - body.add(new JsReturn(invokeCreate)); - - // Finally, Add the function - JsExpression fnDecl = assign(null, - getRTTLookupMethodNameRef(classElement), lookupFn); - globalBlock.getStatements().add(fnDecl.makeStmt()); - } - - private void generateRTTImplementsMethod(DartClass x) { - ClassElement classElement = x.getSymbol(); - - // 1) create static type information construction function - // function Foo$lookupOrCreateRTT(rtt, typeArgs) { - // - // // superclass - // FooSuper$addTo(rtt, superTypeArg1, ...); - // // interfaces - // FooInterface1$addTo(rtt, interface1TypeArg1, ...); - // - // } - - boolean hasTypeParams = classElement.getTypeParameters().size() > 0; - - // Build the function - JsFunction implementsFn = new JsFunction(globalScope); - implementsFn.setBody(new JsBlock()); - List body = implementsFn.getBody().getStatements(); - JsScope scope = new JsScope(globalScope, "temp"); - - JsName rtt = scope.declareName("rtt"); - implementsFn.getParameters().add(new JsParameter(rtt)); - JsName typeArgs = null; - if (hasTypeParams) { - typeArgs = scope.declareName("typeArgs"); - implementsFn.getParameters().add(new JsParameter(typeArgs)); - } - - JsInvocation callAddTo = newInvocation(getRTTAddToMethodName(classElement), rtt.makeRef()); - if (hasTypeParams) { - typeArgs = scope.declareName("typeArgs"); - callAddTo.getArguments().add(typeArgs.makeRef()); - } - body.add(callAddTo.makeStmt()); - - // Finally, Add the function - JsExpression fnDecl = assign(null, - getRTTImplementsMethodName(classElement), implementsFn); - globalBlock.getStatements().add(fnDecl.makeStmt()); - } - - private void generateRTTAddToMethod(DartClass x) { - ClassElement classElement = x.getSymbol(); - - // 2) create "addTo" method - // Foo$Type$addTo(target, typeargs) { - // var rtt = Foo$lookupOrCreateRTT(typeargs) - // target.implementedTypes[rtt.classkey] = rtt; - // } - - // Build the function - JsFunction addToFn = new JsFunction(globalScope); - addToFn.setBody(new JsBlock()); - JsScope scope = new JsScope(globalScope, "temp"); - - JsName targetType = scope.declareName("target"); - addToFn.getParameters().add(new JsParameter(targetType)); - - // Get the RTT info object - JsName rtt = scope.declareName("rtt"); - List body = addToFn.getBody().getStatements(); - JsInvocation callLookup = newInvocation( - getRTTLookupMethodNameRef(classElement)); - - if (hasTypeParameters(classElement)) { - JsName typeArgs = scope.declareName("typeArgs"); - addToFn.getParameters().add(new JsParameter(typeArgs)); - callLookup.getArguments().add(new JsNameRef(typeArgs)); - } - - JsStatement rttLookup = newVar((SourceInfo)null, rtt, callLookup); - body.add(rttLookup); - - // store it. - JsExpression addToTypes = newAssignment( - new JsArrayAccess( - newNameRef(targetType.makeRef(), "implementedTypes"), - newNameRef(rtt.makeRef(), "classKey")), - rtt.makeRef()); - body.add(addToTypes.makeStmt()); - - InterfaceType superType = classElement.getSupertype(); - if (superType != null && !superType.getElement().isObject()) { - ClassElement interfaceElement = superType.getElement(); - JsInvocation callAddTo = newInvocation( - getRTTAddToMethodName(interfaceElement), targetType.makeRef()); - if (hasTypeParameters(interfaceElement) && !superType.hasDynamicTypeArgs()) { - JsArrayLiteral superTypeArgs = new JsArrayLiteral(); - List typeParams = classElement.getTypeParameters(); - for (Type arg : superType.getArguments()) { - superTypeArgs.getExpressions().add( - buildTypeLookupExpression(arg, typeParams, - nameref(null, targetType.makeRef(), "typeArgs"))); - } - callAddTo.getArguments().add(superTypeArgs); - } - body.add(callAddTo.makeStmt()); - } - - // Add the interfaces - - for (InterfaceType interfaceType : classElement.getInterfaces() ) { - ClassElement interfaceElement = interfaceType.getElement(); - // Codefu: Random addition to keep language/BlackListed13 tests failing. - // RTT.dynamic could define $addTo(), but this should be treated as a - // a compile time error, not a run time error. - if (interfaceElement instanceof DynamicElement) { - continue; - } - JsInvocation callAddTo = call(null, - getRTTAddToMethodName(interfaceElement), targetType.makeRef()); - if (hasTypeParameters(interfaceElement) && !interfaceType.hasDynamicTypeArgs()) { - JsArrayLiteral interfaceTypeArgs = new JsArrayLiteral(); - List typeParams = classElement.getTypeParameters(); - for (Type arg : interfaceType.getArguments()) { - interfaceTypeArgs.getExpressions().add( - buildTypeLookupExpression(arg, typeParams, - nameref(null, targetType.makeRef(), "typeArgs"))); - } - callAddTo.getArguments().add(interfaceTypeArgs); - } - body.add(callAddTo.makeStmt()); - } - - // Add the function statement - JsExpression fnDecl = newAssignment( - getRTTAddToMethodName(classElement), addToFn); - globalBlock.getStatements().add(fnDecl.makeStmt()); - } - - private void generateRTTLookupMethod(DartMethodDefinition x) { - generateRTTLookupMethod(x.getSymbol(), null); - } - - private void generateRTTLookupMethod(DartFunctionExpression x, String overrideName) { - generateRTTLookupMethod(x.getSymbol(), overrideName); - } - - private ClassElement getEnclosingClassElement(EnclosingElement enclosingElement) { - while(enclosingElement != null) { - if (enclosingElement.getKind().equals(ElementKind.CLASS)) { - return (ClassElement)enclosingElement; - } - enclosingElement = enclosingElement.getEnclosingElement(); - } - return null; - } - - /* - * This function will create a lookup function that indirectly calls RTT.createFunction with - * and array of parameter types and the return type as arguments. Example: - * Dart: - * typedef List TestAliasType(int x, K k); - * JS: - * $$Dart.$lookupRTT = function(typeArgs){ - * return RTT.createFunction( - * [int$Dart.$lookupRTT(), RTT.getTypeArg(typeArgs, 0)], - * List$Dart.$lookupRTT([RTT.getTypeArg(typeArgs, 1)])); - * } - */ - private void generateRTTLookupMethod(MethodElement methodElement, String overrideName) { - boolean hasTypeArguments = false; - - if (ElementKind.of(methodElement).equals(ElementKind.CONSTRUCTOR) - || methodElement.getModifiers().isNative()) { - // No type lookups for constructors or natives - return; - } - ClassElement classElement = getEnclosingClassElement(methodElement.getEnclosingElement()); - hasTypeArguments = classElement != null ? hasTypeParameters(classElement) : false; - - JsProgram program = translationContext.getProgram(); - JsExpression typeArgContextExpr = hasTypeArguments ? - buildTypeArgsReferenceFromThis(classElement) : null; - - // Build the function - JsFunction lookupFn = new JsFunction(globalScope); - lookupFn.setBody(new JsBlock()); - JsScope scope = new JsScope(globalScope, "temp"); - - List body = lookupFn.getBody().getStatements(); - JsInvocation callLookup; - - callLookup = newInvocation(newQualifiedNameRef("RTT.createFunction")); - - JsArrayLiteral arr = generateTypeArrayFromElements(methodElement.getParameters(), classElement, - typeArgContextExpr); - - JsExpression returnExpr = generateRTTLookupForType(methodElement, - methodElement.getReturnType(), classElement, typeArgContextExpr); - - callLookup.getArguments().add(arr.getExpressions().isEmpty() ? program.getNullLiteral() : arr); - callLookup.getArguments().add(returnExpr); - body.add(new JsReturn(callLookup)); - - // Finally, Add the lookup function to the global block. - JsExpression fnDecl; - if (overrideName == null) { - JsNameRef methodToCall = getRTTLookupMethodNameRef(methodElement); - if (methodElement.getEnclosingElement().getKind().equals(ElementKind.CLASS)) { - fnDecl = assign(null, methodToCall, lookupFn); - } else { - // Top level method - lookupFn.setName(scope.declareFreshName(methodToCall.getIdent())); - fnDecl = lookupFn; - } - } else { - // Special care for hoisted functions. - lookupFn.setName(scope.declareName(overrideName)); - fnDecl = lookupFn; - } - globalBlock.getStatements().add(fnDecl.makeStmt()); - } - - /* - * Create a direct lookup of types for the given element. Useful for in-line function types, as - * in the example: - * int foo( int bar(double x) ); - * No lookup method exists for the type "int bar(double x)", hence the in-line creation of: - * RTT.createFunction([RTT Parameter Types],RTT ReturnType)) - */ - private JsInvocation generateRTTCreate(Element element, - FunctionType elementType, - ClassElement classElement) { - boolean hasTypes = false; - - if (ElementKind.of(element).equals(ElementKind.CONSTRUCTOR) - || element.getModifiers().isNative()) { - // No type lookups for constructors or natives - return newInvocation(newQualifiedNameRef(RTT_DYNAMIC_LOOKUP)); - } - hasTypes = classElement != null ? hasTypeParameters(classElement) : false; - - JsProgram program = translationContext.getProgram(); - JsExpression typeArgContextExpr = hasTypes ? buildTypeArgsReference(classElement) : null; - JsInvocation callLookup; - callLookup = newInvocation(newQualifiedNameRef("RTT.createFunction")); - - JsArrayLiteral arr = generateTypeArrayFromTypes(elementType.getParameterTypes(), classElement, - typeArgContextExpr); - if (arr == null) { - return newInvocation(newQualifiedNameRef(RTT_DYNAMIC_LOOKUP)); - } - - JsExpression returnExpr = generateRTTLookupForType(element, elementType.getReturnType(), - classElement, typeArgContextExpr); - - callLookup.getArguments().add(arr.getExpressions().isEmpty() ? program.getNullLiteral() : arr); - callLookup.getArguments().add(returnExpr); - return callLookup; - } - - private JsArrayLiteral generateTypeArrayFromTypes(List parameterTypes, - ClassElement classElement, JsExpression typeArgContextExpr) { - JsArrayLiteral jsTypeArray = new JsArrayLiteral(); - for (Type param : parameterTypes) { - JsExpression elementExpr; - elementExpr = generateRTTLookupForType(param.getElement(), param, classElement, - typeArgContextExpr); - jsTypeArray.getExpressions().add(elementExpr); - } - return jsTypeArray; - } - - private JsArrayLiteral generateTypeArrayFromParameters(List params, - ClassElement classElement, JsExpression typeArgContextExpr) { - JsArrayLiteral jsTypeArray = new JsArrayLiteral(); - for (DartParameter param : params) { - Type paramType = param.getTypeNode() == null ? null : param.getTypeNode().getType(); - JsInvocation elementInvoke = generateRTTLookupForType(param.getSymbol(), paramType, classElement, - typeArgContextExpr); - jsTypeArray.getExpressions().add(elementInvoke); - } - return jsTypeArray; - } - - private JsArrayLiteral generateTypeArrayFromElements(List elements, - ClassElement classElement, JsExpression typeArgContextExpr) { - JsArrayLiteral jsTypeArray = new JsArrayLiteral(); - for (VariableElement element : elements) { - JsExpression rttTypeExpression = generateRTTLookupForType(element, element.getType(), - classElement, typeArgContextExpr); - jsTypeArray.getExpressions().add(rttTypeExpression); - } - return jsTypeArray; - } - - private JsInvocation generateRTTLookupForType(Element element, Type elementType, - ClassElement classElement, JsExpression typeArgContextExpr) { - return generateRTTLookupForType(element, elementType, classElement, typeArgContextExpr, - element.getModifiers().isNamed() ? element.getName() : null); - } - - private JsInvocation generateRTTLookupForType(Element element, Type elementType, - ClassElement classElement, JsExpression typeArgContextExpr, String named) { - JsInvocation elementInvoke = null; - switch (TypeKind.of(elementType)) { - case VARIABLE: - elementInvoke = buildTypeLookupExpression(elementType, classElement.getTypeParameters(), - typeArgContextExpr); - break; - case INTERFACE: - elementInvoke = generateRTTLookup((ClassElement) elementType.getElement(), - (InterfaceType) elementType, classElement); - break; - case FUNCTION: - elementInvoke = generateRTTCreate(element, (FunctionType) elementType, classElement); - break; - case FUNCTION_ALIAS: - elementInvoke = buildTypeLookupExpression(elementType, - classElement != null ? classElement.getTypeParameters() : null, typeArgContextExpr); - break; - case DYNAMIC: - case VOID: - case NONE: - elementInvoke = newInvocation(newQualifiedNameRef(RTT_DYNAMIC_LOOKUP)); - break; - default: - elementInvoke = buildTypeLookupExpression(elementType, classElement.getTypeParameters(), - typeArgContextExpr); - break; - } - if (named != null) { - if (elementInvoke.getArguments().size() == 0) { - elementInvoke.getArguments().add(translationContext.getProgram().getNullLiteral()); - } - elementInvoke.getArguments().add( - translationContext.getProgram().getStringLiteral(named)); - } - assert elementInvoke != null; - return elementInvoke; - } - - private JsName getJsName(Symbol symbol) { - return translationContext.getNames().getName(symbol); - } - - /* - * This function will create a lookup function that indirectly calls RTT.createFunction with - * and array of parameter types and the return type as arguments. Example: - * Dart: - * typedef List TestAliasType(int x, K k); - * JS: - * $$Dart.$lookupRTT = function(typeArgs){ - * return RTT.createFunction( - * [int$Dart.$lookupRTT(), RTT.getTypeArg(typeArgs, 0)], - * List$Dart.$lookupRTT([RTT.getTypeArg(typeArgs, 0)])); - * } - */ - private void generateRTTLookupMethod(DartFunctionTypeAlias x) { - FunctionAliasElementImplementation classElement = - (FunctionAliasElementImplementation) x.getSymbol(); - FunctionType funcType = classElement.getFunctionType(); - - // Build the function - JsFunction lookupFn = new JsFunction(globalScope); - lookupFn.setBody(new JsBlock()); - List body = lookupFn.getBody().getStatements(); - JsScope scope = new JsScope(globalScope, "temp"); - JsProgram program = translationContext.getProgram(); - JsInvocation invokeCreate = call(null, newQualifiedNameRef("RTT.createFunction")); - List callArgs = invokeCreate.getArguments(); - - JsName typeArgs = scope.declareName("typeArgs"); - JsExpression typeArgsExpr = new JsNameRef("typeArgs"); - lookupFn.getParameters().add(new JsParameter(typeArgs)); - - JsArrayLiteral arr = generateTypeArrayFromParameters(x.getParameters(), classElement, - typeArgsExpr); - callArgs.add(arr.getExpressions().isEmpty() ? program.getNullLiteral() : arr); - - JsExpression returnExpr = generateRTTLookupForType(funcType.getElement(), - funcType.getReturnType(), classElement, typeArgsExpr); - callArgs.add(returnExpr); - - JsName named = scope.declareName(RTT_NAMED_PARAMETER); - lookupFn.getParameters().add(new JsParameter(named)); - callArgs.add(named.makeRef()); - - body.add(new JsReturn(invokeCreate)); - - // Finally, Add the function to the global block of statements. - JsExpression fnDecl = assign(null, getRTTLookupMethodNameRef(classElement), lookupFn); - globalBlock.getStatements().add(fnDecl.makeStmt()); - } - - static JsExpression getRTTClassId(TranslationContext translationContext, - ClassElement classElement) { - JsName classJsName = translationContext.getNames().getName(classElement); - JsProgram program = translationContext.getProgram(); - JsStringLiteral clsid = program.getStringLiteral(classJsName.getShortIdent()); - return call(null, nameref(null, "$cls"), clsid); - } - - JsExpression getRTTClassId(ClassElement classElement) { - return getRTTClassId(translationContext, classElement); - } - - private JsNameRef getRTTLookupMethodNameRef(ClassElement classElement) { - return nameref(null, translationContext.getNames().getName(classElement), "$lookupRTT"); - } - - public JsNameRef getRTTLookupMethodNameRef(MethodElement methodElement) { - JsNameRef methodToCall; - - if (ElementKind.of(methodElement.getEnclosingElement()) == ElementKind.CLASS) { - JsNameRef classJsNameRef = getJsName(methodElement.getEnclosingElement()).makeRef(); - String mangledMethodName = mangler.mangleRttLookupMethod(methodElement, unitLibrary); - if (methodElement.getModifiers().isStatic()) { - methodToCall = AstUtil.newNameRef(classJsNameRef, mangledMethodName); - } else { - JsNameRef prototypeRef = AstUtil.newPrototypeNameRef(classJsNameRef); - methodToCall = AstUtil.newNameRef(prototypeRef, mangledMethodName); - } - } else { - // Top level method - methodToCall = AstUtil.newQualifiedNameRef(mangler.mangleRttLookupMethod(methodElement, - unitLibrary)); - } - return methodToCall; - } - - private JsNameRef getRTTImplementsMethodName(ClassElement classElement) { - return nameref(null, translationContext.getNames().getName(classElement), "$RTTimplements"); - } - - private JsNameRef getRTTAddToMethodName(ClassElement classElement) { - return nameref(null, translationContext.getNames().getName(classElement), "$addTo"); - } - - /** - * Build a class relative type arguments expression - * - * @param classElement The class whose type arguments to refer to. - */ - private JsExpression buildTypeArgsReference(ClassElement classElement) { - JsExpression typeArgs; - if (inFactory()) { - if (hasTypeParameters(classElement)) { - // There is no inheritence involved with generic factory methods, - // so we simply use a hard reference to the type info parameter to the - // factory. - typeArgs = nameref(null, "$typeArgs"); - } else { - typeArgs = new JsArrayLiteral(); - } - } else { - typeArgs = buildTypeArgsReferenceFromThis(classElement); - } - return typeArgs; - } - - private JsExpression buildTypeArgsReferenceFromThis(ClassElement classElement) { - // build: $getTypeArgsFor(this, 'class') - // Here build a reference to the type parameter for this class instance, this needs - // be looked up on a per-class basis. - return call(null, - newQualifiedNameRef( - "RTT.getTypeArgsFor"), new JsThisRef(), getRTTClassId(classElement)); - } - - /** - * @return a JsArrayLiteral listing the type arguments for the interface instance. - */ - private JsExpression buildTypeArgs( - InterfaceType instanceType, - List listTypeVars, - JsExpression contextTypeArgs) { - ClassElement classElement = instanceType.getElement(); - if (!hasTypeParameters(classElement)) { - return null; - } - - if (instanceType.hasDynamicTypeArgs()) { - JsProgram program = translationContext.getProgram(); - return program.getNullLiteral(); - } - - JsArrayLiteral arr = new JsArrayLiteral(); - assert instanceType.getArguments().size() > 0; - for (Type type : instanceType.getArguments()) { - JsExpression typeExpr = buildTypeLookupExpression( - type, listTypeVars, contextTypeArgs); - arr.getExpressions().add(typeExpr); - } - - return arr; - } - - /** - * @return a JsArrayLiteral listing the type arguments for the interface instance. - */ - private JsExpression buildTypeArgsForFactory( - FunctionType functionType, - InterfaceType instanceType, - List listTypeVars, - JsExpression contextTypeArgs) { - if (instanceType.getElement().getTypeParameters().size() == 0) { - return null; - } - - if (instanceType.hasDynamicTypeArgs()) { - return translationContext.getProgram().getNullLiteral(); - } - - JsArrayLiteral arr = new JsArrayLiteral(); - for (Type type : instanceType.getArguments()) { - JsExpression typeExpr = buildTypeLookupExpression( - type, listTypeVars, contextTypeArgs); - arr.getExpressions().add(typeExpr); - } - - return arr; - } - - /** - * @return an expression for looking up the RTT information for the given RAW type. - */ - private JsExpression generateRawRTTLookup(ClassElement classElement) { - JsInvocation invokeLookup = call(null, getRTTLookupMethodNameRef(classElement)); - return invokeLookup; - } - - private JsExpression generateRTTLookup( - InterfaceType instanceType, ClassElement contextClassElement) { - return generateRTTLookup(instanceType.getElement(), instanceType, contextClassElement); - } - - private JsInvocation generateRTTLookup( - ClassElement classElement, InterfaceType instanceType, ClassElement contextClassElement) { - JsInvocation invokeLookup = call(null, getRTTLookupMethodNameRef(classElement)); - if (hasTypeParameters(instanceType.getElement()) && !instanceType.hasDynamicTypeArgs()) { - JsExpression typeArgs = generateTypeArgsArray(instanceType, contextClassElement); - assert typeArgs != null; - invokeLookup.getArguments().add(typeArgs); - } - return invokeLookup; - } - - private JsExpression generateTypeArgsArray( - InterfaceType instanceType, ClassElement contextClassElement) { - JsExpression typeArgs; - if (inStaticNotFactory(contextClassElement)) { - if( ElementKind.of(contextClassElement) == ElementKind.FUNCTION_TYPE_ALIAS) { - // Special case for FunctionAlias as they can have generic types. - typeArgs = buildTypeArgs(instanceType, contextClassElement.getTypeParameters(), - new JsNameRef("typeArgs")); - } else { - typeArgs = buildTypeArgs(instanceType, null, null); - } - } else { - // Build type args in a class context: - // When building a type list in a class instance, type variables are - // resolved from the runtime type information on the instance of the object. - JsExpression typeArgContextExpr = buildTypeArgsReference(contextClassElement); - typeArgs = buildTypeArgs( - instanceType, - contextClassElement.getTypeParameters(), - typeArgContextExpr); - } - return typeArgs; - } - - private JsExpression generateTypeArgsArrayForFactory(FunctionType functionType, - InterfaceType instanceType, - ClassElement contextClassElement) { - JsExpression typeArgs; - if (inStaticNotFactory(contextClassElement)) { - typeArgs = buildTypeArgsForFactory(functionType, instanceType, null, null); - } else { - // Build type args in a class context: - // When building a type list in a class instance, type variables are - // resolved from the runtime type information on the instance of the - // object. - JsExpression typeArgContextExpr = buildTypeArgsReference(contextClassElement); - typeArgs = buildTypeArgsForFactory(functionType, instanceType, contextClassElement - .getTypeParameters(), typeArgContextExpr); - } - return typeArgs; - } - - /** - * @param classElement - * @return Whether the class has type parameters. - */ - private boolean hasTypeParameters(ClassElement classElement) { - return classElement.getTypeParameters().size() > 0; - } - - private boolean hasRTTImplements(ClassElement classElement) { - InterfaceType superType = classElement.getSupertype(); - return ((superType != null - && !superType.getElement().isObject()) - || !classElement.getInterfaces().isEmpty()); - } - - /** - * @return js The expression used to lookup the RTT for the given type. - */ - private JsInvocation buildTypeLookupExpression( - Type type, List list, JsExpression contextTypeArgs) { - switch (TypeKind.of(type)) { - case INTERFACE: - case FUNCTION_ALIAS: - InterfaceType interfaceType = (InterfaceType) type; - JsInvocation callLookup = call(null, - getRTTLookupMethodNameRef(interfaceType.getElement())); - if (hasTypeParameters(interfaceType.getElement()) && !interfaceType.hasDynamicTypeArgs()) { - JsArrayLiteral typeArgs = new JsArrayLiteral(); - for (Type arg : interfaceType.getArguments()) { - typeArgs.getExpressions().add(buildTypeLookupExpression(arg, list, contextTypeArgs)); - } - callLookup.getArguments().add(typeArgs); - } - return callLookup; - - case FUNCTION: - FunctionType functionType = (FunctionType) type; - JsInvocation functionTypeCallLookup = call(null, - getRTTLookupMethodNameRef(functionType.getElement())); - if (hasTypeParameters(functionType.getElement())) { - JsArrayLiteral typeArgs = new JsArrayLiteral(); - functionTypeCallLookup.getArguments().add(typeArgs); - } - return functionTypeCallLookup; - - case VARIABLE: - TypeVariable var = (TypeVariable)type; - JsProgram program = translationContext.getProgram(); - int varIndex = 0; - for (Type t : list) { - if (t.equals(type)) { - return call(null, newQualifiedNameRef("RTT.getTypeArg"), - Cloner.clone(contextTypeArgs), - program.getNumberLiteral(varIndex)); - } - varIndex++; - } - throw new AssertionError("unresolved type variable:" + var); - - default: - throw new AssertionError("unexpected type kind:" + type.getKind()); - } - } - - /** - * Add the appropriate code to a class's constructing factory, if necessary. - */ - void maybeAddClassRuntimeTypeToConstructor( - ClassElement classElement, JsFunction factory, JsExpression thisRef) { - // TODO(johnlenz):in optimized mode, only add this where it is needed. - JsScope factoryScope = factory.getScope(); - JsExpression typeInfo; - if (hasTypeParameters(classElement)) { - JsName typeinfoParameter = factoryScope.declareName("$rtt"); - factory.getParameters().add(0, new JsParameter(typeinfoParameter)); - typeInfo = typeinfoParameter.makeRef(); - } else { - // TODO(johnlenz): this is a constant value, it only needs to be evaluated once. - typeInfo = generateRawRTTLookup(classElement); - } - JsExpression setTypeInfo = assign(null, - nameref(null, Cloner.clone(thisRef), "$typeInfo"), typeInfo); - factory.getBody().getStatements().add(0, setTypeInfo.makeStmt()); - } - - /** - * Add a type arguments parameter to a factory method, if necessary. - */ - void maybeAddTypeParameterToFactory(DartMethodDefinition method, JsFunction factory) { - // TODO(johnlenz):in optimized mode, only add this where it is needed. - if (isParameterizedFactoryMethod(method)) { - JsScope scope = factory.getScope(); - JsName typeArgs = scope.declareName("$typeArgs"); - factory.getParameters().add(0, new JsParameter(typeArgs)); - } - } - - private boolean isParameterizedFactoryMethod(DartMethodDefinition method) { - assert method.getModifiers().isFactory(); - Element enclosingElement = method.getSymbol().getEnclosingElement(); - if (ElementKind.of(enclosingElement).equals(ElementKind.CLASS)) { - ClassElement enclosingClass = (ClassElement) enclosingElement; - return !enclosingClass.getTypeParameters().isEmpty(); - } - return false; - } - - /** - * Add a runtime type information to a array literal, if necessary. - */ - JsExpression maybeAddRuntimeTypeForArrayLiteral(ClassElement enclosingClass, - DartArrayLiteral x, JsArrayLiteral jsArray) { - // TODO(johnlenz):in optimized mode, only add this where it is needed. - InterfaceType instanceType = typeProvider.getArrayLiteralType( - x.getType().getArguments().get(0)); - JsExpression rtt = generateRTTLookup(instanceType, enclosingClass); - // Bind the runtime type information to the native array expression - return call(x, newQualifiedNameRef("RTT.setTypeInfo"), jsArray, rtt); - } - - /** - * Add a runtime type information to a map literal, if necessary. - */ - void maybeAddRuntimeTypeToMapLiteralConstructor(ClassElement enclosingClass, - DartMapLiteral x, JsInvocation invoke) { - // TODO(johnlenz):in optimized mode, only add this where it is needed. - - // Fixup the type for map literal type to be the implementing type. - List typeArgs = x.getType().getArguments(); - InterfaceType instanceType = typeProvider.getMapLiteralType( - typeArgs.get(0), typeArgs.get(1)); - JsExpression rtt = generateRTTLookup(instanceType, enclosingClass); - invoke.getArguments().add(rtt); - } - - /** - * Add runtime type information to a "new" expression, if necessary. - */ - void mayAddRuntimeTypeToConstrutorOrFactoryCall( - ClassElement enclosingClass, DartNewExpression x, JsInvocation invoke) { - // TODO(johnlenz):in optimized mode, only add this where it is needed. - - InterfaceType instanceType = Types.constructorType(x); - if (instanceType == null) { - // TODO(johnlenz): HackHack. Currently the "new FallThroughError" injected by the - // Normalizer does not have the instance type attached. But in this - // case we know it does not have any type parameters. - // reportError(x.getParent().getParent(), new AssertionError("missing type information")); - assert typeProvider.getFallThroughError().getElement().lookupConstructor("").equals( - x.getSymbol()); - } else if (constructorHasTypeParameters(x)) { - ConstructorElement constructor = x.getSymbol(); - ClassElement containingClassElement = enclosingClass; - if (constructor.getModifiers().isFactory()) { - // We are calling a factory, this is either in a class - FunctionType functionType = (FunctionType) constructor.getType(); - JsExpression typeArgs = generateTypeArgsArrayForFactory( - functionType, instanceType, containingClassElement); - assert typeArgs != null; - invoke.getArguments().add(0, typeArgs); - } else { - ClassElement constructorClassElement = constructor.getConstructorType(); - invoke.getArguments().add(0, - generateRTTLookup(constructorClassElement, instanceType, containingClassElement)); - } - } - } - - private boolean constructorHasTypeParameters(DartNewExpression x) { - ConstructorElement element = x.getSymbol(); - if (element.getModifiers().isFactory()) { - return isParameterizedFactoryMethod((DartMethodDefinition)element.getNode()); - } else { - InterfaceType instanceType = Types.constructorType(x); - return hasTypeParameters(instanceType.getElement()); - } - } - - /** - * @return an expression that implements a runtime "is" operation - */ - JsExpression generateInstanceOfComparison( - ClassElement enclosingClass, - JsExpression lhs, - DartTypeNode typeNode, - SourceInfo src) { - ClassElement currentClass = enclosingClass; - Type type = typeNode.getType(); - switch (TypeKind.of(type)) { - case INTERFACE: - InterfaceType interfaceType = (InterfaceType) type; - if (hasTypeParameters(interfaceType.getElement()) - && !interfaceType.hasDynamicTypeArgs()) { - return generateRefiedInterfaceTypeComparison(lhs, interfaceType, currentClass, src); - } else { - // TODO(johnlenz): special case "is Object"? - return generateRawInterfaceTypeComparison(lhs, typeNode, src); - } - case VARIABLE: - TypeVariable typeVar = (TypeVariable) type; - return generateRefiedTypeVariableComparison(lhs, typeVar, currentClass, src); - case DYNAMIC: - JsProgram program = translationContext.getProgram(); - return program.getTrueLiteral(); - case FUNCTION_ALIAS: - FunctionAliasType aliasType = (FunctionAliasType) type; - return generateRefiedInterfaceTypeComparison(lhs, aliasType, currentClass, src); - default: - throw new IllegalStateException("unexpected"); - } - } - - private JsExpression generateRefiedInterfaceTypeComparison( - JsExpression lhs, InterfaceType type, ClassElement contextClassElement, SourceInfo src) { - JsExpression rtt = generateRTTLookup(type, contextClassElement); - return call(src, nameref(src, rtt, "implementedBy"), lhs); - } - - private JsExpression getReifiedTypeVariableRTT(TypeVariable type, ClassElement contextClassElement) { - JsExpression rttContext; - // this.typeinfo.implementedTypes['class'].typeArgs; - // or for a factory method: - // $typeArgs - rttContext = buildTypeArgsReference(contextClassElement); - - // rtt = rttContext.typeArgs[x] - JsExpression rtt = buildTypeLookupExpression(type, contextClassElement.getTypeParameters(), rttContext); - return rtt; - } - - private JsExpression generateRefiedTypeVariableComparison( - JsExpression lhs, TypeVariable type, ClassElement contextClassElement, SourceInfo src) { - JsExpression rtt = getReifiedTypeVariableRTT(type, contextClassElement); - return call(src, nameref(src, rtt, "implementedBy"), lhs); - } - - private JsExpression generateRawInterfaceTypeComparison( - JsExpression lhs, DartTypeNode typeNode, - SourceInfo src) { - ClassElement element = (ClassElement) typeNode.getType().getElement(); - if (element.equals(typeProvider.getObjectType().getElement())) { - // Everything is an object, including null - return this.translationContext.getProgram().getTrueLiteral(); - } - String builtin = builtInTypeChecks.get(element); - if (builtin != null) { - return call(src, nameref(src, builtin), lhs); - } - - // Due to implementing implied interfaces of classes, we always have to - // use $implements$ rather than using JS instanceof for classes. - - // Inject: !!(tmp = target, tmp && tmp.$implements$type) - JsProgram program = translationContext.getProgram(); - JsName tmp = context.createTemporary(); - String mangledClass = translationContext.getMangler().mangleClassName(element); - return not(src, - not(src, - comma(src, - assign(src, tmp.makeRef(), lhs), - and(src, - neq(src, tmp.makeRef().setSourceRef(src), program.getNullLiteral()), - nameref(src, - tmp, - "$implements$" + mangledClass))))); - } - - private boolean inFactory() { - DartClassMember member = context.getCurrentClassMember(); - return member != null && member.getModifiers().isFactory(); - } - - private boolean inStaticNotFactory(ClassElement containingClass) { - return !inFactory() && inStatic(containingClass); - } - - private boolean inStatic(ClassElement containingClass) { - DartClassMember member = context.getCurrentClassMember(); - return containingClass == null - || containingClass.getKind() != ElementKind.CLASS - || member == null - || member.getModifiers().isStatic(); - } - - - /** - * Optionally emit a runtime type check, which is a call to $chk passing the - * runtime type object for the required type and an expression. - * - * @param enclosingClass enclosing class element - * @param expr expression to check - * @param type {@link Type} expected type to check against, null is unknown - * @param exprType {@link Type} statically determined type from analyzing expr - * @param src source info to use for the generated code - * @return an expression wrapping the type check call - */ - JsExpression addTypeCheck(ClassElement enclosingClass, JsExpression expr, Type type, - Type exprType, SourceInfo src) { - if (!emitTypeChecks || isStaticallyGoodAssignment(type, exprType)) { - return expr; - } - if (isStaticallyBadAssignment(type, exprType, expr)) { - return injectTypeError(enclosingClass, expr, type, src); - } - return injectTypeCheck(enclosingClass, expr, type, src); - } - - /** - * Check if an assignment is statically known to have a type error. - * - * @param type type of assignment target - * @param exprType type of value being assigned - * @param expr - * @return true if the assignment is known to be bad statically - */ - private boolean isStaticallyBadAssignment(Type type, Type exprType, JsExpression expr) { - if (!expr.isDefinitelyNotNull() || type == null || exprType == null - || type.getKind() == TypeKind.DYNAMIC || exprType.getKind() == TypeKind.DYNAMIC) { - // nulls can be assigned to any type, and if either is dynamic we can't - // reject it - return false; - } - return !types.isAssignable(type, exprType); - } - - /** - * @param type - * @param exprType - * @return true if the assignment is statically known to not need a check - */ - private boolean isStaticallyGoodAssignment(Type type, Type exprType) { - if (type == null || type.getKind() == TypeKind.DYNAMIC) { - // if there is no target type or it is dynamic, it is good - return true; - } - if (exprType == null || exprType.getKind() == TypeKind.DYNAMIC) { - // otherwise, if the source type is unknown or dynamic, we need a check - return false; - } - return types.isAssignable(type, exprType); - } - - /** - * Optionally emit a type error, used when it is statically known that a - * TypeError must be thrown. - * - * @param enclosingClass enclosing class element - * @param expr expression that fails the check - * @param type type to check against, null is unknown - * @param src source info to use for the generated code - * @return an expression wrapping the call to the throw helper - */ - private JsExpression injectTypeError(ClassElement enclosingClass, JsExpression expr, Type type, - SourceInfo src) { - JsExpression rtt = getRtt(enclosingClass, expr, type); - if (rtt != null) { - expr = call(src, nameref(src, "$te"), rtt, expr); - } - return expr; - } - - /** - * Optionally emit a runtime type check, which is a call to $chk passing the - * runtime type object for the required type and an expression. - * - * @param enclosingClass enclosing class element - * @param expr expression to check - * @param type type to check against, null is unknown - * @param src source info to use for the generated code - * @return an expression wrapping the type check call - */ - private JsExpression injectTypeCheck(ClassElement enclosingClass, JsExpression expr, Type type, - SourceInfo src) { - JsExpression rtt = getRtt(enclosingClass, expr, type); - if (rtt != null) { - expr = call(src, nameref(src, "$chk"), rtt, expr); - } - return expr; - } - - /** - * Get the runtime type object for a type. - * - * @param enclosingClass - * @param expr - * @param type - * @return a {@link JsExpression} for the runtime type, or null if no check is required/possible - */ - private JsExpression getRtt(ClassElement enclosingClass, JsExpression expr, Type type) { - if (!emitTypeChecks || type == null) { - return null; - } - JsExpression rtt; - switch (TypeKind.of(type)) { - case INTERFACE: - InterfaceType interfaceType = (InterfaceType) type; - // TODO: do we need a special case for raw interfaces? - return generateRTTLookup(interfaceType, enclosingClass); - case VARIABLE: - TypeVariable typeVar = (TypeVariable) type; - return getReifiedTypeVariableRTT(typeVar, enclosingClass); - case FUNCTION: - // TODO: We need a more detailed RTT than just a generic function. - return generateRTTLookup(typeProvider.getFunctionType(), enclosingClass); - case VOID: - case FUNCTION_ALIAS: - // TODO: implement, no checks for now - case DYNAMIC: - // no check required - return null; - default: - throw new IllegalStateException("unexpected type " + type); - } - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ScopeRootInfo.java b/compiler/java/com/google/dart/compiler/backend/js/ScopeRootInfo.java deleted file mode 100644 index e3681b92d54..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ScopeRootInfo.java +++ /dev/null @@ -1,533 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.dart.compiler.ast.DartBlock; -import com.google.dart.compiler.ast.DartCatchBlock; -import com.google.dart.compiler.ast.DartClass; -import com.google.dart.compiler.ast.DartClassMember; -import com.google.dart.compiler.ast.DartContext; -import com.google.dart.compiler.ast.DartExpression; -import com.google.dart.compiler.ast.DartField; -import com.google.dart.compiler.ast.DartForInStatement; -import com.google.dart.compiler.ast.DartForStatement; -import com.google.dart.compiler.ast.DartFunction; -import com.google.dart.compiler.ast.DartFunctionExpression; -import com.google.dart.compiler.ast.DartFunctionObjectInvocation; -import com.google.dart.compiler.ast.DartIdentifier; -import com.google.dart.compiler.ast.DartInitializer; -import com.google.dart.compiler.ast.DartMethodDefinition; -import com.google.dart.compiler.ast.DartNode; -import com.google.dart.compiler.ast.DartParameter; -import com.google.dart.compiler.ast.DartThisExpression; -import com.google.dart.compiler.ast.DartTypeParameter; -import com.google.dart.compiler.ast.DartUnit; -import com.google.dart.compiler.ast.DartVariable; -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsScope; -import com.google.dart.compiler.common.Symbol; -import com.google.dart.compiler.resolver.Element; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Deque; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Information relating to a methods scope, symbols, and closures - */ -class ScopeRootInfo { - /** - * Defines a relationship between a DartSymbol and a scope. - */ - static class DartScope { - /** - * A simple class for storing information about a symbol, specifically - * whether the symbol is referenced by a closure. - */ - static class DartSymbolInfo { - private final DartScope owningScope; - private boolean referencedFromClosure = false; - - public DartSymbolInfo(DartScope owningScope) { - this.owningScope = owningScope; - } - - public DartScope getOwningScope() { - return owningScope; - } - - public boolean isReferencedFromClosure() { - return referencedFromClosure; - } - - public void setReferencedFromClosure(boolean referencedFromClosure) { - this.referencedFromClosure = referencedFromClosure; - } - } - - private final DartScope parent; - private Map symbols = Maps.newLinkedHashMap(); - private Map jsAliasNames = Maps.newHashMap(); - // The scope's depth from the initial method definition scope. - private final int depth; - - public DartScope(DartScope parent) { - this.parent = parent; - this.depth = (parent != null) ? parent.getDepth() + 1 : 0; - } - - public void declare(Symbol symbol) { - symbols.put(symbol, new DartSymbolInfo(this)); - } - - public int getDepth() { - return depth; - } - - public DartScope getParent() { - return parent; - } - - public DartScope findSymbolScope(Symbol symbol) { - DartScope current = this; - while (current != null) { - DartScope.DartSymbolInfo info = current.getSymbolInfo(symbol); - if (info != null) { - return current; - } - current = current.getParent(); - } - return null; - } - - public DartScope.DartSymbolInfo getSymbolInfo(Symbol symbol) { - return this.symbols.get(symbol); - } - - public Map getSymbols() { - return symbols; - } - - public boolean definesClosureReferencedSymbols() { - for (DartScope.DartSymbolInfo symbol : symbols.values()) { - if (symbol.isReferencedFromClosure()) { - return true; - } - } - return false; - } - - private String getScopeAliasName() { - return "dartc_scp$" + depth; - } - - /** - * Returns the alias-object-JsName of this DartScope in the given JsScope. If none exists yet, - * creates a new one. - * - * @param jsScope - * @return the JsName representing the alias object for this DartScope. - */ - public JsName getAliasForJsScope(JsScope jsScope) { - JsName result = findAliasForJsScope(jsScope); - if (result == null) { - result = jsScope.declareFreshName(getScopeAliasName()); - jsAliasNames.put(jsScope, result); - } - return result; - } - - /** - * Returns the alias-object-JsName of this DartScope in the given JsScope. If none exists yet, - * null is returned. - * - * @param jsScope - * @return the JsName representing the alias object for this DartScope. - */ - public JsName findAliasForJsScope(JsScope jsScope) { - return jsAliasNames.get(jsScope); - } - } - - /** - * A simple class to keep track of the scope referenced by a closure, - * also whether the closure references "this". - */ - public static class ClosureInfo { - final Set referencedScopes = Sets.newHashSet(); - - boolean referencesThis = false; - - public List getSortedReferencedScopeList() { - ArrayList sortedScopes = Lists.newArrayList( - referencedScopes); - Collections.sort(sortedScopes, new Comparator(){ - @Override - public int compare(DartScope s1, DartScope s2) { - return s1.getDepth() - s2.getDepth(); - }}); - return sortedScopes; - } - } - - /** - * A generic helper class for visiting DartScope definitions. - */ - static private abstract class DartScopesVisitor extends NormalizedVisitor { - - // A place to store the constructor initializer list to the initializers - // can be visited within the scope of the constructor's parameters. - private List pendingConstructorInitList = null; - - @Override - public boolean visit(DartUnit x, DartContext ctx) { - return enterScope(x, ctx); - } - - @Override - public boolean visit(DartClass x, DartContext ctx) { - return enterScope(x, ctx); - } - - @Override - public boolean visit(DartMethodDefinition x, DartContext ctx) { - this.pendingConstructorInitList = x.getInitializers(); - accept(x.getFunction()); - return false; - } - - @Override - public void endVisit(DartMethodDefinition x, DartContext ctx) { - assert this.pendingConstructorInitList == null; - } - - @Override - public boolean visit(DartFunctionExpression x, DartContext ctx) { - // For function statements, the function's name belong in the outer scope. - // For function expressions, it is part of the function's own scope. - if (!x.isStatement()) { - return enterScope(x, ctx); - } - return true; - } - - @Override - public boolean visit(DartFunction x, DartContext ctx) { - boolean enter = enterScope(x, ctx); - if (enter) { - // Save and clear the cached init lists before processing - // any function as default parameters or in init list. - List inits = pendingConstructorInitList; - pendingConstructorInitList = null; - acceptList(x.getParams()); - if (inits != null) { - acceptList(inits); - } - if (x.getBody() != null) { - accept(x.getBody()); - } - } - return false; - } - - @Override - public boolean visit(DartBlock x, DartContext ctx) { - return enterScope(x, ctx); - } - - @Override - public boolean visit(DartCatchBlock x, DartContext ctx) { - return enterScope(x, ctx); - } - - @Override - public boolean visit(DartForInStatement x, DartContext ctx) { - return enterScope(x, ctx); - } - - @Override - public boolean visit(DartForStatement x, DartContext ctx) { - return enterScope(x, ctx); - } - - @Override - public void endVisit(DartUnit x, DartContext ctx) { - exitScope(x, ctx); - } - - @Override - public void endVisit(DartClass x, DartContext ctx) { - exitScope(x, ctx); - } - - @Override - public void endVisit(DartFunctionExpression x, DartContext ctx) { - if (!x.isStatement()) { - exitScope(x, ctx); - } - } - - @Override - public void endVisit(DartFunction x, DartContext ctx) { - exitScope(x, ctx); - } - - @Override - public void endVisit(DartBlock x, DartContext ctx) { - exitScope(x, ctx); - } - - @Override - public void endVisit(DartCatchBlock x, DartContext ctx) { - exitScope(x, ctx); - } - - @Override - public void endVisit(DartForStatement x, DartContext ctx) { - exitScope(x, ctx); - } - - abstract boolean enterScope(DartNode x, DartContext ctx); - abstract void exitScope(DartNode x, DartContext ctx); - } - - /** - * Build a set of ClosureInfo objects for the method, - * find and mark any variable referenced by a closure. - */ - private static class ClosureRefenceMapBuilder extends ScopeRootInfo.DartScopesVisitor { - private final Map scopes; - private Deque scopeStack = Lists.newLinkedList(); - private final Map closures = Maps.newHashMap(); - private Deque closureStack = Lists.newLinkedList(); - private final boolean respectInlinableModifier; - - ClosureRefenceMapBuilder(Map scopes, boolean respectInlinableModifier) { - this.scopes = scopes; - this.respectInlinableModifier = respectInlinableModifier; - } - - @Override - boolean enterScope(DartNode x, DartContext ctx) { - scopeStack.push(scopes.get(x)); - return true; - } - - @Override - void exitScope(DartNode x, DartContext ctx) { - scopeStack.pop(); - } - - @Override - public boolean visit(DartFunctionObjectInvocation x, DartContext ctx) { - DartExpression target = x.getTarget(); - if (target instanceof DartFunctionExpression) { - DartFunctionExpression functionExpression = (DartFunctionExpression) target; - if (respectInlinableModifier && - functionExpression.getSymbol().getModifiers().isInlinable()) { - acceptList(x.getArgs()); - return traverseFunction(functionExpression.getFunction(), ctx); - } - } - return super.visit(x, ctx); - } - - // Inlined from DartFunction#traverse(DartVisitor, DartContext). - private boolean traverseFunction(DartFunction function, DartContext ctx) { - for (DartParameter parameter : function.getParams()) { - doTraverse(parameter, ctx); - } - if (function.getBody() != null) { - doTraverse(function.getBody(), ctx); - } - // Ignore the return type. - return false; - } - - @Override - public boolean visit(DartFunction x, DartContext ctx) { - this.closures.put(x, new ClosureInfo()); - this.closureStack.push(x); - return super.visit(x, ctx); - } - - @Override - public void endVisit(DartFunction x, DartContext ctx) { - closureStack.pop(); - super.endVisit(x, ctx); - } - - @Override - public void endVisit(DartIdentifier x, DartContext ctx) { - processSymbol(x.getTargetSymbol()); - super.endVisit(x, ctx); - } - - @Override - public void endVisit(DartThisExpression x, DartContext ctx) { - for (DartFunction closure : closureStack) { - ScopeRootInfo.ClosureInfo info = closures.get(closure); - info.referencesThis = true; - } - } - - private void processSymbol(Symbol targetSymbol) { - if (targetSymbol != null) { - DartNode node = targetSymbol.getNode(); - if (node instanceof DartClassMember) { - // Special case: implicit instance/static member references. - DartClassMember member = (DartClassMember) node; - if (!member.getModifiers().isStatic()) { - // A member reference implies a reference to the current "this" - // object, the closure will need to pass it through. - for (DartFunction closure : closureStack) { - ScopeRootInfo.ClosureInfo info = closures.get(closure); - info.referencesThis = true; - } - } - } - - if (closureStack.size() > 0) { - DartScope currentScope = this.scopeStack.peek(); - DartScope symbolScope = currentScope.findSymbolScope(targetSymbol); - if (symbolScope != null) { - boolean referencedFromClosure = false; - for (DartFunction closure : closureStack) { - DartScope closureScope = scopes.get(closure); - // For each of the closures, determine if the value is defined - // outside outside the current closure, if so record its use. - if (symbolScope.getDepth() < closureScope.getDepth()) { - ScopeRootInfo.ClosureInfo info = closures.get(closure); - info.referencedScopes.add(symbolScope); - referencedFromClosure = true; - } - } - if (referencedFromClosure) { - symbolScope.getSymbolInfo(targetSymbol) - .setReferencedFromClosure(true); - } - } - } - } - } - } - - /** - * Build the DartScope objects for a method. - */ - static private class MethodScopeMapBuilder extends ScopeRootInfo.DartScopesVisitor { - private Map scopes = Maps.newLinkedHashMap(); - private Deque scopeStack = Lists.newLinkedList(); - - @Override - boolean enterScope(DartNode x, DartContext ctx) { - scopeStack.push(new DartScope(scopeStack.peek())); - scopes.put(x, scopeStack.peek()); - return true; - } - - @Override - void exitScope(DartNode x, DartContext ctx) { - scopeStack.pop(); - } - - // TODO(johnlenz): Handle catch exception declarations. - - @Override - public void endVisit(DartParameter x, DartContext ctx) { - DartScope currentScope = scopeStack.peek(); - currentScope.declare(x.getSymbol()); - super.endVisit(x, ctx); - } - - @Override - public void endVisit(DartVariable x, DartContext ctx) { - DartScope currentScope = scopeStack.peek(); - currentScope.declare(x.getSymbol()); - super.endVisit(x, ctx); - } - - @Override - public boolean visit(DartFunctionExpression x, DartContext ctx) { - DartScope currentScope = scopeStack.peek(); - boolean visit = super.visit(x, ctx); - if (!x.isStatement()) { - // Declare the symbol in the new scope - currentScope = scopeStack.peek(); - } - currentScope.declare(x.getSymbol()); - return visit; - } - } - - private final DartClassMember classMember; - private final Map symbols = Maps.newHashMap(); - private final Map closures; - private final Map scopes; - private int closureIds = 0; - - static ScopeRootInfo makeScopeInfo(DartMethodDefinition x, boolean respectInlinableModifier) { - return makeScopeInfoImpl(x, respectInlinableModifier); - } - - static ScopeRootInfo makeScopeInfo(DartField x, boolean respectInlinableModifier) { - return makeScopeInfoImpl(x, respectInlinableModifier); - } - - private static ScopeRootInfo makeScopeInfoImpl(DartClassMember x, - boolean respectInlinableModifier) { - ScopeRootInfo.MethodScopeMapBuilder scopeBuilder = new MethodScopeMapBuilder(); - scopeBuilder.accept(x); - ScopeRootInfo.ClosureRefenceMapBuilder closureBuilder = new ClosureRefenceMapBuilder( - scopeBuilder.scopes, respectInlinableModifier); - closureBuilder.accept(x); - return new ScopeRootInfo(x, scopeBuilder.scopes, closureBuilder.closures); - } - - ScopeRootInfo( - DartClassMember x, Map scopes, - Map closures) { - this.classMember = x; - this.closures = closures; - this.scopes = scopes; - for (DartScope scope : scopes.values()) { - this.symbols.putAll(scope.getSymbols()); - } - } - - Element getContainingElement() { - return classMember.getSymbol(); - } - - DartClassMember getContainingClassMember() { - return classMember; - } - - DartScope.DartSymbolInfo getSymbolInfo(Symbol targetSymbol) { - return symbols.get(targetSymbol); - } - - public ScopeRootInfo.ClosureInfo getClosureInfo(DartFunction x) { - return closures.get(x); - } - - public DartScope getScope(DartNode x) { - return scopes.get(x); - } - - /** - * @return A name for a closure unique within this method. - */ - public String getNextClosureName() { - return "c" + closureIds++; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/TranslationContext.java b/compiler/java/com/google/dart/compiler/backend/js/TranslationContext.java deleted file mode 100644 index 6240e61857f..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/TranslationContext.java +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.ast.DartFunction; -import com.google.dart.compiler.ast.DartNode; -import com.google.dart.compiler.ast.DartUnit; -import com.google.dart.compiler.backend.js.ast.JsFunction; -import com.google.dart.compiler.backend.js.ast.JsProgram; -import com.google.dart.compiler.backend.js.ast.JsScope; -import com.google.dart.compiler.resolver.Element; -import com.google.dart.compiler.resolver.LibraryElement; - -import java.util.HashMap; -import java.util.Map; - -/** - * Information generated by {@link GenerateNamesAndScopes} and consumed by - * {@link GenerateJavascriptAST}. - */ -public class TranslationContext { - private final DartMangler mangler; - private final Map memberScopes = new HashMap(); - private final Map methods = new HashMap(); - private final JsNameProvider names; - private final JsProgram program; - - private TranslationContext(JsProgram program, DartMangler mangler) { - this.program = program; - this.mangler = mangler; - this.names = new JsNameProvider(program, mangler); - } - - public DartMangler getMangler() { - return mangler; - } - - public Map getMemberScopes() { - return memberScopes; - } - - public Map getMethods() { - return methods; - } - - public JsNameProvider getNames() { - return names; - } - - public JsProgram getProgram() { - return program; - } - - /** - * - * @param unit Unit to create translation context for - * @param program - * @param mangler - * @param filterNode If not null, create names for this node only. - * @return - */ - public static TranslationContext createContext(DartUnit unit, JsProgram program, - DartMangler mangler, DartNode filterNode) { - TranslationContext translationContext = new TranslationContext(program, mangler); - LibraryElement unitLibrary = unit.getLibrary().getElement(); - GenerateNamesAndScopes visitor = new GenerateNamesAndScopes(translationContext, unitLibrary); - if (filterNode != null) { - visitor.accept(filterNode); - } else { - visitor.accept(unit); - } - return translationContext; - } - - -} \ No newline at end of file diff --git a/compiler/java/com/google/dart/compiler/backend/js/TraversalContextProvider.java b/compiler/java/com/google/dart/compiler/backend/js/TraversalContextProvider.java deleted file mode 100644 index dca7a06109a..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/TraversalContextProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2011, the Dart project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.ast.DartClassMember; -import com.google.dart.compiler.backend.js.ast.JsName; - -/** - * @author johnlenz@google.com (John Lenz) - */ -public interface TraversalContextProvider { - DartClassMember getCurrentClassMember(); - - JsName createTemporary(); -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/UncheckedJsParserException.java b/compiler/java/com/google/dart/compiler/backend/js/UncheckedJsParserException.java deleted file mode 100644 index c2db8120537..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/UncheckedJsParserException.java +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -/** - * An unchecked wrapper exception to interop with Rhino. - */ -class UncheckedJsParserException extends RuntimeException { - - private final JsParserException parserException; - - public UncheckedJsParserException(JsParserException parserException) { - this.parserException = parserException; - } - - public JsParserException getParserException() { - return parserException; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/analysis/DependencyComputer.java b/compiler/java/com/google/dart/compiler/backend/js/analysis/DependencyComputer.java deleted file mode 100644 index 3a35d219a6c..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/analysis/DependencyComputer.java +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.analysis; - -import org.mozilla.javascript.Token; -import org.mozilla.javascript.ast.AstNode; -import org.mozilla.javascript.ast.FunctionNode; -import org.mozilla.javascript.ast.Name; -import org.mozilla.javascript.ast.NewExpression; -import org.mozilla.javascript.ast.NodeVisitor; -import org.mozilla.javascript.ast.PropertyGet; -import org.mozilla.javascript.ast.Scope; -import org.mozilla.javascript.ast.Symbol; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Computes the set of dependencies that a given AstNode node has. - */ -class DependencyComputer { - /** - * Visitor for determining what dependencies an AstNode has. - */ - class DependencyComputingVisitor implements NodeVisitor { - /** - * Adds a dependency on the given identifier. If the identifier is virtual then then a - * dependency is only added if the enclosing "class" has been instantiated. - */ - private void addDependency(String identifier, boolean isVirtual) { - List members = namesToElements.get(identifier); - if (members != null) { - for (JavascriptElement member : members) { - if (isVirtual && member.isVirtual()) { - JavascriptElement enclosingElement = member.getEnclosingElement(); - if (enclosingElement != null && enclosingElement.isInstantiated()) { - dependencies.add(member); - } - } else { - if (!member.isVirtual()) { - if (member.getEnclosingElement() != null) { - dependencies.add(member.getEnclosingElement()); - } - } - dependencies.add(member); - } - } - } - } - - /** - * Record that we saw a new of a given identifier. - */ - private void addInstantiation(String identifier) { - List instantiatedClasses = namesToElements.get(identifier); - if (instantiatedClasses != null) { - for (JavascriptElement instantiatedClass : instantiatedClasses) { - instantiatedClass.setInstantiated(true); - - /* - * Whenever we see an instantiation we must check it and any super type for members that - * match the virtual names seen to date and we must ensure that the corresponding inherits - * get emitted. - */ - while (instantiatedClass != null) { - JavascriptElement inheritsInvocation = instantiatedClass.getInheritsInvocation(); - if (inheritsInvocation != null) { - dependencies.add(inheritsInvocation); - } - - for (JavascriptElement member : instantiatedClass.getMembers()) { - if (virtualNames.contains(member.getName())) { - dependencies.add(member); - } - } - - instantiatedClass = instantiatedClass.getInheritsElement(); - } - } - } - } - - private void addStaticDependency(String identifier) { - addDependency(identifier, false); - } - - private void addVirtualDependency(String identifier) { - virtualNames.add(identifier); - addDependency(identifier, true); - } - - Symbol findSymbol(Scope scope, String name) { - if (scope == null) { - return null; - } - - Symbol symbol = scope.getSymbol(name); - if (symbol == null) { - Scope parentScope = scope.getParentScope(); - if (parentScope == null && (scope != scope.getAstRoot())) { - return findSymbol(scope.getAstRoot(), name); - } else { - return findSymbol(parentScope, name); - } - } - - return symbol; - } - - /** - * Returns true if the name is a local or parameter name. However, if the name is on the - * right hand side of a property get then we don't consider this name to be a local variable. - */ - boolean isLocalVariableOrParameter(Name name) { - Scope definingScope = name.getDefiningScope(); - Scope enclosingScope = name.getEnclosingScope(); - if (definingScope != null) { - Symbol symbol = definingScope.getSymbol(name.getIdentifier()); - if (definingScope.getType() == Token.FUNCTION) { - if (symbol != null && (symbol.getDeclType() == Token.VAR) - || (symbol.getDeclType() == Token.LP)) { - - if (name.getParent().getType() == Token.GETPROP) { - PropertyGet propertyGet = (PropertyGet) name.getParent(); - return propertyGet.getRight() != name; - } - - return true; - } - } - } - - return false; - } - - /** - * Returns true if the name is associated with a native - * function or a top level function. - */ - private boolean isNativeOrTopLevelFunction(Scope enclosingScope, String name) { - List list = namesToElements.get(name); - if (list == null || list.isEmpty()) { - return false; - } - - Symbol symbol = findSymbol(enclosingScope, name); - if (symbol != null - && (symbol.getDeclType() == Token.FUNCTION || symbol.getDeclType() == Token.VAR)) { - return true; - } - - JavascriptElement javascriptElement = list.get(0); - return javascriptElement.isNative(); - } - - /** - * Return a static name if the {@link PropertyGet} matches the pattern x.y or - * x.prototype.y or null if it does not. - */ - String maybeGetStaticName(PropertyGet propertyGet) { - AstNode right = propertyGet.getRight(); - int rightType = right.getType(); - if (rightType != Token.NAME) { - return null; - } - - AstNode left = propertyGet.getLeft(); - int leftType = left.getType(); - if (leftType == Token.NAME) { - String qualifier = ((Name) left).getIdentifier(); - - if (isNativeOrTopLevelFunction(left.getEnclosingScope(), qualifier)) { - String targetName = ((Name) right).getIdentifier(); - String qualifiedName = qualifier + "." + targetName; - if ("prototype".equals(targetName)) { - return qualifiedName; - } else if (namesToElements.containsKey(qualifiedName)) { - return qualifiedName; - } - } - } else if (leftType == Token.GETPROP) { - PropertyGet leftPropGet = (PropertyGet) left; - String handleSpecialCase = maybeGetStaticName(leftPropGet); - if (handleSpecialCase != null && handleSpecialCase.endsWith("prototype")) { - handleSpecialCase = handleSpecialCase + "." + ((Name) right).getIdentifier(); - if (namesToElements.containsKey(handleSpecialCase)) { - return handleSpecialCase; - } - } - } - - return null; - } - - @Override - public boolean visit(AstNode node) { - switch (node.getType()) { - case Token.GETPROP: - PropertyGet propertyGet = (PropertyGet) node; - String staticName = maybeGetStaticName(propertyGet); - if (staticName != null) { - addStaticDependency(staticName); - return false; - } - break; - - case Token.FUNCTION: - FunctionNode functionNode = (FunctionNode) node; - functionNode.getBody().visit(this); - // Don't process the parameters - return false; - - case Token.NAME: - Name name = (Name) node; - if (!isLocalVariableOrParameter(name)) { - String identifier = name.getIdentifier(); - addVirtualDependency(identifier); - } - break; - - case Token.NEW: - NewExpression newExpression = (NewExpression) node; - Name target = (Name) newExpression.getTarget(); - if (target != null) { - addInstantiation(target.getIdentifier()); - } - break; - - default: - break; - } - - return true; - } - - } - - private final List dependencies = new ArrayList(); - private final Map> namesToElements; - - /** - * Names that have been referenced using virtual syntax, i.e. not using A.prototype.foo, but - * as foo or this.foo, etc. - */ - private final Set virtualNames = new HashSet(); - - public DependencyComputer(Map> namesToElements) { - this.namesToElements = namesToElements; - } - - public List computeDependencies(AstNode node) { - // Clear the dependencies so this object can be reused. - dependencies.clear(); - node.visit(new DependencyComputingVisitor()); - return dependencies; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/analysis/JavascriptElement.java b/compiler/java/com/google/dart/compiler/backend/js/analysis/JavascriptElement.java deleted file mode 100644 index 0604773cb4e..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/analysis/JavascriptElement.java +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.analysis; - -import org.mozilla.javascript.ast.AstNode; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -/** - * JavaScript element that could be any subtype of {@link AstNode}. In the cases where the element - * is a function any members that are hung off of its prototype chain are also recorded as members. - */ -class JavascriptElement { - private final JavascriptElement enclosingElement; - private JavascriptElement inheritsElement; - private JavascriptElement inheritsInvocation; - private boolean instantiated; - private final boolean isVirtual; - private List members = null; - private final String name; - private final AstNode node; - private final String qualifiedName; - - public JavascriptElement(JavascriptElement enclosingElement, boolean isVirtual, - String qualifiedName, String name, AstNode node) { - this.enclosingElement = enclosingElement; - this.isVirtual = isVirtual; - this.qualifiedName = qualifiedName; - this.name = name; - this.node = node; - if (enclosingElement != null) { - enclosingElement.addMember(this); - } - } - - /** - * @param javascriptElement - */ - private void addMember(JavascriptElement javascriptElement) { - if (members == null) { - members = new LinkedList(); - } - members.add(javascriptElement); - } - - public JavascriptElement getEnclosingElement() { - return enclosingElement; - } - - public JavascriptElement getInheritsElement() { - return inheritsElement; - } - - public JavascriptElement getInheritsInvocation() { - return inheritsInvocation; - } - - /** - * Returns the length of this element in characters. - */ - public int getLength() { - return node.getLength(); - } - - public List getMembers() { - if (members == null) { - return Collections.emptyList(); - } - - return members; - } - - public String getName() { - return name; - } - - public AstNode getNode() { - return node; - } - - public int getOffset() { - return node.getAbsolutePosition(); - } - - public String getQualifiedName() { - return qualifiedName; - } - - /** - * Returns true if the element was used in a new expression. For now, we assume that - * any javascript native element is instantiated. - */ - public boolean isInstantiated() { - // TODO: Assume that natives are always instantiated for now - return instantiated || isNative(); - } - - /** - * Returns true if the element was referenced from a top-level expression but was - * not declared. For example, we would synthesize a native member if the following top-level - * expression is found "Array.prototype.XXX = function(){}". Array is a native JS object. - */ - public boolean isNative() { - return getNode() == null; - } - - public boolean isVirtual() { - return isVirtual; - } - - public void setInherits(JavascriptElement inherits) { - this.inheritsElement = inherits; - } - - public void setInheritsNode(AstNode inheritsNode) { - this.inheritsInvocation = new JavascriptElement(null,false, "", "", inheritsNode); - } - - public void setInstantiated(boolean instantiated) { - this.instantiated = instantiated; - - if (inheritsElement != null) { - inheritsElement.setInstantiated(instantiated); - } - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/analysis/TopLevelElementIndexer.java b/compiler/java/com/google/dart/compiler/backend/js/analysis/TopLevelElementIndexer.java deleted file mode 100644 index 13a2c14242d..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/analysis/TopLevelElementIndexer.java +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.analysis; - -import org.mozilla.javascript.Token; -import org.mozilla.javascript.ast.Assignment; -import org.mozilla.javascript.ast.AstNode; -import org.mozilla.javascript.ast.ExpressionStatement; -import org.mozilla.javascript.ast.FunctionCall; -import org.mozilla.javascript.ast.FunctionNode; -import org.mozilla.javascript.ast.Name; -import org.mozilla.javascript.ast.NodeVisitor; -import org.mozilla.javascript.ast.VariableDeclaration; -import org.mozilla.javascript.ast.VariableInitializer; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Deque; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -/** - * Indexes the top level declarations and expressions contained in a JavaScript AST tree. Where top - * level expressions can be global variables, method definitions or invocations. Note that method - * bodies are not processed. - */ -class TopLevelElementIndexer implements NodeVisitor { - /** - * - */ - private static final String RUN_ENTRY_METHOD_NAME = "RunEntry"; - - /** - * Collects {@link Name} {@link AstNode}s. - */ - static class NameLocator implements NodeVisitor { - private static final int PROTOTYPE_DEFAULT_INDEX = -1; - private final Deque identifiers = new LinkedList(); - private int prototypeIndex = PROTOTYPE_DEFAULT_INDEX; - - public String getEnclosingTypeName() { - return identifiers.getFirst(); - } - - public String getName() { - return identifiers.getLast(); - } - - public Collection getPossibleNames() { - List names = new ArrayList(2); - if (hasPrototypeInName()) { - names.add(identifiers.getLast()); - } - names.add(getQualifiedName()); - return names; - } - - public String getQualifiedName() { - StringBuffer sb = new StringBuffer(); - Iterator iterator = identifiers.iterator(); - while (iterator.hasNext()) { - sb.append(iterator.next()); - if (iterator.hasNext()) { - sb.append("."); - } - } - return sb.toString(); - } - - public boolean hasPrototypeInName() { - return prototypeIndex != PROTOTYPE_DEFAULT_INDEX; - } - - @Override - public boolean visit(AstNode node) { - if (node.getType() == Token.NAME) { - Name name = (Name) node; - String identifier = name.getIdentifier(); - if ("prototype".equals(identifier)) { - prototypeIndex = identifiers.size(); - } - identifiers.add(identifier); - } - return true; - } - } - - public static void printGlobals(List globals) { - System.out.println("Globals"); - for (AstNode global : globals) { - System.out.println("--------"); - System.out.println(global.toSource()); - System.out.println(); - } - } - - public static void printNamesToElements(Map> namesToElements) { - long rttCost = 0; - long namedCost = 0; - long ctorCost = 0; - - Set>> entrySet = namesToElements.entrySet(); - for (Entry> entry : entrySet) { - System.out.println("--------"); - System.out.println("Name: " + entry.getKey()); - for (JavascriptElement javascriptElement : entry.getValue()) { - AstNode node = javascriptElement.getNode(); - if (node == null) { - continue; - } - - System.out.println("Type: " + Token.typeToName(node.getType())); - if (javascriptElement.getInheritsElement() != null) { - System.out.println("Inherits: " + javascriptElement.getInheritsElement()); - } - - try { - System.out.println(node.toSource()); - } catch (Exception e) { - System.out.println("Failed to print node source code"); - } - - String name = javascriptElement.getName(); - if (name.endsWith("$named")) { - namedCost += node.getLength(); - } else if (name.endsWith("$addTo") || name.endsWith("$lookupRTT") - || name.endsWith("$RTTimplements")) { - rttCost += node.getLength(); - } else if (name.endsWith("$Constructor") || name.endsWith("$Initializer")) { - ctorCost += node.getLength(); - } - } - System.out.println(); - } - - System.out.println(ctorCost + - " characters worth of $Constructor and $Initializer methode declarations"); - System.out.println(namedCost + " characters worth of $named methods declarations"); - System.out.println(rttCost + " characters worth of RTT method declarations"); - } - - private final List entryPoints = new ArrayList(); - private final List globals; - - private final Map> namesToElements; - - public TopLevelElementIndexer(Map> namesToElements, - List globals) { - this.globals = globals; - this.namesToElements = namesToElements; - } - - private void addElement(String identifier, JavascriptElement javascriptElement) { - List list = namesToElements.get(identifier); - if (list == null) { - list = new ArrayList(1); - namesToElements.put(identifier, list); - } - list.add(javascriptElement); - } - - /** - * Processes an AST node that does not define a method. If the node is an invocation to a - * RunEntry method or an inherits method update the entry points and element inheritance - * hierarchy accordingly. Otherwise we just add this node to the globals block and continue. - */ - private void processGlobal(AstNode node) { - if (node.getType() == Token.EXPR_RESULT) { - ExpressionStatement expressionStatement = (ExpressionStatement) node; - AstNode expression = expressionStatement.getExpression(); - if (expression.getType() == Token.CALL) { - FunctionCall functionCall = (FunctionCall) expression; - AstNode target = functionCall.getTarget(); - if (target.getType() == Token.NAME) { - Name targetName = (Name) target; - if (RUN_ENTRY_METHOD_NAME.equals(targetName.getIdentifier())) { - // This is a call to an entry point so add it to the known set of entry points. - entryPoints.add(node); - return; - } else if ("$inherits".equals(targetName.getIdentifier())) { - // This is an inherits call so update the element's inheritance hierarchy. - List arguments = functionCall.getArguments(); - assert (arguments.size() == 2); - assert (arguments.get(0).getType() == Token.NAME); - assert (arguments.get(1).getType() == Token.NAME); - Name subtype = (Name) arguments.get(0); - Name supertype = (Name) arguments.get(1); - List subTypeFunctions = namesToElements.get(subtype.getIdentifier()); - assert (subTypeFunctions != null && subTypeFunctions.size() == 1); - JavascriptElement subtypeFunction = subTypeFunctions.get(0); - subtypeFunction.setInheritsNode(node); - subtypeFunction.setInherits(namesToElements.get(supertype.getIdentifier()).get(0)); - return; - } - } - } - } - - globals.add(node); - } - - public List getEntryPoints() { - return entryPoints; - } - - @Override - public boolean visit(AstNode node) { - if (node == node.getAstRoot()) { - return true; - } - - switch (node.getType()) { - case Token.EXPR_VOID: - case Token.EXPR_RESULT: - ExpressionStatement expressionStatement = (ExpressionStatement) node; - AstNode expression = expressionStatement.getExpression(); - if (expression.getType() == Token.ASSIGN) { - Assignment assignment = (Assignment) expression; - NameLocator nameLocator = new NameLocator(); - assignment.getLeft().visit(nameLocator); - String enclosingTypeName = nameLocator.getEnclosingTypeName(); - JavascriptElement enclosingElement = null; - if (enclosingTypeName != null) { - List list = namesToElements.get(enclosingTypeName); - if (list == null) { - // TODO: Assume that this is a native object for now, we could have a whitelist of - // native objects if we wanted to. - enclosingElement = - new JavascriptElement(null, false, enclosingTypeName, nameLocator.getName(), - null); - addElement(enclosingTypeName, enclosingElement); - } else { - assert (list != null && list.size() == 1); - enclosingElement = list.get(0); - } - } - - JavascriptElement javascriptElement = - new JavascriptElement(enclosingElement, nameLocator.hasPrototypeInName(), - nameLocator.getQualifiedName(), nameLocator.getName(), node); - for (String identifier : nameLocator.getPossibleNames()) { - addElement(identifier, javascriptElement); - } - } else { - processGlobal(node); - } - break; - - case Token.FUNCTION: - FunctionNode functionNode = (FunctionNode) node; - String name = functionNode.getName(); - if (name != null && !name.isEmpty()) { - addElement(name, new JavascriptElement(null, false, name, name, node)); - } - break; - - case Token.VAR: - VariableDeclaration variableDeclaration = (VariableDeclaration) node; - List variables = variableDeclaration.getVariables(); - for (VariableInitializer variable : variables) { - AstNode target = variable.getTarget(); - if (target.getType() == Token.NAME) { - Name variableName = (Name) target; - addElement(variableName.getIdentifier(), new JavascriptElement(null, false, - variableName.getIdentifier(), variableName.getIdentifier(), node)); - } - } - break; - - default: - processGlobal(node); - break; - } - - return false; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/analysis/TreeShaker.java b/compiler/java/com/google/dart/compiler/backend/js/analysis/TreeShaker.java deleted file mode 100644 index 27a975224cb..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/analysis/TreeShaker.java +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.analysis; - -import com.google.common.io.CharStreams; -import com.google.common.io.Closeables; -import com.google.dart.compiler.DartCompilerContext; -import com.google.dart.compiler.LibrarySource; - -import org.mozilla.javascript.EvaluatorException; -import org.mozilla.javascript.Parser; -import org.mozilla.javascript.ast.AstNode; -import org.mozilla.javascript.ast.AstRoot; -import org.mozilla.javascript.ast.NodeVisitor; - -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * A JavaScript tree shaker that is specialized for the output produced by - * dartc. - */ -public class TreeShaker { - private static class VisitorIOException extends RuntimeException { - public VisitorIOException(IOException e) { - super(e); - } - - @Override - public IOException getCause() { - return (IOException) super.getCause(); - } - } - - private static final class OutputFileWriter implements NodeVisitor { - private final Set nodesToEmit; - private final Writer outputFile; - private final Reader inputFile; - private long lastReadPosition = 0; - private long outputSize = 0; - - private OutputFileWriter(Set nodesToEmit, Writer outputFile, Reader inputFile) { - this.nodesToEmit = nodesToEmit; - this.outputFile = outputFile; - this.inputFile = inputFile; - } - - @Override - public boolean visit(AstNode node) { - if (node.getAstRoot() == node) { - return true; - } - - try { - if (nodesToEmit.contains(node)) { - int nodePosition = node.getAbsolutePosition(); - inputFile.skip(nodePosition - lastReadPosition); - - char[] buffer = new char[node.getLength()]; - int charsRead = inputFile.read(buffer); - assert (charsRead == buffer.length); - outputFile.write(buffer); - outputFile.write("\n"); - outputSize += charsRead + 1; - lastReadPosition = nodePosition + node.getLength(); - } - } catch (IOException e) { - throw new VisitorIOException(e); - } - - return false; - } - - public long getOutputSize() { - return outputSize; - } - } - - private static final boolean DEBUG = false; - - /** - * Returns the set of {@link AstNode}s that should be emitted into the final - * JS code. - */ - private static Set computeNodesToEmit(AstRoot root) { - List globals = new ArrayList(); - Map> namesToElements = - new HashMap>(); - TopLevelElementIndexer declVisitor = new TopLevelElementIndexer(namesToElements, globals); - root.visit(declVisitor); - - if (DEBUG) { - TopLevelElementIndexer.printNamesToElements(namesToElements); - TopLevelElementIndexer.printGlobals(globals); - } - - List worklist = new ArrayList(); - for (AstNode global : globals) { - worklist.add(global); - } - - worklist.addAll(declVisitor.getEntryPoints()); - DependencyComputer dependencyComputer = new DependencyComputer(namesToElements); - final Set nodesProcessed = new LinkedHashSet(); - while (!worklist.isEmpty()) { - AstNode node = worklist.remove(worklist.size() - 1); - if (!nodesProcessed.add(node)) { - continue; - } - - if (DEBUG) { - try { - System.out.println(node.toSource()); - System.out.println("Dependencies:"); - } catch (Exception e) { - // Ignore exceptions thrown by rhino's toSource method... - } - } - - List dependencies = dependencyComputer.computeDependencies(node); - for (JavascriptElement dependency : dependencies) { - if (dependency.isNative() || nodesProcessed.contains(dependency.getNode())) { - // Skip natives since they don't have a node in the AST - continue; - } - - if (DEBUG) { - System.out.println("\t" + dependency.getQualifiedName()); - } - - worklist.add(dependency.getNode()); - } - } - return nodesProcessed; - } - - /** - * Reduce the input JS file by following the conservative "call graph" and - * pruning dead code. - */ - public static long reduce(LibrarySource app, DartCompilerContext context, - String completeArtifactName, Writer outputFile) throws IOException { - Reader inputFile = context.getArtifactReader(app, "", completeArtifactName); - // Mark beyond the expected length so we can reset back to zero - AstRoot root = null; - boolean failed = true; - try { - Parser parser = new Parser(); - root = parser.parse(inputFile, "", 1); - failed = false; - } catch (EvaluatorException e) { - /* - * This can happen if we generate bad JS code. For example, the negative - * tests may cause invalid control flow constructs to be generated. In - * this case we will swallow the exception and simply copy the input file - * to the output file. - */ - Closeables.close(inputFile, failed); - inputFile = context.getArtifactReader(app, "", completeArtifactName); - return CharStreams.copy(inputFile, outputFile); - } finally { - Closeables.close(inputFile, failed); - } - - final Set nodesProcessed = computeNodesToEmit(root); - - // Need to get a new reader since we don't cache the stream - failed = true; - inputFile = context.getArtifactReader(app, "", completeArtifactName); - OutputFileWriter outputFileWriter = - new OutputFileWriter(nodesProcessed, outputFile, inputFile); - try { - root.visit(outputFileWriter); - failed = false; - return outputFileWriter.getOutputSize(); - } catch (VisitorIOException e) { - throw e.getCause(); - } finally { - Closeables.close(inputFile, failed); - } - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/CanBooleanEval.java b/compiler/java/com/google/dart/compiler/backend/js/ast/CanBooleanEval.java deleted file mode 100644 index 8f4364d94f2..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/CanBooleanEval.java +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * An interface that describes the boolean evaluation of an expression. - */ -public interface CanBooleanEval { - - boolean isBooleanFalse(); - - boolean isBooleanTrue(); -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/HasArguments.java b/compiler/java/com/google/dart/compiler/backend/js/ast/HasArguments.java deleted file mode 100644 index 2b880f7c86c..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/HasArguments.java +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import java.util.List; - -/** - * Implemented by JavaScript objects that accept arguments. - */ -public interface HasArguments { - - List getArguments(); -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/HasCondition.java b/compiler/java/com/google/dart/compiler/backend/js/ast/HasCondition.java deleted file mode 100644 index 082f4e15eb3..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/HasCondition.java +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Implemented by JavaScript objects with conditional execution. - */ -public interface HasCondition { - - JsExpression getCondition(); - - void setCondition(JsExpression condition); -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/HasName.java b/compiler/java/com/google/dart/compiler/backend/js/ast/HasName.java deleted file mode 100644 index bdd87970929..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/HasName.java +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.common.HasSymbol; - -/** - * Implemented by JavaScript objects that have a name. - */ -public interface HasName extends HasSymbol { - JsName getName(); -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsArrayAccess.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsArrayAccess.java deleted file mode 100644 index 46df5108086..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsArrayAccess.java +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents a javascript expression for array access. - */ -public final class JsArrayAccess extends JsExpression { - - private JsExpression arrayExpr; - private JsExpression indexExpr; - - public JsArrayAccess() { - super(); - } - - public JsArrayAccess(JsExpression arrayExpr, JsExpression indexExpr) { - this.arrayExpr = arrayExpr; - this.indexExpr = indexExpr; - } - - public JsExpression getArrayExpr() { - return arrayExpr; - } - - public JsExpression getIndexExpr() { - return indexExpr; - } - - @Override - public boolean hasSideEffects() { - return arrayExpr.hasSideEffects() || indexExpr.hasSideEffects(); - } - - @Override - public boolean isDefinitelyNotNull() { - return false; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - public void setArrayExpr(JsExpression arrayExpr) { - this.arrayExpr = arrayExpr; - } - - public void setIndexExpr(JsExpression indexExpr) { - this.indexExpr = indexExpr; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - arrayExpr = v.accept(arrayExpr); - indexExpr = v.accept(indexExpr); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.ARRAY_ACCESS; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsArrayLiteral.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsArrayLiteral.java deleted file mode 100644 index 8cb9f7e6d52..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsArrayLiteral.java +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import java.util.ArrayList; -import java.util.List; - -/** - * Represents a JavaScript expression for array literals. - */ -public final class JsArrayLiteral extends JsLiteral { - - private final List exprs = new ArrayList(); - - public JsArrayLiteral() { - super(); - } - - public List getExpressions() { - return exprs; - } - - @Override - public boolean hasSideEffects() { - for (JsExpression expr : exprs) { - if (expr.hasSideEffects()) { - return true; - } - } - return false; - } - - @Override - public boolean isBooleanFalse() { - return false; - } - - @Override - public boolean isBooleanTrue() { - return true; - } - - @Override - public boolean isDefinitelyNotNull() { - return true; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - v.acceptWithInsertRemove(exprs); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.ARRAY; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsBinaryOperation.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsBinaryOperation.java deleted file mode 100644 index b09d50c1d05..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsBinaryOperation.java +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents a JavaScript binary operation. - */ -public final class JsBinaryOperation extends JsExpression { - - private JsExpression arg1; - private JsExpression arg2; - private final JsBinaryOperator op; - - public JsBinaryOperation(JsBinaryOperator op) { - this(op, null, null); - } - - public JsBinaryOperation(JsBinaryOperator op, JsExpression arg1, JsExpression arg2) { - this.op = op; - this.arg1 = arg1; - this.arg2 = arg2; - } - - public JsExpression getArg1() { - return arg1; - } - - public JsExpression getArg2() { - return arg2; - } - - public JsBinaryOperator getOperator() { - return op; - } - - @Override - public boolean hasSideEffects() { - return op.isAssignment() || arg1.hasSideEffects() || arg2.hasSideEffects(); - } - - @Override - public boolean isDefinitelyNotNull() { - // Precarious coding, but none of these can have null results. - if (op.getPrecedence() > 5) { - return true; - } - if (op == JsBinaryOperator.OR) { - if (arg1 instanceof CanBooleanEval) { - if (((CanBooleanEval) arg1).isBooleanTrue()) { - assert arg1.isDefinitelyNotNull(); - return true; - } - } - } - // AND and OR can return nulls - if (op.isAssignment()) { - if (op == JsBinaryOperator.ASG) { - return arg2.isDefinitelyNotNull(); - } else { - // All other ASG's are math ops. - return true; - } - } - - if (op == JsBinaryOperator.COMMA) { - return arg2.isDefinitelyNotNull(); - } - - return false; - } - - @Override - public boolean isDefinitelyNull() { - if (op == JsBinaryOperator.AND) { - return arg1.isDefinitelyNull(); - } - return false; - } - - public void setArg1(JsExpression arg1) { - this.arg1 = arg1; - } - - public void setArg2(JsExpression arg2) { - this.arg2 = arg2; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - if (op.isAssignment()) { - arg1 = v.acceptLvalue(arg1); - } else { - arg1 = v.accept(arg1); - } - arg2 = v.accept(arg2); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.BINARY_OP; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsBinaryOperator.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsBinaryOperator.java deleted file mode 100644 index b54647f3a46..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsBinaryOperator.java +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents the operator in a JavaScript binary operation. - */ -public enum JsBinaryOperator implements JsOperator { - - /* - * Precedence indices from "JavaScript - The Definitive Guide" 4th Edition - * (page 57) - * - * - * Precedence 15 is for really important things that have their own AST - * classes. - * - * Precedence 14 is for unary operators. - */ - - MUL("*", 13, LEFT | INFIX), DIV("/", 13, LEFT | INFIX), MOD("%", 13, LEFT - | INFIX), - - ADD("+", 12, LEFT | INFIX), SUB("-", 12, LEFT | INFIX), - - SHL("<<", 11, LEFT | INFIX), SHR(">>", 11, LEFT | INFIX), SHRU(">>>", 11, - LEFT | INFIX), - - LT("<", 10, LEFT | INFIX), LTE("<=", 10, LEFT | INFIX), GT(">", 10, LEFT - | INFIX), GTE(">=", 10, LEFT | INFIX), INSTANCEOF("instanceof", 10, LEFT - | INFIX), INOP("in", 10, LEFT | INFIX), - - EQ("==", 9, LEFT | INFIX), NEQ("!=", 9, LEFT | INFIX), REF_EQ("===", 9, LEFT - | INFIX), REF_NEQ("!==", 9, LEFT | INFIX), - - BIT_AND("&", 8, LEFT | INFIX), - - BIT_XOR("^", 7, LEFT | INFIX), - - BIT_OR("|", 6, LEFT | INFIX), - - AND("&&", 5, LEFT | INFIX), - - OR("||", 4, LEFT | INFIX), - - // Precedence 3 is for the condition operator. - - // These assignment operators are right-associative. - ASG("=", 2, INFIX), ASG_ADD("+=", 2, INFIX), ASG_SUB("-=", 2, INFIX), ASG_MUL( - "*=", 2, INFIX), ASG_DIV("/=", 2, INFIX), ASG_MOD("%=", 2, INFIX), ASG_SHL( - "<<=", 2, INFIX), ASG_SHR(">>=", 2, INFIX), ASG_SHRU(">>>=", 2, INFIX), ASG_BIT_AND( - "&=", 2, INFIX), ASG_BIT_OR("|=", 2, INFIX), ASG_BIT_XOR("^=", 2, INFIX), - - COMMA(",", 1, LEFT | INFIX); - - private final int mask; - private final int precedence; - private final String symbol; - - private JsBinaryOperator(String symbol, int precedence, int mask) { - this.symbol = symbol; - this.precedence = precedence; - this.mask = mask; - } - - @Override - public int getPrecedence() { - return precedence; - } - - @Override - public String getSymbol() { - return symbol; - } - - public boolean isAssignment() { - /* - * Beware, flaky! Maybe I should have added Yet Another Field to - * BinaryOperator? - */ - return (getPrecedence() == ASG.getPrecedence()); - } - - @Override - public boolean isKeyword() { - return this == INSTANCEOF || this == INOP; - } - - @Override - public boolean isLeftAssociative() { - return (mask & LEFT) != 0; - } - - @Override - public boolean isPrecedenceLessThan(JsOperator other) { - return precedence < other.getPrecedence(); - } - - @Override - public boolean isValidInfix() { - return (mask & INFIX) != 0; - } - - @Override - public boolean isValidPostfix() { - return (mask & POSTFIX) != 0; - } - - @Override - public boolean isValidPrefix() { - return (mask & PREFIX) != 0; - } - - @Override - public String toString() { - return symbol; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsBlock.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsBlock.java deleted file mode 100644 index 39d1e356b2d..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsBlock.java +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import java.util.ArrayList; -import java.util.List; - -/** - * Represents a JavaScript block statement. - */ -public class JsBlock extends JsStatement { - - private final List stmts = new ArrayList(); - - public JsBlock() { - } - - public JsBlock(JsStatement stmt) { - stmts.add(stmt); - } - - public List getStatements() { - return stmts; - } - - public boolean isGlobalBlock() { - return false; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - v.acceptWithInsertRemove(stmts); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.BLOCK; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsBooleanLiteral.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsBooleanLiteral.java deleted file mode 100644 index 12238ddbb02..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsBooleanLiteral.java +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents a JavaScript literal boolean expression. - */ -public final class JsBooleanLiteral extends JsValueLiteral { - - private final boolean value; - - // Should be interned by JsProgram - JsBooleanLiteral(boolean value) { - this.value = value; - } - - public boolean getValue() { - return value; - } - - @Override - public boolean isBooleanFalse() { - return value == false; - } - - @Override - public boolean isBooleanTrue() { - return value == true; - } - - @Override - public boolean isDefinitelyNotNull() { - return true; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - v.visit(this, ctx); - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.BOOLEAN; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsBreak.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsBreak.java deleted file mode 100644 index 363f294df78..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsBreak.java +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents the JavaScript break statement. - */ -public final class JsBreak extends JsStatement { - - private final JsNameRef label; - - public JsBreak() { - this(null); - } - - public JsBreak(JsNameRef label) { - super(); - this.label = label; - } - - public JsNameRef getLabel() { - return label; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - if (label != null) { - v.accept(label); - } - } - v.endVisit(this, ctx); - } - - @Override - public boolean unconditionalControlBreak() { - return true; - } - - @Override - public NodeKind getKind() { - return NodeKind.BREAK; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsCase.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsCase.java deleted file mode 100644 index 43d2fc41230..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsCase.java +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents the JavaScript case statement. - */ -public final class JsCase extends JsSwitchMember { - - private JsExpression caseExpr; - - public JsCase() { - super(); - } - - public JsExpression getCaseExpr() { - return caseExpr; - } - - public void setCaseExpr(JsExpression caseExpr) { - this.caseExpr = caseExpr; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - caseExpr = v.accept(caseExpr); - v.acceptWithInsertRemove(stmts); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.CASE; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsCatch.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsCatch.java deleted file mode 100644 index f992545b944..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsCatch.java +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents a JavaScript catch clause. - */ -public class JsCatch extends JsNode implements HasCondition { - - protected final JsCatchScope scope; - private JsBlock body; - private JsExpression condition; - private JsParameter param; - - public JsCatch(JsScope parent, String ident) { - super(); - assert (parent != null); - scope = new JsCatchScope(parent, ident); - param = new JsParameter(scope.findExistingName(ident)); - } - - public JsBlock getBody() { - return body; - } - - @Override - public JsExpression getCondition() { - return condition; - } - - public JsParameter getParameter() { - return param; - } - - public JsScope getScope() { - return scope; - } - - public void setBody(JsBlock body) { - this.body = body; - } - - @Override - public void setCondition(JsExpression condition) { - this.condition = condition; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - param = v.accept(param); - if (condition != null) { - condition = v.accept(condition); - } - body = v.accept(body); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.CATCH; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsCatchScope.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsCatchScope.java deleted file mode 100644 index 6c9ce22a0e8..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsCatchScope.java +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * A special scope used only for catch blocks. It only holds a single symbol: - * the catch argument's name. - */ -public class JsCatchScope extends JsScope { - - private final JsName name; - - public JsCatchScope(JsScope parent, String ident) { - super(parent, "Catch scope"); - this.name = new JsName(this, ident, ident, ident); - } - - @Override - public JsName declareName(String ident) { - // Declare into parent scope! - return getParent().declareName(ident); - } - - @Override - public JsName declareName(String ident, String shortIdent) { - // Declare into parent scope! - return getParent().declareName(ident, shortIdent); - } - - @Override - public Iterator getAllNames() { - return new Iterator() { - private boolean didIterate = false; - - @Override - public boolean hasNext() { - return !didIterate; - } - - @Override - public JsName next() { - if (didIterate) { - throw new NoSuchElementException(); - } - didIterate = true; - return name; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } - - @Override - protected JsName doCreateName(String ident, String shortIdent, String originalName) { - throw new UnsupportedOperationException("Cannot create a name in a catch scope"); - } - - @Override - protected JsName findExistingNameNoRecurse(String ident) { - if (name.getIdent().equals(ident)) { - return name; - } else { - return null; - } - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsConditional.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsConditional.java deleted file mode 100644 index b1171bac2c0..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsConditional.java +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents a JavaScript conditional expression. - */ -public final class JsConditional extends JsExpression { - - private JsExpression elseExpr; - private JsExpression testExpr; - private JsExpression thenExpr; - - public JsConditional() { - } - - public JsConditional(JsExpression testExpr, JsExpression thenExpr, JsExpression elseExpr) { - this.testExpr = testExpr; - this.thenExpr = thenExpr; - this.elseExpr = elseExpr; - } - - public JsExpression getElseExpression() { - return elseExpr; - } - - public JsExpression getTestExpression() { - return testExpr; - } - - public JsExpression getThenExpression() { - return thenExpr; - } - - @Override - public boolean hasSideEffects() { - return testExpr.hasSideEffects() || thenExpr.hasSideEffects() || elseExpr.hasSideEffects(); - } - - @Override - public boolean isDefinitelyNotNull() { - return thenExpr.isDefinitelyNotNull() && elseExpr.isDefinitelyNotNull(); - } - - @Override - public boolean isDefinitelyNull() { - return thenExpr.isDefinitelyNull() && elseExpr.isDefinitelyNull(); - } - - public void setElseExpression(JsExpression elseExpr) { - this.elseExpr = elseExpr; - } - - public void setTestExpression(JsExpression testExpr) { - this.testExpr = testExpr; - } - - public void setThenExpression(JsExpression thenExpr) { - this.thenExpr = thenExpr; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - testExpr = v.accept(testExpr); - thenExpr = v.accept(thenExpr); - elseExpr = v.accept(elseExpr); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.CONDITIONAL; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsContext.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsContext.java deleted file mode 100644 index ddb170052d3..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsContext.java +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * The context in which a JsNode visitation occurs. This represents the set of - * possible operations a JsVisitor subclass can perform on the currently visited - * node. - */ -public interface JsContext { - - boolean canInsert(); - - boolean canRemove(); - - void insertAfter(JsVisitable node); - - void insertBefore(JsVisitable node); - - boolean isLvalue(); - - void removeMe(); - - void replaceMe(JsVisitable node); -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsContinue.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsContinue.java deleted file mode 100644 index d761815fe76..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsContinue.java +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents the JavaScript continue statement. - */ -public final class JsContinue extends JsStatement { - - private final JsNameRef label; - - public JsContinue() { - this(null); - } - - public JsContinue(JsNameRef label) { - super(); - this.label = label; - } - - public JsNameRef getLabel() { - return label; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - if (label != null) { - v.accept(label); - } - } - v.endVisit(this, ctx); - } - - @Override - public boolean unconditionalControlBreak() { - return true; - } - - @Override - public NodeKind getKind() { - return NodeKind.CONTINUE; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsDebugger.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsDebugger.java deleted file mode 100644 index 34cfae43f48..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsDebugger.java +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents a JavaScript debugger statement. - */ -public class JsDebugger extends JsStatement { - - public JsDebugger() { - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - v.visit(this, ctx); - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.DEBUGGER; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsDefault.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsDefault.java deleted file mode 100644 index a76987a8e5d..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsDefault.java +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents the default option in a JavaScript swtich statement. - */ -public final class JsDefault extends JsSwitchMember { - - public JsDefault() { - super(); - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - v.acceptWithInsertRemove(stmts); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.DEFAULT; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsDoWhile.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsDoWhile.java deleted file mode 100644 index 1dd4a47e8d4..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsDoWhile.java +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents a JavaScript do..while statement. - */ -public class JsDoWhile extends JsStatement { - - private JsStatement body; - private JsExpression condition; - - public JsDoWhile() { - super(); - } - - public JsDoWhile(JsExpression condition, JsStatement body) { - super(); - this.condition = condition; - this.body = body; - } - - public JsStatement getBody() { - return body; - } - - public JsExpression getCondition() { - return condition; - } - - public void setBody(JsStatement body) { - this.body = body; - } - - public void setCondition(JsExpression condition) { - this.condition = condition; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - body = v.accept(body); - condition = v.accept(condition); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.DO; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsEmpty.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsEmpty.java deleted file mode 100644 index c2ac99e3ac0..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsEmpty.java +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents an empty statement in JavaScript. - */ -public class JsEmpty extends JsStatement { - - // Interned by JsProgram - JsEmpty() { - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - v.visit(this, ctx); - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.EMPTY; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsExprStmt.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsExprStmt.java deleted file mode 100644 index 5b9fc1218c3..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsExprStmt.java +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents a JavaScript expression statement. - */ -public final class JsExprStmt extends JsStatement { - - private JsExpression expr; - - public JsExprStmt(JsExpression expr) { - super(); - this.expr = expr; - this.setSourceInfo(expr); - } - - public JsExpression getExpression() { - return expr; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - expr = v.accept(expr); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.EXPR_STMT; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsExpression.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsExpression.java deleted file mode 100644 index 43545ec98dc..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsExpression.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.common.SourceInfo; - -/** - * An abstract base class for all JavaScript expressions. - */ -public abstract class JsExpression extends JsNode { - - protected JsExpression() { - } - - /** - * Determines whether the expression can cause side effects. - */ - public abstract boolean hasSideEffects(); - - /** - * True if the target expression is definitely not null. - */ - public abstract boolean isDefinitelyNotNull(); - - /** - * True if the target expression is definitely null. - */ - public abstract boolean isDefinitelyNull(); - - /** - * Determines whether or not this expression is a leaf, such as a - * {@link JsNameRef}, {@link JsBooleanLiteral}, and so on. Leaf expressions - * never need to be parenthesized. - */ - public boolean isLeaf() { - // Conservatively say that it isn't a leaf. - // Individual subclasses can speak for themselves if they are a leaf. - return false; - } - - public JsExprStmt makeStmt() { - return new JsExprStmt(this); - } - - @Override - public JsExpression setSourceRef(SourceInfo info) { - super.setSourceRef(info); - return this; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsFor.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsFor.java deleted file mode 100644 index b980d4be1a2..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsFor.java +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.common.SourceInfo; - -/** - * A for statement. If specified at all, the initializer part is - * either a declaration of one or more variables, in which case - * {@link #getInitVars()} is used, or an expression, in which case - * {@link #getInitExpr()} is used. In the latter case, the comma operator is - * often used to create a compound expression. - * - *

- * Note that any of the parts of the for loop header can be - * null, although the body will never be null. - */ -public class JsFor extends JsStatement { - - private JsStatement body; - private JsExpression condition; - private JsExpression incrExpr; - private JsExpression initExpr; - private JsVars initVars; - - public JsFor() { - super(); - } - - public JsStatement getBody() { - return body; - } - - public JsExpression getCondition() { - return condition; - } - - public JsExpression getIncrExpr() { - return incrExpr; - } - - public JsExpression getInitExpr() { - return initExpr; - } - - public JsVars getInitVars() { - return initVars; - } - - public void setBody(JsStatement body) { - this.body = body; - } - - public void setCondition(JsExpression condition) { - this.condition = condition; - } - - public void setIncrExpr(JsExpression incrExpr) { - this.incrExpr = incrExpr; - } - - public void setInitExpr(JsExpression initExpr) { - this.initExpr = initExpr; - } - - public void setInitVars(JsVars initVars) { - this.initVars = initVars; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - assert (!(initExpr != null && initVars != null)); - - if (initExpr != null) { - initExpr = v.accept(initExpr); - } else if (initVars != null) { - initVars = v.accept(initVars); - } - - if (condition != null) { - condition = v.accept(condition); - } - - if (incrExpr != null) { - incrExpr = v.accept(incrExpr); - } - body = v.accept(body); - } - v.endVisit(this, ctx); - } - - @Override - public JsFor setSourceRef(SourceInfo info) { - super.setSourceRef(info); - return this; - } - - @Override - public NodeKind getKind() { - return NodeKind.FOR; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsForIn.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsForIn.java deleted file mode 100644 index 646e349885c..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsForIn.java +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents a JavaScript for..in statement. - */ -public class JsForIn extends JsStatement { - - private JsStatement body; - private JsExpression iterExpr; - private JsExpression objExpr; - - // Optional: the name of a new iterator variable to introduce - private final JsName iterVarName; - - public JsForIn() { - this(null); - } - - public JsForIn(JsName iterVarName) { - this.iterVarName = iterVarName; - } - - public JsStatement getBody() { - return body; - } - - public JsExpression getIterExpr() { - return iterExpr; - } - - public JsName getIterVarName() { - return iterVarName; - } - - public JsExpression getObjExpr() { - return objExpr; - } - - public void setBody(JsStatement body) { - this.body = body; - } - - public void setIterExpr(JsExpression iterExpr) { - this.iterExpr = iterExpr; - } - - public void setObjExpr(JsExpression objExpr) { - this.objExpr = objExpr; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - if (iterExpr != null) { - iterExpr = v.acceptLvalue(iterExpr); - } - objExpr = v.accept(objExpr); - body = v.accept(body); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.FOR_IN; - } -} \ No newline at end of file diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsFunction.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsFunction.java deleted file mode 100644 index 956f114e477..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsFunction.java +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.common.SourceInfo; -import com.google.dart.compiler.common.Symbol; - -import java.util.ArrayList; -import java.util.List; - -/** - * Represents a JavaScript function expression. - */ -public final class JsFunction extends JsLiteral implements HasName { - - private static void trace(String title, String code) { - System.out.println("---------------------------"); - System.out.println(title + ":"); - System.out.println("---------------------------"); - System.out.println(code); - } - - protected JsBlock body; - protected final List params = new ArrayList(); - protected final JsScope scope; - private boolean artificiallyRescued; - private boolean executeOnce; - private boolean fromDart; - private JsFunction impliedExecute; - private JsName name; - private boolean trace = false; - private boolean traceFirst = true; - private boolean hoisted = false; - private boolean constructor = false; - - /** - * Creates an anonymous function. - */ - public JsFunction(JsScope parent) { - this(parent, null, false); - } - - /** - * Creates a function that is not derived from Dart source. - */ - public JsFunction(JsScope parent, JsName name) { - this(parent, name, false); - } - - /** - * Creates a named function, possibly derived from Dart source. - */ - public JsFunction(JsScope parent, JsName name, boolean fromDart) { - assert (parent != null); - this.fromDart = fromDart; - setName(name); - String scopeName = (name == null) ? "" : name.getIdent(); - scopeName = "function " + scopeName; - this.scope = new JsScope(parent, scopeName); - } - - public JsBlock getBody() { - return body; - } - - /** - * If true, this indicates that only the first invocation of the function will - * have any effects. Subsequent invocations may be considered to be no-op - * calls whose return value is ignored. - */ - public boolean getExecuteOnce() { - return executeOnce; - } - - public JsFunction getImpliedExecute() { - return impliedExecute; - } - - @Override - public JsName getName() { - return name; - } - - @Override - public Symbol getSymbol() { - return name; - } - - public List getParameters() { - return params; - } - - public JsScope getScope() { - return scope; - } - - @Override - public boolean hasSideEffects() { - // If there's a name, the name is assigned to. - return name != null; - } - - public boolean isArtificiallyRescued() { - return artificiallyRescued; - } - - @Override - public boolean isBooleanFalse() { - return false; - } - - @Override - public boolean isBooleanTrue() { - return true; - } - - @Override - public boolean isDefinitelyNotNull() { - return true; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - public boolean isFromDart() { - return fromDart; - } - - public void setArtificiallyRescued(boolean rescued) { - this.artificiallyRescued = rescued; - } - - public void setBody(JsBlock body) { - this.body = body; - } - - public void setExecuteOnce(boolean executeOnce) { - this.executeOnce = executeOnce; - } - - public void setFromDart(boolean fromDart) { - this.fromDart = fromDart; - } - - public void setImpliedExecute(JsFunction impliedExecute) { - this.impliedExecute = impliedExecute; - } - - public void setName(JsName name) { - this.name = name; - if (name != null) { - if (isFromDart()) { - name.setStaticRef(this); - } - } - } - - public void setTrace() { - this.trace = true; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - String before = null; - if (trace && v instanceof JsModVisitor) { - before = this.toSource(); - if (traceFirst) { - traceFirst = false; - trace("SCRIPT INITIAL", before); - } - } - if (v.visit(this, ctx)) { - v.acceptWithInsertRemove(params); - body = v.accept(body); - } - v.endVisit(this, ctx); - if (trace && v instanceof JsModVisitor) { - String after = this.toSource(); - if (!after.equals(before)) { - String title = v.getClass().getSimpleName(); - trace(title, after); - } - } - } - - public void setHoisted() { - hoisted = true; - } - - /** Whether the function has been hoisted */ - public boolean isHoisted() { - return hoisted; - } - - /** - * Rebase the function to a new scope. - * @param newScopeParent The scope to add the function to. - */ - public void rebaseScope(JsScope newScopeParent) { - this.scope.rebase(newScopeParent); - } - - @Override - public JsFunction setSourceRef(SourceInfo info) { - super.setSourceRef(info); - return this; - } - - public boolean isConstructor() { - return this.constructor; - } - - public boolean setIsConstructor(boolean constructor) { - return this.constructor = constructor; - } - - @Override - public NodeKind getKind() { - return NodeKind.FUNCTION; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsGlobalBlock.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsGlobalBlock.java deleted file mode 100644 index 9a14004e14c..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsGlobalBlock.java +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represnts a JavaScript block in the global scope. - */ -public class JsGlobalBlock extends JsBlock { - - public JsGlobalBlock() { - } - - @Override - public boolean isGlobalBlock() { - return true; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsIf.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsIf.java deleted file mode 100644 index 478538235ab..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsIf.java +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents a JavaScript if statement. - */ -public final class JsIf extends JsStatement { - - private JsExpression ifExpr; - private JsStatement thenStmt; - private JsStatement elseStmt; - - public JsIf() { - } - - public JsIf(JsExpression ifExpr, JsStatement thenStmt, JsStatement elseStmt) { - this.ifExpr = ifExpr; - this.thenStmt = thenStmt; - this.elseStmt = elseStmt; - } - - public JsStatement getElseStmt() { - return elseStmt; - } - - public JsExpression getIfExpr() { - return ifExpr; - } - - public JsStatement getThenStmt() { - return thenStmt; - } - - public void setElseStmt(JsStatement elseStmt) { - this.elseStmt = elseStmt; - } - - public void setIfExpr(JsExpression ifExpr) { - this.ifExpr = ifExpr; - } - - public void setThenStmt(JsStatement thenStmt) { - this.thenStmt = thenStmt; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - ifExpr = v.accept(ifExpr); - thenStmt = v.accept(thenStmt); - if (elseStmt != null) { - elseStmt = v.accept(elseStmt); - } - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.IF; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsInvocation.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsInvocation.java deleted file mode 100644 index beb10a1eeed..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsInvocation.java +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import java.util.ArrayList; -import java.util.List; - -/** - * Represents a JavaScript invocation. - */ -public final class JsInvocation extends JsExpression implements HasArguments { - - private final List args = new ArrayList(); - private JsExpression qualifier; - - public JsInvocation() { - } - - @Override - public List getArguments() { - return args; - } - - public JsExpression getQualifier() { - return qualifier; - } - - @Override - public boolean hasSideEffects() { - return true; - } - - @Override - public boolean isDefinitelyNotNull() { - return false; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - public void setQualifier(JsExpression qualifier) { - this.qualifier = qualifier; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - qualifier = v.accept(qualifier); - v.acceptList(args); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.INVOKE; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsLabel.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsLabel.java deleted file mode 100644 index ec044fea415..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsLabel.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.common.Symbol; - -/** - * Represents a JavaScript label statement. - */ -public class JsLabel extends JsStatement implements HasName { - - private final JsName label; - - private JsStatement stmt; - - public JsLabel(JsName label) { - this.label = label; - } - - @Override - public JsName getName() { - return label; - } - - @Override - public Symbol getSymbol() { - return label; - } - - public JsStatement getStmt() { - return stmt; - } - - public void setStmt(JsStatement stmt) { - this.stmt = stmt; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - stmt = v.accept(stmt); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.LABEL; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsLiteral.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsLiteral.java deleted file mode 100644 index c87ae0c8af1..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsLiteral.java +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript string literal expression. - */ -public abstract class JsLiteral extends JsExpression implements CanBooleanEval { - - protected JsLiteral() { - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsModVisitor.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsModVisitor.java deleted file mode 100644 index ef6e75ce994..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsModVisitor.java +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.util.Hack; - -import java.util.List; - -/** - * A visitor for iterating through and modifying an AST. - */ -public class JsModVisitor extends JsVisitor { - - private class ListContext implements JsContext { - - private List collection; - private int index; - private boolean removed; - private boolean replaced; - - @Override - public boolean canInsert() { - return true; - } - - @Override - public boolean canRemove() { - return true; - } - - @Override - public void insertAfter(JsVisitable node) { - checkRemoved(); - collection.add(index + 1, Hack.cast(node)); - didChange = true; - } - - @Override - public void insertBefore(JsVisitable node) { - checkRemoved(); - collection.add(index++, Hack.cast(node)); - didChange = true; - } - - @Override - public boolean isLvalue() { - return false; - } - - @Override - public void removeMe() { - checkState(); - collection.remove(index--); - didChange = removed = true; - } - - @Override - public void replaceMe(JsVisitable node) { - checkState(); - checkReplacement(collection.get(index), node); - collection.set(index, Hack.cast(node)); - didChange = replaced = true; - } - - protected void traverse(List collection) { - this.collection = collection; - for (index = 0; index < collection.size(); ++index) { - removed = replaced = false; - doTraverse(collection.get(index), this); - } - } - - private void checkRemoved() { - if (removed) { - throw new RuntimeException("Node was already removed"); - } - } - - private void checkState() { - checkRemoved(); - if (replaced) { - throw new RuntimeException("Node was already replaced"); - } - } - } - - private class LvalueContext extends NodeContext { - @Override - public boolean isLvalue() { - return true; - } - } - - private class NodeContext implements JsContext { - private T node; - private boolean replaced; - - @Override - public boolean canInsert() { - return false; - } - - @Override - public boolean canRemove() { - return false; - } - - @Override - public void insertAfter(JsVisitable node) { - throw new UnsupportedOperationException(); - } - - @Override - public void insertBefore(JsVisitable node) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isLvalue() { - return false; - } - - @Override - public void removeMe() { - throw new UnsupportedOperationException(); - } - - @Override - public void replaceMe(JsVisitable node) { - if (replaced) { - throw new RuntimeException("Node was already replaced"); - } - checkReplacement(this.node, node); - this.node = Hack.cast(node); - didChange = replaced = true; - } - - protected T traverse(T node) { - this.node = node; - replaced = false; - doTraverse(node, this); - return this.node; - } - } - - protected static void checkReplacement(T origNode, T newNode) { - if (newNode == null) { - throw new RuntimeException("Cannot replace with null"); - } - if (newNode == origNode) { - throw new RuntimeException("The replacement is the same as the original"); - } - } - - protected boolean didChange = false; - - @Override - public boolean didChange() { - return didChange; - } - - @Override - protected T doAccept(T node) { - return new NodeContext().traverse(node); - } - - @Override - protected void doAcceptList(List collection) { - NodeContext ctx = new NodeContext(); - for (int i = 0, c = collection.size(); i < c; ++i) { - ctx.traverse(collection.get(i)); - if (ctx.replaced) { - collection.set(i, ctx.node); - } - } - } - - @Override - protected JsExpression doAcceptLvalue(JsExpression expr) { - return new LvalueContext().traverse(expr); - } - - @Override - protected void doAcceptWithInsertRemove(List collection) { - new ListContext().traverse(collection); - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsName.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsName.java deleted file mode 100644 index 97fab4dfe8c..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsName.java +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.ast.DartNode; -import com.google.dart.compiler.common.Symbol; - -import java.io.Serializable; - -/** - * An abstract base class for named JavaScript objects. - */ -public class JsName implements Symbol, Serializable { - private final JsScope enclosing; - private final String ident; - private boolean isObfuscatable; - private String shortIdent; - private String originalName; - - /** - * A back-reference to the JsNode that the JsName refers to. - */ - private JsNode staticRef; - - /** - * @param ident the unmangled ident to use for this name - */ - JsName(JsScope enclosing, String ident, String shortIdent, String originalName) { - this.enclosing = enclosing; - this.ident = ident; - this.shortIdent = shortIdent; - if (originalName != null) { - this.originalName = originalName; - } - this.isObfuscatable = true; - } - - public JsScope getEnclosing() { - return enclosing; - } - - public String getIdent() { - return ident; - } - - public String getShortIdent() { - return shortIdent; - } - - public String getOriginalName() { - return originalName; - } - - public JsNode getStaticRef() { - return staticRef; - } - - public boolean isObfuscatable() { - return isObfuscatable; - } - - public JsNameRef makeRef() { - return new JsNameRef(this); - } - - public void setObfuscatable(boolean isObfuscatable) { - this.isObfuscatable = isObfuscatable; - } - - public void setShortIdent(String shortIdent) { - this.shortIdent = shortIdent; - } - - /** - * Should never be called except on immutable stuff. - */ - public void setStaticRef(JsNode node) { - this.staticRef = node; - } - - @Override - public String toString() { - return ident; - } - - @Override - public String getOriginalSymbolName() { - return getOriginalName(); - } - - @Override - public int hashCode() { - return ident.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof JsName)) { - return false; - } - JsName other = (JsName) obj; - return ident.equals(other.ident) && enclosing == other.enclosing; - } - - @Override - public DartNode getNode() { - throw new UnsupportedOperationException(); - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsNameRef.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsNameRef.java deleted file mode 100644 index fd07125e98b..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsNameRef.java +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.common.Symbol; - -/** - * Represents a JavaScript expression that references a name. - */ -public final class JsNameRef extends JsExpression implements CanBooleanEval, HasName { - - private String ident; - private JsName name; - private JsExpression qualifier; - - public JsNameRef(JsName name) { - this.name = name; - } - - public JsNameRef(String ident) { - this.ident = ident; - } - - public String getIdent() { - return (name == null) ? ident : name.getIdent(); - } - - @Override - public JsName getName() { - return name; - } - - @Override - public Symbol getSymbol() { - return name; - } - - public JsExpression getQualifier() { - return qualifier; - } - - public String getShortIdent() { - return (name == null) ? ident : name.getShortIdent(); - } - - @Override - public boolean hasSideEffects() { - if (qualifier == null) { - return false; - } - if (!qualifier.isDefinitelyNotNull()) { - // Could trigger NPE. - return true; - } - return qualifier.hasSideEffects(); - } - - @Override - public boolean isBooleanFalse() { - return isDefinitelyNull(); - } - - @Override - public boolean isBooleanTrue() { - return false; - } - - @Override - public boolean isDefinitelyNotNull() { - // TODO: look for single-assignment of stuff from Java? - return false; - } - - @Override - public boolean isDefinitelyNull() { - if (name != null) { - return (name.getEnclosing().getProgram().getUndefinedLiteral().getName() == name); - } - return false; - } - - @Override - public boolean isLeaf() { - if (qualifier == null) { - return true; - } else { - return false; - } - } - - public boolean isResolved() { - return name != null; - } - - public void resolve(JsName name) { - this.name = name; - this.ident = null; - } - - public void setQualifier(JsExpression qualifier) { - this.qualifier = qualifier; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - if (qualifier != null) { - qualifier = v.accept(qualifier); - } - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.NAME_REF; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsNew.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsNew.java deleted file mode 100644 index 19b6f5d6c90..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsNew.java +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import java.util.ArrayList; -import java.util.List; - -/** - * Represents the JavaScript new expression. - */ -public final class JsNew extends JsExpression implements HasArguments { - - private final List args = new ArrayList(); - private JsExpression ctorExpr; - - public JsNew(JsExpression ctorExpr) { - this.ctorExpr = ctorExpr; - } - - @Override - public List getArguments() { - return args; - } - - public JsExpression getConstructorExpression() { - return ctorExpr; - } - - @Override - public boolean hasSideEffects() { - return true; - } - - @Override - public boolean isDefinitelyNotNull() { - // Sadly, in JS it can be! - // TODO: analysis could probably determine most instances cannot be null. - return false; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - ctorExpr = v.accept(ctorExpr); - v.acceptList(args); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.NEW; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsNode.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsNode.java deleted file mode 100644 index 2856ad8a008..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsNode.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.backend.js.JsSourceGenerationVisitor; -import com.google.dart.compiler.backend.js.JsToStringGenerationVisitor; -import com.google.dart.compiler.common.AbstractNode; -import com.google.dart.compiler.common.SourceInfo; -import com.google.dart.compiler.util.DefaultTextOutput; - -/** - * Base class for all JS AST elements. - */ -public abstract class JsNode extends AbstractNode implements JsVisitable { - - protected JsNode() { - } - - // Causes source generation to delegate to the one visitor - public final String toSource() { - DefaultTextOutput out = new DefaultTextOutput(false); - JsSourceGenerationVisitor v = new JsSourceGenerationVisitor(out); - v.accept(this); - return out.toString(); - } - - // Causes source generation to delegate to the one visitor - @Override - public final String toString() { - DefaultTextOutput out = new DefaultTextOutput(false); - JsToStringGenerationVisitor v = new JsToStringGenerationVisitor(out); - v.accept(this); - return out.toString(); - } - - @Override - public SourceInfo getSourceInfo() { - return this; - } - - public JsNode setSourceRef(SourceInfo info) { - if (info != null) { - this.setSourceInfo(info); - } - return this; - } - - public abstract NodeKind getKind(); -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsNullLiteral.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsNullLiteral.java deleted file mode 100644 index 506b2e3f330..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsNullLiteral.java +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript null literal. - */ -public final class JsNullLiteral extends JsValueLiteral { - - // Should only be instantiated in JsProgram - JsNullLiteral() { - } - - @Override - public boolean isBooleanFalse() { - return true; - } - - @Override - public boolean isBooleanTrue() { - return false; - } - - @Override - public boolean isDefinitelyNotNull() { - return false; - } - - @Override - public boolean isDefinitelyNull() { - return true; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - v.visit(this, ctx); - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.NULL; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsNumberLiteral.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsNumberLiteral.java deleted file mode 100644 index 726c6b0ed27..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsNumberLiteral.java +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Represents a JavaScript literal decimal expression. - */ -public final class JsNumberLiteral extends JsValueLiteral { - - private final double value; - - // Should be interned by JsProgram - JsNumberLiteral(double value) { - this.value = value; - } - - public double getValue() { - return value; - } - - @Override - public boolean isBooleanFalse() { - return value == 0.0; - } - - @Override - public boolean isBooleanTrue() { - return value != 0.0; - } - - @Override - public boolean isDefinitelyNotNull() { - return true; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - v.visit(this, ctx); - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.NUMBER; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsObjectLiteral.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsObjectLiteral.java deleted file mode 100644 index 4f70265624b..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsObjectLiteral.java +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import java.util.ArrayList; -import java.util.List; - -/** - * A JavaScript object literal. - */ -public final class JsObjectLiteral extends JsLiteral { - - private final List props = new ArrayList(); - - public JsObjectLiteral() { - } - - public List getPropertyInitializers() { - return props; - } - - @Override - public boolean hasSideEffects() { - for (JsPropertyInitializer prop : props) { - if (prop.hasSideEffects()) { - return true; - } - } - return false; - } - - @Override - public boolean isBooleanFalse() { - return false; - } - - @Override - public boolean isBooleanTrue() { - return true; - } - - @Override - public boolean isDefinitelyNotNull() { - return true; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - v.acceptWithInsertRemove(props); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.OBJECT; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsOperator.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsOperator.java deleted file mode 100644 index e4440cbe9ab..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsOperator.java +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript operator. - */ -public interface JsOperator { - - int INFIX = 0x02; - int LEFT = 0x01; - int POSTFIX = 0x04; - int PREFIX = 0x08; - - int getPrecedence(); - - String getSymbol(); - - boolean isKeyword(); - - boolean isLeftAssociative(); - - boolean isPrecedenceLessThan(JsOperator other); - - boolean isValidInfix(); - - boolean isValidPostfix(); - - boolean isValidPrefix(); -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsParameter.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsParameter.java deleted file mode 100644 index 758767d62bc..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsParameter.java +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.common.Symbol; - -/** - * A JavaScript parameter. - */ -public final class JsParameter extends JsNode implements HasName { - - private final JsName name; - - public JsParameter(JsName name) { - this.name = name; - name.setStaticRef(this); - } - - @Override - public JsName getName() { - return name; - } - - @Override - public Symbol getSymbol() { - return name; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - v.visit(this, ctx); - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.PARAMETER; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsPostfixOperation.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsPostfixOperation.java deleted file mode 100644 index a33536f6c0d..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsPostfixOperation.java +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript postfix operation. - */ -public final class JsPostfixOperation extends JsUnaryOperation { - - public JsPostfixOperation(JsUnaryOperator op) { - this(op, null); - } - - public JsPostfixOperation(JsUnaryOperator op, JsExpression arg) { - super(op, arg); - } - - @Override - public boolean isDefinitelyNotNull() { - return true; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - super.traverse(v, ctx); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.POSTFIX_OP; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsPrefixOperation.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsPrefixOperation.java deleted file mode 100644 index 8ce12c7bacd..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsPrefixOperation.java +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript prefix operation. - */ -public final class JsPrefixOperation extends JsUnaryOperation implements CanBooleanEval { - - public JsPrefixOperation(JsUnaryOperator op) { - this(op, null); - } - - public JsPrefixOperation(JsUnaryOperator op, JsExpression arg) { - super(op, arg); - } - - @Override - public boolean isBooleanFalse() { - if (getOperator() == JsUnaryOperator.VOID) { - return true; - } - if (getOperator() == JsUnaryOperator.NOT && getArg() instanceof CanBooleanEval) { - CanBooleanEval eval = (CanBooleanEval) getArg(); - return eval.isBooleanTrue(); - } - return false; - } - - @Override - public boolean isBooleanTrue() { - if (getOperator() == JsUnaryOperator.NOT && getArg() instanceof CanBooleanEval) { - CanBooleanEval eval = (CanBooleanEval) getArg(); - return eval.isBooleanFalse(); - } - if (getOperator() == JsUnaryOperator.TYPEOF) { - return true; - } - return false; - } - - @Override - public boolean isDefinitelyNotNull() { - if (getOperator() == JsUnaryOperator.TYPEOF) { - return true; - } - return getOperator() != JsUnaryOperator.VOID; - } - - @Override - public boolean isDefinitelyNull() { - return getOperator() == JsUnaryOperator.VOID; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - super.traverse(v, ctx); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.PREFIX_OP; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsProgram.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsProgram.java deleted file mode 100644 index 1d2c902d27a..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsProgram.java +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import java.util.HashMap; -import java.util.Map; - -/** - * A JavaScript program. - */ -public final class JsProgram extends JsNode { - - private final JsStatement debuggerStmt; - private final JsEmpty emptyStmt; - private final JsBooleanLiteral falseLiteral; - private JsProgramFragment[] fragments; - private final Map indexedFunctions = new HashMap(); - private final JsNullLiteral nullLiteral; - private final Map numberLiteralMap = - new HashMap(); - private final JsScope objectScope; - private final JsRootScope rootScope; - private final Map stringLiteralMap = - new HashMap(); - private final JsScope topScope; - private final JsBooleanLiteral trueLiteral; - - /** - * Constructs a JavaScript program object. - */ - public JsProgram(String unitId) { - rootScope = new JsRootScope(this); - topScope = new JsScope(rootScope, "Global", unitId); - objectScope = new JsScope(rootScope, "Object"); - setFragmentCount(1); - - debuggerStmt = new JsDebugger(); - emptyStmt = new JsEmpty(); - falseLiteral = new JsBooleanLiteral(false); - nullLiteral = new JsNullLiteral(); - trueLiteral = new JsBooleanLiteral(true); - } - - public JsBooleanLiteral getBooleanLiteral(boolean truth) { - if (truth) { - return getTrueLiteral(); - } - return getFalseLiteral(); - } - - /** - * Gets the {@link JsStatement} to use whenever parsed source include a - * debugger statement. - */ - public JsStatement getDebuggerStmt() { - return debuggerStmt; - } - - public JsEmpty getEmptyStmt() { - return emptyStmt; - } - - public JsBooleanLiteral getFalseLiteral() { - return falseLiteral; - } - - public JsBlock getFragmentBlock(int fragment) { - if (fragment < 0 || fragment >= fragments.length) { - throw new IllegalArgumentException("Invalid fragment: " + fragment); - } - return fragments[fragment].getGlobalBlock(); - } - - public int getFragmentCount() { - return this.fragments.length; - } - - /** - * Gets the one and only global block. - */ - public JsBlock getGlobalBlock() { - return getFragmentBlock(0); - } - - public JsFunction getIndexedFunction(String name) { - return indexedFunctions.get(name); - } - - public JsNullLiteral getNullLiteral() { - return nullLiteral; - } - - public JsNumberLiteral getNumberLiteral(double value) { - JsNumberLiteral lit = numberLiteralMap.get(value); - if (lit == null) { - lit = new JsNumberLiteral(value); - numberLiteralMap.put(value, lit); - } - - return lit; - } - - public JsScope getObjectScope() { - return objectScope; - } - - /** - * Gets the quasi-mythical root scope. This is not the same as the top scope; - * all unresolvable identifiers wind up here, because they are considered - * external to the program. - */ - public JsRootScope getRootScope() { - return rootScope; - } - - /** - * Gets the top level scope. This is the scope of all the statements in the - * main program. - */ - public JsScope getScope() { - return topScope; - } - - /** - * Creates or retrieves a JsStringLiteral from an interned object pool. - */ - public JsStringLiteral getStringLiteral(String value) { - JsStringLiteral lit = stringLiteralMap.get(value); - if (lit == null) { - lit = new JsStringLiteral(value); - stringLiteralMap.put(value, lit); - } - return lit; - } - - public JsBooleanLiteral getTrueLiteral() { - return trueLiteral; - } - - public JsNameRef getUndefinedLiteral() { - return new JsNameRef("$Dart$Null"); - } - - public void setFragmentCount(int fragments) { - this.fragments = new JsProgramFragment[fragments]; - for (int i = 0; i < fragments; i++) { - this.fragments[i] = new JsProgramFragment(); - } - } - - public void setIndexedFunctions(Map indexedFunctions) { - this.indexedFunctions.clear(); - this.indexedFunctions.putAll(indexedFunctions); - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - for (JsProgramFragment fragment : fragments) { - v.accept(fragment); - } - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.PROGRAM; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsProgramFragment.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsProgramFragment.java deleted file mode 100644 index 3c6859e2150..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsProgramFragment.java +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * One independently loadable fragment of a {@link JsProgram}. - */ -public class JsProgramFragment extends JsNode { - - private final JsGlobalBlock globalBlock; - - public JsProgramFragment() { - this.globalBlock = new JsGlobalBlock(); - } - - public JsBlock getGlobalBlock() { - return globalBlock; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - v.accept(globalBlock); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.PROGRAM_FRAGMENT; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsPropertyInitializer.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsPropertyInitializer.java deleted file mode 100644 index d68d8d01af4..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsPropertyInitializer.java +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Used in object literals to specify property values by name. - */ -public class JsPropertyInitializer extends JsNode { - - private JsExpression labelExpr; - private JsExpression valueExpr; - - public JsPropertyInitializer() { - } - - public JsPropertyInitializer(JsExpression labelExpr, JsExpression valueExpr) { - this.labelExpr = labelExpr; - this.valueExpr = valueExpr; - } - - public JsExpression getLabelExpr() { - return labelExpr; - } - - public JsExpression getValueExpr() { - return valueExpr; - } - - public boolean hasSideEffects() { - return labelExpr.hasSideEffects() || valueExpr.hasSideEffects(); - } - - public void setLabelExpr(JsExpression labelExpr) { - this.labelExpr = labelExpr; - } - - public void setValueExpr(JsExpression valueExpr) { - this.valueExpr = valueExpr; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - labelExpr = v.accept(labelExpr); - valueExpr = v.accept(valueExpr); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.PROPERTY_INIT; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsRegExp.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsRegExp.java deleted file mode 100644 index 158c7a5e092..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsRegExp.java +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript regular expression. - */ -public final class JsRegExp extends JsValueLiteral { - - private String flags; - private String pattern; - - public JsRegExp() { - } - - public String getFlags() { - return flags; - } - - public String getPattern() { - return pattern; - } - - @Override - public boolean isBooleanFalse() { - return false; - } - - @Override - public boolean isBooleanTrue() { - return true; - } - - @Override - public boolean isDefinitelyNotNull() { - return true; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - public void setFlags(String suffix) { - this.flags = suffix; - } - - public void setPattern(String re) { - this.pattern = re; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - v.visit(this, ctx); - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.REGEXP; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsReturn.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsReturn.java deleted file mode 100644 index 16d90e4b353..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsReturn.java +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript return statement. - */ -public final class JsReturn extends JsStatement { - - private JsExpression expr; - - public JsReturn() { - } - - public JsReturn(JsExpression expr) { - this.expr = expr; - } - - public JsExpression getExpr() { - return expr; - } - - public void setExpr(JsExpression expr) { - this.expr = expr; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - if (expr != null) { - expr = v.accept(expr); - } - } - v.endVisit(this, ctx); - } - - @Override - public boolean unconditionalControlBreak() { - return true; - } - - @Override - public NodeKind getKind() { - return NodeKind.RETURN; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsRootScope.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsRootScope.java deleted file mode 100644 index 25c50b2c9ad..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsRootScope.java +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.backend.js.JsReservedIdentifiers; - -/** - * The root scope is the parent of every scope. All identifiers in this scope - * are not obfuscatable. This scope is prefilled with reserved global - * JavaScript symbols. - */ -public final class JsRootScope extends JsScope { - - private final JsProgram program; - - public JsRootScope(JsProgram program) { - super("Root"); - this.program = program; - } - - @Override - public JsProgram getProgram() { - return program; - } - - @Override - protected JsName doCreateName(String ident, String shortIdent, String originalName) { - JsName name = super.doCreateName(ident, shortIdent, originalName); - name.setObfuscatable(false); - return name; - } - - @Override - protected JsName findExistingNameNoRecurse(String ident) { - JsName name = super.findExistingNameNoRecurse(ident); - if (name == null) { - if (JsReservedIdentifiers.getReservedGlobalSymbols().contains(ident)) { - /* - * Lazily add JsNames for reserved identifiers. Since a JsName for a reserved global symbol - * must report a legitimate enclosing scope, we can't simply have a shared set of symbol - * names. - */ - name = doCreateName(ident, ident, ident); - } - } - return name; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsScope.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsScope.java deleted file mode 100644 index 0344842aa61..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsScope.java +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.common.collect.Interner; -import com.google.common.collect.Interners; -import com.google.dart.compiler.util.Lists; -import com.google.dart.compiler.util.Maps; - -import java.io.Serializable; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - * A scope is a factory for creating and allocating - * {@link com.google.dart.compiler.backend.js.ast.JsName}s. A JavaScript AST is - * built in terms of abstract name objects without worrying about obfuscation, - * keyword/identifier blacklisting, and so on. - * - *

- * - * Scopes are associated with - * {@link com.google.dart.compiler.backend.js.ast.JsFunction}s, but the two are - * not equivalent. Functions have scopes, but a scope does not - * necessarily have an associated Function. Examples of this include the - * {@link com.google.dart.compiler.backend.js.ast.JsRootScope} and synthetic - * scopes that might be created by a client. - * - *

- * - * Scopes can have parents to provide constraints when allocating actual - * identifiers for names. Specifically, names in child scopes are chosen such - * that they do not conflict with names in their parent scopes. The ultimate - * parent is usually the global scope (see - * {@link com.google.dart.compiler.backend.js.ast.JsProgram#getRootScope()}), - * but parentless scopes are useful for managing names that are always accessed - * with a qualifier and could therefore never be confused with the global scope - * hierarchy. - */ -public class JsScope implements Serializable { - - private List children = Collections.emptyList(); - private final String description; - private Map names = Collections.emptyMap(); - private JsScope parent; - protected int tempIndex = 0; - private final String scopeId; - private static Interner interner = Interners.newWeakInterner(); - - /* - * Create a scope with parent. - */ - public JsScope(JsScope parent, String description) { - this(parent, description, null); - } - - /** - * Create a scope with parent. - */ - public JsScope(JsScope parent, String description, String scopeId) { - assert (parent != null); - this.scopeId = scopeId; - this.description = interner.intern(description); - this.parent = parent; - parent.children = Lists.add(parent.children, this); - } - - /** - * Rebase the function to a new scope. - * @param newParent The scope to add the function to. - */ - public void rebase(JsScope newParent) { - detachFromParent(); - parent = newParent; - parent.children = Lists.add(parent.children, this); - } - - /** - * Rebase the function's children to a new scope. - * @param newParent - */ - public void rebaseChildScopes(JsScope newParent) { - if (newParent == this) { - return; - } - parent.children = Lists.addAll(parent.children, children); - for (JsScope child : children) { - child.parent = newParent; - } - children = Collections.emptyList(); - } - - /** - * Subclasses can detach and become parentless. - */ - protected void detachFromParent() { - JsScope oldParent = parent; - - oldParent.children = Lists.remove( - parent.children, oldParent.children.indexOf(this)); - - parent = null; - } - - /** - * Subclasses can be parentless. - */ - protected JsScope(String description) { - this.description = description; - this.parent = null; - this.scopeId = null; - } - - /** - * Gets a name object associated with the specified ident in this scope, - * creating it if necessary.
- * If the JsName does not exist yet, a new JsName is created. The ident, - * short name, and original name of the newly created JsName are equal to - * the given ident. - * - * @param ident An identifier that is unique within this scope. - */ - public JsName declareName(String ident) { - JsName name = findExistingNameNoRecurse(ident); - if (name != null) { - return name; - } - return doCreateName(ident, ident, ident); - } - - /** - * Creates a new variable with an unique ident in this scope. - * The generated JsName is guaranteed to have an identifier (but not short - * name) that does not clash with any existing variables in the scope. - * Future declarations of variables might however clash with the temporary - * (unless they use this function). - */ - public JsName declareFreshName(String shortName) { - String ident = shortName; - int counter = 0; - while (findExistingNameNoRecurse(ident) != null) { - ident = shortName + "_" + counter++; - } - return doCreateName(ident, shortName, shortName); - } - - String getNextTempName() { - // TODO(ngeoffray): Decide on a convention for temporary variables - // introduced by the compiler. - return "tmp$" + (scopeId != null ? scopeId + "$" : "") + tempIndex++; - } - - /** - * Creates a temporary variable with an unique name in this scope. - * The generated temporary is guaranteed to have an identifier (but not short - * name) that does not clash with any existing variables in the scope. - * Future declarations of variables might however clash with the temporary. - */ - public JsName declareTemporary() { - return declareFreshName(getNextTempName()); - } - - /** - * Gets a name object associated with the specified ident in this scope, - * creating it if necessary.
- * If the JsName does not exist yet, a new JsName is created with the given - * ident, short name and original name. - * - * @param ident An identifier that is unique within this scope. - * @param shortIdent A "pretty" name that does not have to be unique. - * @throws IllegalArgumentException if ident already exists in this scope but - * the requested short name does not match the existing short name. - */ - public JsName declareName(String ident, String shortIdent) { - return declareName(ident, shortIdent, ident); - } - - /** - * Gets a name object associated with the specified ident in this scope, - * creating it if necessary.
- * If the JsName does not exist yet, a new JsName is created. The original - * name stored in the JsName is equal to the (unmangled) specified originalName. - * - * @param ident An identifier that is unique within this scope. - * @param shortIdent A "pretty" name that does not have to be unique. - * @param originalName The original name in the source. - * @throws IllegalArgumentException if ident already exists in this scope but - * the requested short name does not match the existing short name, - * or the original name does not match the existing original name. - */ - public JsName declareName(String ident, String shortIdent, String originalName) { - JsName name = findExistingNameNoRecurse(ident); - if (name != null) { - if (!name.getShortIdent().equals(shortIdent) - || !nullableEquals(name.getOriginalName(), originalName)) { - throw new IllegalArgumentException("Requested short name " + shortIdent - + " conflicts with preexisting short name " + name.getShortIdent() + " for identifier " - + ident); - } - return name; - } - return doCreateName(ident, shortIdent, originalName); - } - - boolean nullableEquals(String s1, String s2) { - return (s1 == null) ? (s2 == null) : s1.equals(s2); - } - - /** - * Attempts to find the name object for the specified ident, searching in this - * scope, and if not found, in the parent scopes. - * - * @return null if the identifier has no associated name - */ - public final JsName findExistingName(String ident) { - JsName name = findExistingNameNoRecurse(ident); - if (name == null && parent != null) { - return parent.findExistingName(ident); - } - return name; - } - - /** - * Attempts to find an unobfuscatable name object for the specified ident, - * searching in this scope, and if not found, in the parent scopes. - * - * @return null if the identifier has no associated name - */ - public final JsName findExistingUnobfuscatableName(String ident) { - JsName name = findExistingNameNoRecurse(ident); - if (name != null && name.isObfuscatable()) { - name = null; - } - if (name == null && parent != null) { - return parent.findExistingUnobfuscatableName(ident); - } - return name; - } - - /** - * Returns an iterator for all the names defined by this scope. - */ - public Iterator getAllNames() { - return names.values().iterator(); - } - - /** - * Returns a list of this scope's child scopes. - */ - public final List getChildren() { - return children; - } - - /** - * Returns the parent scope of this scope, or null if this is the - * root scope. - */ - public final JsScope getParent() { - return parent; - } - - /** - * Returns the associated program. - */ - public JsProgram getProgram() { - assert (parent != null) : "Subclasses must override getProgram() if they do not set a parent"; - return parent.getProgram(); - } - - @Override - public final String toString() { - if (parent != null) { - return description + "->" + parent; - } else { - return description; - } - } - - /** - * Creates a new name in this scope. - */ - protected JsName doCreateName(String ident, String shortIdent, String originalName) { - JsName name = new JsName(this, ident, shortIdent, originalName); - names = Maps.putOrdered(names, ident, name); - return name; - } - - /** - * Attempts to find the name object for the specified ident, searching in this - * scope only. - * - * @return null if the identifier has no associated name - */ - protected JsName findExistingNameNoRecurse(String ident) { - return names.get(ident); - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsStatement.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsStatement.java deleted file mode 100644 index 82d37ca1185..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsStatement.java +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Abstract base class for JavaScript statement objects. - */ -public abstract class JsStatement extends JsNode { - - protected JsStatement() { - } - - /** - * Returns true if this statement definitely causes an abrupt change in flow - * control. - */ - public boolean unconditionalControlBreak() { - return false; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsStringLiteral.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsStringLiteral.java deleted file mode 100644 index 77e60c9b89a..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsStringLiteral.java +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript string literal expression. - */ -public final class JsStringLiteral extends JsValueLiteral { - - private final String value; - - // These only get created by JsProgram so that they can be interned. - JsStringLiteral(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public boolean isBooleanFalse() { - return value.length() == 0; - } - - @Override - public boolean isBooleanTrue() { - return value.length() != 0; - } - - @Override - public boolean isDefinitelyNotNull() { - return true; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - v.visit(this, ctx); - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.STRING; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsSwitch.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsSwitch.java deleted file mode 100644 index 5a49624af42..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsSwitch.java +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import java.util.ArrayList; -import java.util.List; - -/** - * A JavaScript switch statement. - */ -public class JsSwitch extends JsStatement { - - private final List cases = new ArrayList(); - private JsExpression expr; - - public JsSwitch() { - super(); - } - - public List getCases() { - return cases; - } - - public JsExpression getExpr() { - return expr; - } - - public void setExpr(JsExpression expr) { - this.expr = expr; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - expr = v.accept(expr); - v.acceptWithInsertRemove(cases); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.SWITCH; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsSwitchMember.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsSwitchMember.java deleted file mode 100644 index 0a748f60078..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsSwitchMember.java +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import java.util.ArrayList; -import java.util.List; - -/** - * A member/case in a JavaScript switch object. - */ -public abstract class JsSwitchMember extends JsNode { - - protected final List stmts = new ArrayList(); - - protected JsSwitchMember() { - super(); - } - - public List getStmts() { - return stmts; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsThisRef.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsThisRef.java deleted file mode 100644 index 9adb6459488..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsThisRef.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript this reference. - */ -public final class JsThisRef extends JsValueLiteral { - - public JsThisRef() { - super(); - } - - @Override - public boolean isBooleanFalse() { - return false; - } - - @Override - public boolean isBooleanTrue() { - return true; - } - - @Override - public boolean isDefinitelyNotNull() { - /* - * You'd think that you could get a null this via function.call/apply, but - * in fact you can't: they just make this be the window object instead. So - * it really can't ever be null. - */ - return true; - } - - @Override - public boolean isDefinitelyNull() { - return false; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - v.visit(this, ctx); - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.THIS; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsThrow.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsThrow.java deleted file mode 100644 index 4616418fb6b..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsThrow.java +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript throw statement. - */ -public class JsThrow extends JsStatement { - - private JsExpression expr; - - public JsThrow() { - super(); - } - - public JsThrow(JsExpression expr) { - super(); - this.expr = expr; - } - - public JsExpression getExpr() { - return expr; - } - - public void setExpr(JsExpression expr) { - this.expr = expr; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - expr = v.accept(expr); - } - v.endVisit(this, ctx); - } - - @Override - public boolean unconditionalControlBreak() { - return true; - } - - @Override - public NodeKind getKind() { - return NodeKind.THROW; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsTry.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsTry.java deleted file mode 100644 index 61357bcd406..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsTry.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import java.util.ArrayList; -import java.util.List; - -/** - * A JavaScript try statement. - */ -public class JsTry extends JsStatement { - - private final List catches = new ArrayList(); - private JsBlock finallyBlock; - private JsBlock tryBlock; - - public JsTry() { - super(); - } - - public List getCatches() { - return catches; - } - - public JsBlock getFinallyBlock() { - return finallyBlock; - } - - public JsBlock getTryBlock() { - return tryBlock; - } - - public void setFinallyBlock(JsBlock block) { - this.finallyBlock = block; - } - - public void setTryBlock(JsBlock block) { - tryBlock = block; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - tryBlock = v.accept(tryBlock); - v.acceptWithInsertRemove(catches); - if (finallyBlock != null) { - finallyBlock = v.accept(finallyBlock); - } - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.TRY; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsUnaryOperation.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsUnaryOperation.java deleted file mode 100644 index 00f103f35c9..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsUnaryOperation.java +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript prefix or postfix operation. - */ -public abstract class JsUnaryOperation extends JsExpression { - - private JsExpression arg; - - private final JsUnaryOperator op; - - public JsUnaryOperation(JsUnaryOperator op) { - this(op, null); - } - - public JsUnaryOperation(JsUnaryOperator op, JsExpression arg) { - super(); - this.op = op; - this.arg = arg; - } - - public JsExpression getArg() { - return arg; - } - - public JsUnaryOperator getOperator() { - return op; - } - - @Override - public final boolean hasSideEffects() { - return op.isModifying() || arg.hasSideEffects(); - } - - public void setArg(JsExpression arg) { - this.arg = arg; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (op.isModifying()) { - // The delete operator is practically like an assignment of undefined, so - // for practical purposes we're treating it as an lvalue. - arg = v.acceptLvalue(arg); - } else { - arg = v.accept(arg); - } - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsUnaryOperator.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsUnaryOperator.java deleted file mode 100644 index 2b854d8313e..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsUnaryOperator.java +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript unary operator. - */ -public enum JsUnaryOperator implements JsOperator { - - /* - * Precedence indices from "JavaScript - The Definitive Guide" 4th Edition - * (page 57) - */ - BIT_NOT("~", 14, PREFIX), DEC("--", 14, POSTFIX | PREFIX), DELETE("delete", 14, PREFIX), INC( - "++", 14, POSTFIX | PREFIX), NEG("-", 14, PREFIX), POS("+", 14, PREFIX), - NOT("!", 14, PREFIX), TYPEOF("typeof", 14, PREFIX), VOID("void", 14, PREFIX); - - private final int mask; - private final int precedence; - private final String symbol; - - private JsUnaryOperator(String symbol, int precedence, int mask) { - this.symbol = symbol; - this.precedence = precedence; - this.mask = mask; - } - - @Override - public int getPrecedence() { - return precedence; - } - - @Override - public String getSymbol() { - return symbol; - } - - @Override - public boolean isKeyword() { - return this == DELETE || this == TYPEOF || this == VOID; - } - - @Override - public boolean isLeftAssociative() { - return (mask & LEFT) != 0; - } - - public boolean isModifying() { - return this == DEC || this == INC || this == DELETE; - } - - @Override - public boolean isPrecedenceLessThan(JsOperator other) { - return precedence < other.getPrecedence(); - } - - @Override - public boolean isValidInfix() { - return (mask & INFIX) != 0; - } - - @Override - public boolean isValidPostfix() { - return (mask & POSTFIX) != 0; - } - - @Override - public boolean isValidPrefix() { - return (mask & PREFIX) != 0; - } - - @Override - public String toString() { - return symbol; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsValueLiteral.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsValueLiteral.java deleted file mode 100644 index f23ab5dbce4..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsValueLiteral.java +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript string literal expression. - */ -public abstract class JsValueLiteral extends JsLiteral { - - protected JsValueLiteral() { - } - - @Override - public final boolean hasSideEffects() { - return false; - } - - @Override - public final boolean isLeaf() { - return true; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsVars.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsVars.java deleted file mode 100644 index 7f2f50f3d51..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsVars.java +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.common.SourceInfo; -import com.google.dart.compiler.common.Symbol; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * A JavaScript var statement. - */ -public class JsVars extends JsStatement implements Iterable { - - /** - * A var declared using the JavaScript var statement. - */ - public static class JsVar extends JsNode implements HasName { - - private final JsName name; - private JsExpression initExpr; - - public JsVar(JsName name) { - this.name = name; - } - - public JsVar(JsName name, JsExpression initExpr) { - this.name = name; - this.initExpr = initExpr; - } - - public JsExpression getInitExpr() { - return initExpr; - } - - @Override - public JsName getName() { - return name; - } - - @Override - public Symbol getSymbol() { - return name; - } - - public void setInitExpr(JsExpression initExpr) { - this.initExpr = initExpr; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - if (initExpr != null) { - initExpr = v.accept(initExpr); - } - } - v.endVisit(this, ctx); - } - - @Override - public JsVar setSourceRef(SourceInfo info) { - super.setSourceRef(info); - return this; - } - - @Override - public NodeKind getKind() { - return NodeKind.VAR; - } - } - - private final List vars = new ArrayList(); - - public JsVars() { - } - - public void add(JsVar var) { - vars.add(var); - } - - public int getNumVars() { - return vars.size(); - } - - public void insert(JsVar var) { - vars.add(var); - } - - public boolean isEmpty() { - return vars.isEmpty(); - } - - // Iterator returns JsVar objects - @Override - public Iterator iterator() { - return vars.iterator(); - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - v.acceptWithInsertRemove(vars); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.VARS; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsVisitable.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsVisitable.java deleted file mode 100644 index 626648af8ae..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsVisitable.java +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * Abstracts the idea that a class can be traversed. - */ -public interface JsVisitable { - - /** - * Causes this object to have the visitor visit itself and its children. - * - * @param visitor the visitor that should traverse this node - * @param ctx the context of an existing traversal - */ - void traverse(JsVisitor visitor, JsContext ctx); -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsVisitor.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsVisitor.java deleted file mode 100644 index 8781300ec13..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsVisitor.java +++ /dev/null @@ -1,433 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -import com.google.dart.compiler.backend.js.ast.JsVars.JsVar; - -import java.util.Iterator; -import java.util.List; - -/** - * Implemented by nodes that will visit child nodes. - */ -@SuppressWarnings("unused") -public class JsVisitor { - - protected static final JsContext LVALUE_CONTEXT = new JsContext() { - - @Override - public boolean canInsert() { - return false; - } - - @Override - public boolean canRemove() { - return false; - } - - @Override - public void insertAfter(JsVisitable node) { - throw new UnsupportedOperationException(); - } - - @Override - public void insertBefore(JsVisitable node) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isLvalue() { - return true; - } - - @Override - public void removeMe() { - throw new UnsupportedOperationException(); - } - - @Override - public void replaceMe(JsVisitable node) { - throw new UnsupportedOperationException(); - } - }; - - protected static final JsContext UNMODIFIABLE_CONTEXT = new JsContext() { - - @Override - public boolean canInsert() { - return false; - } - - @Override - public boolean canRemove() { - return false; - } - - @Override - public void insertAfter(JsVisitable node) { - throw new UnsupportedOperationException(); - } - - @Override - public void insertBefore(JsVisitable node) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isLvalue() { - return false; - } - - @Override - public void removeMe() { - throw new UnsupportedOperationException(); - } - - @Override - public void replaceMe(JsVisitable node) { - throw new UnsupportedOperationException(); - } - }; - - public final T accept(T node) { - return this.doAccept(node); - } - - public final void acceptList(List collection) { - doAcceptList(collection); - } - - public JsExpression acceptLvalue(JsExpression expr) { - return doAcceptLvalue(expr); - } - - public final void acceptWithInsertRemove(List collection) { - doAcceptWithInsertRemove(collection); - } - - public boolean didChange() { - throw new UnsupportedOperationException(); - } - - public void endVisit(JsArrayAccess x, JsContext ctx) { - } - - public void endVisit(JsArrayLiteral x, JsContext ctx) { - } - - public void endVisit(JsBinaryOperation x, JsContext ctx) { - } - - public void endVisit(JsBlock x, JsContext ctx) { - } - - public void endVisit(JsBooleanLiteral x, JsContext ctx) { - } - - public void endVisit(JsBreak x, JsContext ctx) { - } - - public void endVisit(JsCase x, JsContext ctx) { - } - - public void endVisit(JsCatch x, JsContext ctx) { - } - - public void endVisit(JsConditional x, JsContext ctx) { - } - - public void endVisit(JsContinue x, JsContext ctx) { - } - - public void endVisit(JsDebugger x, JsContext ctx) { - } - - public void endVisit(JsDefault x, JsContext ctx) { - } - - public void endVisit(JsDoWhile x, JsContext ctx) { - } - - public void endVisit(JsEmpty x, JsContext ctx) { - } - - public void endVisit(JsExprStmt x, JsContext ctx) { - } - - public void endVisit(JsFor x, JsContext ctx) { - } - - public void endVisit(JsForIn x, JsContext ctx) { - } - - public void endVisit(JsFunction x, JsContext ctx) { - } - - public void endVisit(JsIf x, JsContext ctx) { - } - - public void endVisit(JsInvocation x, JsContext ctx) { - } - - public void endVisit(JsLabel x, JsContext ctx) { - } - - public void endVisit(JsNameRef x, JsContext ctx) { - } - - public void endVisit(JsNew x, JsContext ctx) { - } - - public void endVisit(JsNullLiteral x, JsContext ctx) { - } - - public void endVisit(JsNumberLiteral x, JsContext ctx) { - } - - public void endVisit(JsObjectLiteral x, JsContext ctx) { - } - - public void endVisit(JsParameter x, JsContext ctx) { - } - - public void endVisit(JsPostfixOperation x, JsContext ctx) { - } - - public void endVisit(JsPrefixOperation x, JsContext ctx) { - } - - public void endVisit(JsProgram x, JsContext ctx) { - } - - public void endVisit(JsProgramFragment x, JsContext ctx) { - } - - public void endVisit(JsPropertyInitializer x, JsContext ctx) { - } - - public void endVisit(JsRegExp x, JsContext ctx) { - } - - public void endVisit(JsReturn x, JsContext ctx) { - } - - public void endVisit(JsStringLiteral x, JsContext ctx) { - } - - public void endVisit(JsSwitch x, JsContext ctx) { - } - - public void endVisit(JsThisRef x, JsContext ctx) { - } - - public void endVisit(JsThrow x, JsContext ctx) { - } - - public void endVisit(JsTry x, JsContext ctx) { - } - - public void endVisit(JsVar x, JsContext ctx) { - } - - public void endVisit(JsVars x, JsContext ctx) { - } - - public void endVisit(JsWhile x, JsContext ctx) { - } - - public boolean visit(JsArrayAccess x, JsContext ctx) { - return true; - } - - public boolean visit(JsArrayLiteral x, JsContext ctx) { - return true; - } - - public boolean visit(JsBinaryOperation x, JsContext ctx) { - return true; - } - - public boolean visit(JsBlock x, JsContext ctx) { - return true; - } - - public boolean visit(JsBooleanLiteral x, JsContext ctx) { - return true; - } - - public boolean visit(JsBreak x, JsContext ctx) { - return true; - } - - public boolean visit(JsCase x, JsContext ctx) { - return true; - } - - public boolean visit(JsCatch x, JsContext ctx) { - return true; - } - - public boolean visit(JsConditional x, JsContext ctx) { - return true; - } - - public boolean visit(JsContinue x, JsContext ctx) { - return true; - } - - public boolean visit(JsDebugger x, JsContext ctx) { - return true; - } - - public boolean visit(JsDefault x, JsContext ctx) { - return true; - } - - public boolean visit(JsDoWhile x, JsContext ctx) { - return true; - } - - public boolean visit(JsEmpty x, JsContext ctx) { - return true; - } - - public boolean visit(JsExprStmt x, JsContext ctx) { - return true; - } - - public boolean visit(JsFor x, JsContext ctx) { - return true; - } - - public boolean visit(JsForIn x, JsContext ctx) { - return true; - } - - public boolean visit(JsFunction x, JsContext ctx) { - return true; - } - - public boolean visit(JsIf x, JsContext ctx) { - return true; - } - - public boolean visit(JsInvocation x, JsContext ctx) { - return true; - } - - public boolean visit(JsLabel x, JsContext ctx) { - return true; - } - - public boolean visit(JsNameRef x, JsContext ctx) { - return true; - } - - public boolean visit(JsNew x, JsContext ctx) { - return true; - } - - public boolean visit(JsNullLiteral x, JsContext ctx) { - return true; - } - - public boolean visit(JsNumberLiteral x, JsContext ctx) { - return true; - } - - public boolean visit(JsObjectLiteral x, JsContext ctx) { - return true; - } - - public boolean visit(JsParameter x, JsContext ctx) { - return true; - } - - public boolean visit(JsPostfixOperation x, JsContext ctx) { - return true; - } - - public boolean visit(JsPrefixOperation x, JsContext ctx) { - return true; - } - - public boolean visit(JsProgram x, JsContext ctx) { - return true; - } - - public boolean visit(JsProgramFragment x, JsContext ctx) { - return true; - } - - public boolean visit(JsPropertyInitializer x, JsContext ctx) { - return true; - } - - public boolean visit(JsRegExp x, JsContext ctx) { - return true; - } - - public boolean visit(JsReturn x, JsContext ctx) { - return true; - } - - public boolean visit(JsStringLiteral x, JsContext ctx) { - return true; - } - - public boolean visit(JsSwitch x, JsContext ctx) { - return true; - } - - public boolean visit(JsThisRef x, JsContext ctx) { - return true; - } - - public boolean visit(JsThrow x, JsContext ctx) { - return true; - } - - public boolean visit(JsTry x, JsContext ctx) { - return true; - } - - public boolean visit(JsVar x, JsContext ctx) { - return true; - } - - public boolean visit(JsVars x, JsContext ctx) { - return true; - } - - public boolean visit(JsWhile x, JsContext ctx) { - return true; - } - - protected T doAccept(T node) { - doTraverse(node, UNMODIFIABLE_CONTEXT); - return node; - } - - protected void doAcceptList(List collection) { - for (T node : collection) { - doTraverse(node, UNMODIFIABLE_CONTEXT); - } - } - - protected JsExpression doAcceptLvalue(JsExpression expr) { - doTraverse(expr, LVALUE_CONTEXT); - return expr; - } - - protected void doAcceptWithInsertRemove(List collection) { - for (T node : collection) { - doTraverse(node, UNMODIFIABLE_CONTEXT); - } - } - - protected void doTraverse(JsVisitable node, JsContext ctx) { - node.traverse(this, ctx); - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/JsWhile.java b/compiler/java/com/google/dart/compiler/backend/js/ast/JsWhile.java deleted file mode 100644 index c40203bc1f1..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/JsWhile.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -/** - * A JavaScript while statement. - */ -public class JsWhile extends JsStatement { - - private JsStatement body; - private JsExpression condition; - - public JsWhile() { - } - - public JsWhile(JsExpression condition, JsStatement body) { - this.condition = condition; - this.body = body; - } - - public JsStatement getBody() { - return body; - } - - public JsExpression getCondition() { - return condition; - } - - public void setBody(JsStatement body) { - this.body = body; - } - - public void setCondition(JsExpression condition) { - this.condition = condition; - } - - @Override - public void traverse(JsVisitor v, JsContext ctx) { - if (v.visit(this, ctx)) { - condition = v.accept(condition); - body = v.accept(body); - } - v.endVisit(this, ctx); - } - - @Override - public NodeKind getKind() { - return NodeKind.WHILE; - } -} diff --git a/compiler/java/com/google/dart/compiler/backend/js/ast/NodeKind.java b/compiler/java/com/google/dart/compiler/backend/js/ast/NodeKind.java deleted file mode 100644 index 614e4bb3bd9..00000000000 --- a/compiler/java/com/google/dart/compiler/backend/js/ast/NodeKind.java +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.ast; - -public enum NodeKind { - ARRAY_ACCESS, - ARRAY, - BINARY_OP, - BLOCK, - BOOLEAN, - BREAK, - CASE, - CATCH, - CONDITIONAL, - CONTINUE, - DEBUGGER, - DEFAULT, - DO, - EMPTY, - EXPR_STMT, - FOR, - FOR_IN, - FUNCTION, - IF, - INVOKE, - LABEL, - NAME_REF, - NEW, - NULL, - NUMBER, - OBJECT, - PARAMETER, - POSTFIX_OP, - PREFIX_OP, - PROGRAM, - PROGRAM_FRAGMENT, - PROPERTY_INIT, - REGEXP, - RETURN, - STRING, - SWITCH, - THIS, - THROW, - TRY, - VARS, - VAR, - WHILE -} diff --git a/compiler/java/com/google/dart/compiler/metrics/CompilerMetrics.java b/compiler/java/com/google/dart/compiler/metrics/CompilerMetrics.java index 161cbccc7cd..3f7d9380f6c 100644 --- a/compiler/java/com/google/dart/compiler/metrics/CompilerMetrics.java +++ b/compiler/java/com/google/dart/compiler/metrics/CompilerMetrics.java @@ -46,10 +46,6 @@ public final class CompilerMetrics { private long nanoParseWallTime = 0; private AtomicLong nanoTotalParseTime = new AtomicLong(); private long nativeLibCharCount; - private long packageAppTime = 0L; - private long packageAppTimeStart = 0L; - // JavascriptBackend Data - private long totalJsOutputCharCount; // Parser metrics private AtomicLong unitsParsed = new AtomicLong(); @@ -85,10 +81,6 @@ public final class CompilerMetrics { compileLibrariesTime = System.currentTimeMillis() - compileLibrariesTimeStart; } - public void endPackageAppTime() { - packageAppTime = System.currentTimeMillis() - packageAppTimeStart; - } - public void endUpdateAndResolveTime() { updateAndResolveTime = System.currentTimeMillis() - updateAndResolveTimeStart; } @@ -101,10 +93,6 @@ public final class CompilerMetrics { return nativeLibCharCount; } - public long getJSOutputCharSize() { - return totalJsOutputCharCount; - } - public double getLinesPerMS() { return getNumLinesParsed() / getTotalCompilationTime(); } @@ -133,10 +121,6 @@ public final class CompilerMetrics { return unitsParsed.get(); } - public long getPackageAppTime() { - return packageAppTime; - } - public double getParseTime() { return nanoToMillis(nanoTotalParseTime.get()); } @@ -152,20 +136,6 @@ public final class CompilerMetrics { public double getPercentTimeParsing() { return getParseTime() / getTotalCompilationTime(); } - - public double getRatioOutputToInput() { - if (getNumCharsParsed() == 0) { - return 0; - } - return getJSOutputCharSize() / getNumCharsParsed(); - } - - public double getRatioOutputToInputExcludingComments() { - if (getNumNonCommentChars() == 0) { - return 0; - } - return getJSOutputCharSize() / getNumNonCommentChars(); - } public double getTimeSpentPerUnit() { if (getNumUnitsParsed() == 0) { @@ -182,26 +152,10 @@ public final class CompilerMetrics { return updateAndResolveTime; } - /** - * Records that the application was packaged to JS. - * - * @param totalJsOutputCharSize number of characts of JS output produced - * @param nativeLibCharCount number of characters of JS output consumed by native JS libs or -1 if - * the backend did not record this information - */ - public void packagedJsApplication(long totalJsOutputCharSize, long nativeLibCharCount) { - this.totalJsOutputCharCount = totalJsOutputCharSize; - this.nativeLibCharCount = nativeLibCharCount; - } - public void startCompileLibrariesTime() { compileLibrariesTimeStart = System.currentTimeMillis(); } - public void startPackageAppTime() { - packageAppTimeStart = System.currentTimeMillis(); - } - public void startUpdateAndResolveTime() { updateAndResolveTimeStart = System.currentTimeMillis(); } @@ -226,7 +180,6 @@ public final class CompilerMetrics { out.format("Compile-time-total-ms : %1$.2f%n", getTotalCompilationTime()); out.format("# Update-and-resolve-time-ms : %d\n", getUpdateAndResolveTime()); out.format("# Compile-libraries-time-ms : %d\n", getCompileLibrariesTime()); - out.format("# Package-app-time-ms : %d\n", getPackageAppTime()); out.println("# Compile-time-unit-average-ms : " + getTimeSpentPerUnit()); out.format("# Parse-wall-time-ms : %1$.2f%n", getParseWallTime()); out.format("# Parse-time-ms : %1$.2f%n", getParseTime()); @@ -235,13 +188,10 @@ public final class CompilerMetrics { out.println("# Parsed-src-lines : " + getNumLinesParsed()); out.println("# Parsed-code-chars : " + getNumNonCommentChars()); out.println("# Parsed-code-lines : " + getNumNonCommentLines()); - out.println("# Output-js-chars : " + getJSOutputCharSize()); double jsNativeLibCharSize = (getJSNativeLibCharSize() == -1) ? 0 : getJSNativeLibCharSize(); out.println("# Output-js-native-lib-chars : " + jsNativeLibCharSize ); out.println("# Processed-total-lines-ms : " + getLinesPerMS()); out.println("# Processed-code-lines-ms : " + getNonCommentLinesPerMS()); - out.println("# Ratio-output-intput-total : " + getRatioOutputToInput()); - out.println("# Ratio-output-intput-code : " + getRatioOutputToInputExcludingComments()); out.println("# Ratio-parsing-compile-percent : " + getPercentTimeParsing() * 100); } } diff --git a/compiler/java/com/google/dart/compiler/metrics/DartEventType.java b/compiler/java/com/google/dart/compiler/metrics/DartEventType.java index cd0ca80f281..c6b2ec306da 100644 --- a/compiler/java/com/google/dart/compiler/metrics/DartEventType.java +++ b/compiler/java/com/google/dart/compiler/metrics/DartEventType.java @@ -11,34 +11,21 @@ import com.google.dart.compiler.metrics.Tracer.EventType; */ public enum DartEventType implements EventType { ADD_OUTOFDATE("MistyRose"), - BACKEND_COMPILE("DarkGreen"), - BACKEND_OUTOFDATE("DarkOliveGreen"), - BACKEND_PACKAGE_APP("MediumPurple"), BUILD_LIB_SCOPES("violet"), COMPILE("green"), COMPILE_APP("gray"), COMPILE_LIBRARIES("brown"), EXEC_PHASE("blue"), IMPORT_EMBEDDED_LIBRARIES("purple"), - IS_CLASS_OUT_OF_DATE("Aqua"), IS_SOURCE_OUTOFDATE("Chartreuse"), - JS_NORMALIZE("DarkMagenta"), - JS_SOURCE_GEN("LightBlue"), - NAMER("MidnightBlue"), - PACKAGE_APP("pink"), SCANNER("GoldenRod"), PARSE("red"), - PARSE_API("green"), PARSE_OUTOFDATE("LightCoral"), RESOLVE_LIBRARIES("black"), TIMESTAMP_OUTOFDATE("LightSteelBlue"), - TRANSLATE_NODE("Gold"), - TRANSLATE_TO_JS("MediumOrchid"), UPDATE_LIBRARIES("yellow"), UPDATE_RESOLVE("orange"), - WRITE_METRICS("LightChiffon"), - WRITE_SOURCE_MAP("MediumAquaMarine"), - GEN_AST_INIT("Olive"); + WRITE_METRICS("LightChiffon"); final String cssColor; final String name; diff --git a/compiler/java/com/google/dart/compiler/testing/TestCompilerConfiguration.java b/compiler/java/com/google/dart/compiler/testing/TestCompilerConfiguration.java index f35c94ba1b5..4177d483146 100644 --- a/compiler/java/com/google/dart/compiler/testing/TestCompilerConfiguration.java +++ b/compiler/java/com/google/dart/compiler/testing/TestCompilerConfiguration.java @@ -1,10 +1,9 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. package com.google.dart.compiler.testing; -import com.google.dart.compiler.Backend; import com.google.dart.compiler.CommandLineOptions.CompilerOptions; import com.google.dart.compiler.CompilerConfiguration; import com.google.dart.compiler.DartCompilationPhase; @@ -55,11 +54,6 @@ public class TestCompilerConfiguration implements CompilerConfiguration { return Collections.emptyList(); } - @Override - public File getOutputFilename() { - return null; - } - @Override public File getOutputDirectory() { throw new AssertionError(); @@ -75,21 +69,6 @@ public class TestCompilerConfiguration implements CompilerConfiguration { return null; } - @Override - public List getBackends() { - return Collections.emptyList(); - } - - @Override - public boolean checkOnly() { - return true; - } - - @Override - public boolean expectEntryPoint() { - return false; - } - @Override public LibrarySource getSystemLibraryFor(String importSpec) { URI systemUri; diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java index 04d2b458412..11ee910fd4b 100644 --- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java +++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java @@ -1119,10 +1119,9 @@ public class TypeAnalyzer implements DartCompilationPhase { // Check the map literal entries against the return type. Type valueType = type.getArguments().get(1); for (DartMapLiteralEntry literalEntry : node.getEntries()) { - boolean result = checkAssignable(literalEntry, typeOf(literalEntry), valueType); - if (developerModeChecks == true && result == false) { - typeError(literalEntry, ResolverErrorCode.MAP_LITERAL_ELEMENT_TYPE, - valueType.toString()); + boolean isValueAssignable = checkAssignable(literalEntry, typeOf(literalEntry), valueType); + if (developerModeChecks && !isValueAssignable) { + typeError(literalEntry, ResolverErrorCode.MAP_LITERAL_ELEMENT_TYPE, valueType); } } @@ -1716,10 +1715,9 @@ public class TypeAnalyzer implements DartCompilationPhase { InterfaceType type = node.getType(); Type elementType = type.getArguments().get(0); for (DartExpression expression : node.getExpressions()) { - boolean result = checkAssignable(elementType, expression); - if (developerModeChecks == true && result == false) { - typeError(expression, ResolverErrorCode.LIST_LITERAL_ELEMENT_TYPE, - elementType.toString()); + boolean isValueAssignable = checkAssignable(elementType, expression); + if (developerModeChecks && !isValueAssignable) { + typeError(expression, ResolverErrorCode.LIST_LITERAL_ELEMENT_TYPE, elementType); } } return type; diff --git a/compiler/java/com/google/dart/compiler/util/AstUtil.java b/compiler/java/com/google/dart/compiler/util/AstUtil.java deleted file mode 100644 index 11f7211fff9..00000000000 --- a/compiler/java/com/google/dart/compiler/util/AstUtil.java +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.util; - -import com.google.dart.compiler.InternalCompilerException; -import com.google.dart.compiler.backend.js.ast.JsArrayAccess; -import com.google.dart.compiler.backend.js.ast.JsBinaryOperation; -import com.google.dart.compiler.backend.js.ast.JsBinaryOperator; -import com.google.dart.compiler.backend.js.ast.JsBlock; -import com.google.dart.compiler.backend.js.ast.JsCase; -import com.google.dart.compiler.backend.js.ast.JsDefault; -import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsFunction; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.google.dart.compiler.backend.js.ast.JsParameter; -import com.google.dart.compiler.backend.js.ast.JsPrefixOperation; -import com.google.dart.compiler.backend.js.ast.JsScope; -import com.google.dart.compiler.backend.js.ast.JsStatement; -import com.google.dart.compiler.backend.js.ast.JsSwitch; -import com.google.dart.compiler.backend.js.ast.JsSwitchMember; -import com.google.dart.compiler.backend.js.ast.JsUnaryOperator; -import com.google.dart.compiler.backend.js.ast.JsVars; -import com.google.dart.compiler.backend.js.ast.JsVars.JsVar; -import com.google.dart.compiler.common.SourceInfo; - -/** - * @author johnlenz@google.com (John Lenz) - */ -public class AstUtil { - - public static JsInvocation newInvocation( - JsExpression target, JsExpression ... params) { - JsInvocation invoke = new JsInvocation(); - invoke.setQualifier(target); - for (JsExpression expr : params) { - invoke.getArguments().add(expr); - } - return invoke; - } - - public static JsNameRef newQualifiedNameRef(String name) { - JsNameRef node = null; - int endPos = -1; - int startPos = 0; - do { - endPos = name.indexOf('.', startPos); - String part = (endPos == -1 - ? name.substring(startPos) - : name.substring(startPos, endPos)); - node = newNameRef(node, part); - startPos = endPos + 1; - } while (endPos != -1); - - return node; - } - - public static JsNameRef newNameRef(JsExpression qualifier, String prop) { - JsNameRef nameRef = new JsNameRef(prop); - if (qualifier != null) { - nameRef.setQualifier(qualifier); - } - return nameRef; - } - - public static JsNameRef nameref(SourceInfo info, JsName qualifier, JsName prop) { - JsNameRef nameRef = new JsNameRef(prop); - if (qualifier != null) { - nameRef.setQualifier(qualifier.makeRef()); - } - nameRef.setSourceRef(info); - return nameRef; - } - - public static JsNameRef newNameRef(JsExpression qualifier, JsName prop) { - JsNameRef nameRef = new JsNameRef(prop); - if (qualifier != null) { - nameRef.setQualifier(qualifier); - } - return nameRef; - } - - public static JsNameRef newPrototypeNameRef(JsExpression qualifier) { - return newNameRef(qualifier, "prototype"); - } - - public static JsArrayAccess newArrayAccess(JsExpression target, JsExpression key) { - JsArrayAccess arr = new JsArrayAccess(); - arr.setArrayExpr(target); - arr.setIndexExpr(key); - return arr; - } - - public static JsBlock newBlock(JsStatement ... stmts) { - JsBlock jsBlock = new JsBlock(); - for (JsStatement stmt : stmts) { - jsBlock.getStatements().add(stmt); - } - return jsBlock; - } - - /** - * Returns a sequence of expressions (using the binary sequence operator). - * @param exprs - expressions to add to sequence - * @return a sequence of expressions. - */ - public static JsBinaryOperation newSequence(JsExpression ... exprs) { - if (exprs.length < 2) { - throw new InternalCompilerException("newSequence expects at least two arguments"); - } - JsExpression result = exprs[exprs.length - 1]; - for (int i = exprs.length - 2; i >= 0; i--) { - result = new JsBinaryOperation(JsBinaryOperator.COMMA, exprs[i], result); - } - return (JsBinaryOperation) result; - } - - // Ensure a valid LHS - public static JsBinaryOperation newAssignment( - JsNameRef nameRef, JsExpression expr) { - return new JsBinaryOperation(JsBinaryOperator.ASG, nameRef, expr); - } - - public static JsBinaryOperation newAssignment( - JsArrayAccess target, JsExpression expr) { - return new JsBinaryOperation(JsBinaryOperator.ASG, target, expr); - } - - public static JsVars newVar(SourceInfo info, JsName name, JsExpression expr) { - JsVar var = new JsVar(name).setSourceRef(info); - var.setInitExpr(expr); - JsVars vars = new JsVars(); - vars.add(var); - return vars; - } - - public static JsSwitch newSwitch( - JsExpression expr, JsSwitchMember ... cases) { - JsSwitch jsSwitch = new JsSwitch(); - jsSwitch.setExpr(expr); - for (JsSwitchMember jsCase : cases) { - jsSwitch.getCases().add(jsCase); - } - return jsSwitch; - } - - public static JsCase newCase(JsExpression expr, JsStatement ... stmts) { - JsCase jsCase = new JsCase(); - jsCase.setCaseExpr(expr); - for (JsStatement stmt : stmts) { - jsCase.getStmts().add(stmt); - } - return jsCase; - } - - public static JsDefault newDefaultCase(JsStatement ... stmts) { - JsDefault jsCase = new JsDefault(); - for (JsStatement stmt : stmts) { - jsCase.getStmts().add(stmt); - } - return jsCase; - } - - public static JsFunction newFunction( - JsScope scope, JsName name, JsParameter[] params, JsStatement ... stmts) { - JsFunction fn = new JsFunction(scope); - if (name != null) { - fn.setName(name); - } - if (params != null) { - for (JsParameter param : params) { - fn.getParameters().add(param); - } - } - fn.setBody(newBlock(stmts)); - return fn; - } - - public static JsInvocation call(SourceInfo src, JsExpression target, JsExpression ... params) { - return (JsInvocation) newInvocation(target, params).setSourceRef(src); - } - - public static JsBinaryOperation comma(SourceInfo src, JsExpression op1, JsExpression op2) { - return (JsBinaryOperation)new JsBinaryOperation(JsBinaryOperator.COMMA, op1, op2) - .setSourceRef(src); - } - - public static JsNameRef nameref(SourceInfo src, String name) { - return (JsNameRef) new JsNameRef(name).setSourceRef(src); - } - - public static JsNameRef nameref(SourceInfo src, JsName qualifier, String prop) { - return AstUtil.nameref(src, qualifier.makeRef().setSourceRef(src), prop); - } - - public static JsNameRef nameref(SourceInfo src, JsExpression qualifier, String prop) { - return (JsNameRef) newNameRef(qualifier, prop).setSourceRef(src); - } - - public static JsExpression assign(SourceInfo src, JsNameRef op1, JsExpression op2) { - return newAssignment(op1, op2).setSourceRef(src); - } - - public static JsExpression neq(SourceInfo src, JsExpression op1, JsExpression op2) { - return new JsBinaryOperation(JsBinaryOperator.NEQ, op1, op2).setSourceRef(src); - } - - public static JsExpression not(SourceInfo src, JsExpression op1) { - return new JsPrefixOperation(JsUnaryOperator.NOT, op1).setSourceRef(src); - } - - public static JsExpression preinc(SourceInfo src, JsExpression op1) { - return new JsPrefixOperation(JsUnaryOperator.INC, op1).setSourceRef(src); - } - - public static JsExpression and(SourceInfo src, JsExpression op1, JsExpression op2) { - return new JsBinaryOperation(JsBinaryOperator.AND, op1, op2).setSourceRef(src); - } - - public static JsExpression in(SourceInfo src, JsExpression propName, JsExpression obj) { - return new JsBinaryOperation(JsBinaryOperator.INOP, propName, obj).setSourceRef(src); - } -} diff --git a/compiler/javatests/com/google/dart/compiler/CompilerTestCase.java b/compiler/javatests/com/google/dart/compiler/CompilerTestCase.java index e6f949dc8f8..2affb905cfa 100644 --- a/compiler/javatests/com/google/dart/compiler/CompilerTestCase.java +++ b/compiler/javatests/com/google/dart/compiler/CompilerTestCase.java @@ -44,11 +44,6 @@ public abstract class CompilerTestCase extends TestCase { */ protected static final CompilerConfiguration CHECK_ONLY_CONFIGURATION = new DefaultCompilerConfiguration(new CompilerOptions()) { - @Override - public boolean checkOnly() { - return true; - } - @Override public boolean incremental() { return true; @@ -211,14 +206,14 @@ public abstract class CompilerTestCase extends TestCase { } /** - * Compiles a single unit with a synthesized application, using the specified backend. + * Compiles a single unit with a synthesized application. */ protected DartSource compileSingleUnit(String name, String code, - DartArtifactProvider provider, Backend backend) throws IOException { + DartArtifactProvider provider) throws IOException { MockLibrarySource lib = new MockLibrarySource(); DartSourceTest src = new DartSourceTest(name, code, lib); lib.addSource(src); - CompilerConfiguration config = getCompilerConfiguration(backend); + CompilerConfiguration config = getCompilerConfiguration(); DartCompilerListener listener = new DartCompilerListenerTest(src.getName()); DartCompiler.compileLib(lib, config, provider, listener); return src; @@ -227,8 +222,8 @@ public abstract class CompilerTestCase extends TestCase { /** * Allow tests to override the configuration used. */ - protected CompilerConfiguration getCompilerConfiguration(Backend backend) { - return new DefaultCompilerConfiguration(backend); + protected CompilerConfiguration getCompilerConfiguration() { + return new DefaultCompilerConfiguration(); } /** diff --git a/compiler/javatests/com/google/dart/compiler/MockArtifactProvider.java b/compiler/javatests/com/google/dart/compiler/MockArtifactProvider.java index 8291dc89cc8..bb2d534bd76 100644 --- a/compiler/javatests/com/google/dart/compiler/MockArtifactProvider.java +++ b/compiler/javatests/com/google/dart/compiler/MockArtifactProvider.java @@ -9,7 +9,6 @@ import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import java.net.URI; -import java.util.Date; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -46,7 +45,7 @@ public class MockArtifactProvider extends DartArtifactProvider { public Writer getArtifactWriter(Source source, String part, String ext) { Artifact artifact = new Artifact(); artifacts.put(keyFor(source, part, ext), artifact); - artifact.lastModified = new Date().getTime(); + artifact.lastModified = System.currentTimeMillis(); return artifact.writer; } diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testArrayIncompatibleArrayOperator.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testArrayIncompatibleArrayOperator.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testArrayIncompatibleArrayOperator.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testCombinedExpressions.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testCombinedExpressions.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testCombinedExpressions.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleBinaryOp.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleBinaryOp.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleBinaryOp.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleFields.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleFields.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleFields.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleMethods.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleMethods.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testCompatibleMethods.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleBinaryOp1.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleBinaryOp1.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleBinaryOp1.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleBinaryOp2.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleBinaryOp2.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleBinaryOp2.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFields.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFields.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFields.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFields2.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFields2.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFields2.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFieldsWithGetter.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFieldsWithGetter.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFieldsWithGetter.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFieldsWithSetter.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFieldsWithSetter.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleFieldsWithSetter.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleLogicalOp.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleLogicalOp.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleLogicalOp.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleMethods.dart b/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleMethods.dart deleted file mode 100644 index 6ce73110b96..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/common/testIncompatibleMethods.dart +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/ComparingVisitor.java b/compiler/javatests/com/google/dart/compiler/backend/js/ComparingVisitor.java deleted file mode 100644 index 36085b3b0e0..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/ComparingVisitor.java +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.FlatteningVisitor.TreeNode; -import com.google.dart.compiler.backend.js.ast.JsArrayAccess; -import com.google.dart.compiler.backend.js.ast.JsArrayLiteral; -import com.google.dart.compiler.backend.js.ast.JsBinaryOperation; -import com.google.dart.compiler.backend.js.ast.JsBlock; -import com.google.dart.compiler.backend.js.ast.JsBooleanLiteral; -import com.google.dart.compiler.backend.js.ast.JsBreak; -import com.google.dart.compiler.backend.js.ast.JsCase; -import com.google.dart.compiler.backend.js.ast.JsCatch; -import com.google.dart.compiler.backend.js.ast.JsConditional; -import com.google.dart.compiler.backend.js.ast.JsContext; -import com.google.dart.compiler.backend.js.ast.JsContinue; -import com.google.dart.compiler.backend.js.ast.JsDebugger; -import com.google.dart.compiler.backend.js.ast.JsDefault; -import com.google.dart.compiler.backend.js.ast.JsDoWhile; -import com.google.dart.compiler.backend.js.ast.JsEmpty; -import com.google.dart.compiler.backend.js.ast.JsExprStmt; -import com.google.dart.compiler.backend.js.ast.JsFor; -import com.google.dart.compiler.backend.js.ast.JsForIn; -import com.google.dart.compiler.backend.js.ast.JsFunction; -import com.google.dart.compiler.backend.js.ast.JsIf; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsLabel; -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.google.dart.compiler.backend.js.ast.JsNew; -import com.google.dart.compiler.backend.js.ast.JsNullLiteral; -import com.google.dart.compiler.backend.js.ast.JsNumberLiteral; -import com.google.dart.compiler.backend.js.ast.JsObjectLiteral; -import com.google.dart.compiler.backend.js.ast.JsParameter; -import com.google.dart.compiler.backend.js.ast.JsPostfixOperation; -import com.google.dart.compiler.backend.js.ast.JsPrefixOperation; -import com.google.dart.compiler.backend.js.ast.JsProgram; -import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer; -import com.google.dart.compiler.backend.js.ast.JsRegExp; -import com.google.dart.compiler.backend.js.ast.JsReturn; -import com.google.dart.compiler.backend.js.ast.JsStatement; -import com.google.dart.compiler.backend.js.ast.JsStringLiteral; -import com.google.dart.compiler.backend.js.ast.JsSwitch; -import com.google.dart.compiler.backend.js.ast.JsThisRef; -import com.google.dart.compiler.backend.js.ast.JsThrow; -import com.google.dart.compiler.backend.js.ast.JsTry; -import com.google.dart.compiler.backend.js.ast.JsVars; -import com.google.dart.compiler.backend.js.ast.JsVars.JsVar; -import com.google.dart.compiler.backend.js.ast.JsVisitable; -import com.google.dart.compiler.backend.js.ast.JsVisitor; -import com.google.dart.compiler.backend.js.ast.JsWhile; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import java.util.List; - -class ComparingVisitor extends JsVisitor { - - public static void exec(List expected, List actual) { - TreeNode expectedTree = FlatteningVisitor.exec(expected); - TreeNode actualTree = FlatteningVisitor.exec(actual); - compare(expectedTree, actualTree); - } - - private static void compare(JsVisitable expected, JsVisitable actual) { - if (expected == actual) { - return; - } - Assert.assertNotNull(expected); - Assert.assertNotNull(actual); - ComparingVisitor visitor = new ComparingVisitor(expected); - visitor.accept(actual); - } - - private static void compare(TreeNode expected, TreeNode actual) { - compare(expected.node, actual.node); - List expectedChildren = expected.children; - List actualChildren = actual.children; - Assert.assertEquals(expectedChildren.size(), actualChildren.size()); - for (int i = 0; i < expectedChildren.size(); i++) { - compare(expectedChildren.get(i), actualChildren.get(i)); - } - } - - /** - * We use a raw type here because Sun's javac will barf all over the casts and - * instanceof tests we do all throughout this file. - */ - private final JsVisitable other; - - private ComparingVisitor(JsVisitable other) { - this.other = other; - } - - @Override - public boolean visit(JsArrayAccess x, JsContext ctx) { - Assert.assertTrue(other instanceof JsArrayAccess); - return false; - } - - @Override - public boolean visit(JsArrayLiteral x, JsContext ctx) { - Assert.assertTrue(other instanceof JsArrayLiteral); - return false; - } - - @Override - public boolean visit(JsBinaryOperation x, JsContext ctx) { - Assert.assertTrue(other instanceof JsBinaryOperation); - Assert.assertEquals(((JsBinaryOperation) other).getOperator().getSymbol(), - x.getOperator().getSymbol()); - return false; - } - - @Override - public boolean visit(JsBlock x, JsContext ctx) { - Assert.assertTrue(other instanceof JsBlock); - Assert.assertEquals(((JsBlock) other).isGlobalBlock(), x.isGlobalBlock()); - return false; - } - - @Override - public boolean visit(JsBooleanLiteral x, JsContext ctx) { - Assert.assertTrue(other instanceof JsBooleanLiteral); - Assert.assertEquals(((JsBooleanLiteral) other).getValue(), x.getValue()); - return false; - } - - @Override - public boolean visit(JsBreak x, JsContext ctx) { - Assert.assertTrue(other instanceof JsBreak); - Assert.assertEquals(((JsBreak) other).getLabel().getIdent(), x.getLabel().getIdent()); - return false; - } - - @Override - public boolean visit(JsCase x, JsContext ctx) { - Assert.assertTrue(other instanceof JsCase); - return false; - } - - @Override - public boolean visit(JsCatch x, JsContext ctx) { - Assert.assertTrue(other instanceof JsCatch); - Assert.assertEquals(((JsCatch) other).getParameter().getName().getIdent(), - x.getParameter().getName().getIdent()); - return false; - } - - @Override - public boolean visit(JsConditional x, JsContext ctx) { - Assert.assertTrue(other instanceof JsConditional); - return false; - } - - @Override - public boolean visit(JsContinue x, JsContext ctx) { - Assert.assertTrue(other instanceof JsContinue); - Assert.assertEquals(((JsContinue) other).getLabel().getIdent(), x.getLabel().getIdent()); - return false; - } - - @Override - public boolean visit(JsDebugger x, JsContext ctx) { - Assert.assertTrue(other instanceof JsDebugger); - return false; - } - - @Override - public boolean visit(JsDefault x, JsContext ctx) { - Assert.assertTrue(other instanceof JsDefault); - return false; - } - - @Override - public boolean visit(JsDoWhile x, JsContext ctx) { - Assert.assertTrue(other instanceof JsDoWhile); - return false; - } - - @Override - public boolean visit(JsEmpty x, JsContext ctx) { - Assert.assertTrue(other instanceof JsEmpty); - return false; - } - - @Override - public boolean visit(JsExprStmt x, JsContext ctx) { - Assert.assertTrue(other instanceof JsExprStmt); - return false; - } - - @Override - public boolean visit(JsFor x, JsContext ctx) { - Assert.assertTrue(other instanceof JsFor); - return false; - } - - @Override - public boolean visit(JsForIn x, JsContext ctx) { - Assert.assertTrue(other instanceof JsForIn); - return false; - } - - @Override - public boolean visit(JsFunction x, JsContext ctx) { - Assert.assertTrue(other instanceof JsFunction); - JsFunction otherFunc = (JsFunction) other; - JsName otherName = otherFunc.getName(); - JsName name = x.getName(); - if (name != otherName) { - Assert.assertEquals(otherName.getIdent(), name.getIdent()); - } - return false; - } - - @Override - public boolean visit(JsIf x, JsContext ctx) { - Assert.assertTrue(other instanceof JsIf); - return false; - } - - @Override - public boolean visit(JsInvocation x, JsContext ctx) { - Assert.assertTrue(other instanceof JsInvocation); - return false; - } - - @Override - public boolean visit(JsLabel x, JsContext ctx) { - Assert.assertTrue(other instanceof JsLabel); - Assert.assertEquals(((JsLabel) other).getName().getIdent(), x.getName().getIdent()); - return false; - } - - @Override - public boolean visit(JsNameRef x, JsContext ctx) { - Assert.assertTrue(other instanceof JsNameRef); - Assert.assertEquals(((JsNameRef) other).getIdent(), x.getIdent()); - return false; - } - - @Override - public boolean visit(JsNew x, JsContext ctx) { - Assert.assertTrue(other instanceof JsNew); - return false; - } - - @Override - public boolean visit(JsNullLiteral x, JsContext ctx) { - Assert.assertTrue(other instanceof JsNullLiteral); - return false; - } - - @Override - public boolean visit(JsNumberLiteral x, JsContext ctx) { - Assert.assertTrue(other instanceof JsNumberLiteral); - Assert.assertEquals(((JsNumberLiteral) other).getValue(), x.getValue()); - return false; - } - - @Override - public boolean visit(JsObjectLiteral x, JsContext ctx) { - Assert.assertTrue(other instanceof JsObjectLiteral); - return false; - } - - @Override - public boolean visit(JsParameter x, JsContext ctx) { - Assert.assertTrue(other instanceof JsParameter); - Assert.assertEquals(((JsParameter) other).getName().getIdent(), x.getName().getIdent()); - return false; - } - - @Override - public boolean visit(JsPostfixOperation x, JsContext ctx) { - Assert.assertTrue(other instanceof JsPostfixOperation); - Assert.assertEquals(((JsPostfixOperation) other).getOperator().getSymbol(), - x.getOperator().getSymbol()); - return false; - } - - @Override - public boolean visit(JsPrefixOperation x, JsContext ctx) { - Assert.assertTrue(other instanceof JsPrefixOperation); - Assert.assertEquals(((JsPrefixOperation) other).getOperator().getSymbol(), - x.getOperator().getSymbol()); - return false; - } - - @Override - public boolean visit(JsProgram x, JsContext ctx) { - Assert.assertTrue(other instanceof JsProgram); - return false; - } - - @Override - public boolean visit(JsPropertyInitializer x, JsContext ctx) { - Assert.assertTrue(other instanceof JsPropertyInitializer); - return false; - } - - @Override - public boolean visit(JsRegExp x, JsContext ctx) { - Assert.assertTrue(other instanceof JsRegExp); - Assert.assertEquals(((JsRegExp) other).getFlags(), x.getFlags()); - Assert.assertEquals(((JsRegExp) other).getPattern(), x.getPattern()); - return false; - } - - @Override - public boolean visit(JsReturn x, JsContext ctx) { - Assert.assertTrue(other instanceof JsReturn); - return false; - } - - @Override - public boolean visit(JsStringLiteral x, JsContext ctx) { - Assert.assertTrue(other instanceof JsStringLiteral); - Assert.assertEquals(((JsStringLiteral) other).getValue(), x.getValue()); - return false; - } - - @Override - public boolean visit(JsSwitch x, JsContext ctx) { - Assert.assertTrue(other instanceof JsSwitch); - return false; - } - - @Override - public boolean visit(JsThisRef x, JsContext ctx) { - Assert.assertTrue(other instanceof JsThisRef); - return false; - } - - @Override - public boolean visit(JsThrow x, JsContext ctx) { - Assert.assertTrue(other instanceof JsThrow); - return false; - } - - @Override - public boolean visit(JsTry x, JsContext ctx) { - Assert.assertTrue(other instanceof JsTry); - return false; - } - - @Override - public boolean visit(JsVar x, JsContext ctx) { - TestCase.assertTrue(other instanceof JsVar); - TestCase.assertEquals(((JsVar) other).getName().getIdent(), x.getName().getIdent()); - return false; - } - - public boolean visit(JsVars x, JsContext ctx) { - TestCase.assertTrue(other instanceof JsVars); - return false; - } - - public boolean visit(JsWhile x, JsContext ctx) { - TestCase.assertTrue(other instanceof JsWhile); - return false; - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/FlatteningVisitor.java b/compiler/javatests/com/google/dart/compiler/backend/js/FlatteningVisitor.java deleted file mode 100644 index b50515ad024..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/FlatteningVisitor.java +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.ast.JsStatement; -import com.google.dart.compiler.backend.js.ast.JsVisitable; -import com.google.dart.compiler.backend.js.ast.JsVisitor; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -class FlatteningVisitor extends JsVisitor { - - public static TreeNode exec(List statements) { - FlatteningVisitor visitor = new FlatteningVisitor(); - visitor.acceptList(statements); - return visitor.root; - } - - public static class TreeNode { - public final JsVisitable node; - public final List children = new ArrayList(); - - public TreeNode(JsVisitable node) { - this.node = node; - } - } - - private TreeNode root; - - private FlatteningVisitor() { - root = new TreeNode(null); - } - - protected T doAccept(T node) { - TreeNode oldRoot = root; - root = new TreeNode(node); - oldRoot.children.add(root); - super.doAccept(node); - root = oldRoot; - return node; - } - - // @Override - protected void doAcceptList(List collection) { - for (Iterator it = collection.iterator(); it.hasNext();) { - doAccept(it.next()); - } - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/JavaScriptStringTest.java b/compiler/javatests/com/google/dart/compiler/backend/js/JavaScriptStringTest.java deleted file mode 100644 index 0d592d3200a..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/JavaScriptStringTest.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import junit.framework.TestCase; - -import org.mozilla.javascript.Node; -import org.mozilla.javascript.Parser; -import org.mozilla.javascript.Token; -import org.mozilla.javascript.ast.AstNode; -import org.mozilla.javascript.ast.ExpressionStatement; -import org.mozilla.javascript.ast.StringLiteral; - -import java.io.IOException; -import java.io.StringReader; - -/** - * Tests {@link JsToStringGenerationVisitor#javaScriptString(String)}. - */ -public class JavaScriptStringTest extends TestCase { - private void test(String original) throws IOException { - String escaped = JsToStringGenerationVisitor.javaScriptString(original); - - // Parse it back - Parser parser = new Parser(); - AstNode node = parser.parse(new StringReader(escaped), "virtual file", 1); - assertEquals(Token.SCRIPT, node.getType()); - Node exprResult = node.getFirstChild(); - assertEquals(Token.EXPR_RESULT, node.getFirstChild().getType()); - ExpressionStatement exprStatement = (ExpressionStatement) node.getFirstChild(); - assertEquals(Token.STRING, exprStatement.getExpression().getType()); - StringLiteral stringLiteral = (StringLiteral) exprStatement.getExpression(); - assertEquals(original, stringLiteral.getValue()); - - // It should be the only token - assertNull(node.getNext()); - } - - public void testBasic() throws IOException { - test("abc"); - test(""); - test("abc\0def"); - test("abc\\def"); - test("\u00CC\u1234\5678\uabcd"); - test("'''"); - test("\"\"\""); - test("\b\f\n\r\t"); - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/JsScopeTest.java b/compiler/javatests/com/google/dart/compiler/backend/js/JsScopeTest.java deleted file mode 100644 index a179b33d4e1..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/JsScopeTest.java +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsRootScope; -import com.google.dart.compiler.backend.js.ast.JsScope; - -import junit.framework.TestCase; - -/** - * Tests {@link JsScope} and {@link JsName}. - */ -public class JsScopeTest extends TestCase { - public void testRootScope() { - JsScope scope = new JsRootScope(null); - JsName name = scope.declareName("foo"); - assertSame(name, scope.findExistingName("foo")); - assertTrue("foo".equals(name.getOriginalName())); - JsName name2 = scope.declareName("foo"); - assertSame(name, name2); - - name = scope.declareName("bar"); - assertSame(name, scope.findExistingName("bar")); - assertTrue("bar".equals(name.getOriginalName())); - name2 = scope.declareName("bar"); - assertSame(name, name2); - - name = scope.declareName("false"); - assertTrue("false".equals(name.getIdent())); - assertTrue("false".equals(name.getShortIdent())); - assertTrue("false".equals(name.getOriginalName())); - } - - public void testJsNames() { - JsScope scope = new JsRootScope(null); - - JsName name = scope.declareName("foobar1"); - assertTrue("foobar1".equals(name.getIdent())); - assertTrue("foobar1".equals(name.getShortIdent())); - assertTrue("foobar1".equals(name.getOriginalName())); - - name = scope.declareName("foobar2", "foobar3"); - assertTrue("foobar2".equals(name.getIdent())); - assertTrue("foobar3".equals(name.getShortIdent())); - assertTrue("foobar2".equals(name.getOriginalName())); - - name = scope.declareName("foobar4", "foobar5", "foobar6"); - assertTrue("foobar4".equals(name.getIdent())); - assertTrue("foobar5".equals(name.getShortIdent())); - assertTrue("foobar6".equals(name.getOriginalName())); - } - - public void testNestedScope() { - JsScope rootScope = new JsRootScope(null); - JsScope scope = new JsScope(rootScope, "nested", "unitid"); - - // First the basic operations. - JsName name = scope.declareName("foo"); - assertSame(name, scope.findExistingName("foo")); - assertTrue("foo".equals(name.getOriginalName())); - JsName name2 = scope.declareName("foo"); - assertSame(name, name2); - name = scope.declareName("bar"); - assertSame(name, scope.findExistingName("bar")); - assertTrue("bar".equals(name.getOriginalName())); - name2 = scope.declareName("bar"); - assertSame(name, name2); - - // Test deep search. - name = rootScope.declareName("fisk"); - name2 = scope.findExistingName("fisk"); - assertSame(name, name2); - // Test shadowing. - name2 = scope.declareName("fisk"); - assertNotSame(name, name2); - assertTrue("fisk".equals(name2.getOriginalName())); - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/RttTest.java b/compiler/javatests/com/google/dart/compiler/backend/js/RttTest.java deleted file mode 100644 index 04c0458070c..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/RttTest.java +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -package com.google.dart.compiler.backend.js; - -import java.io.IOException; - -/** - * @author johnlenz@google.com (John Lenz) - */ -public class RttTest extends SnippetTestCase { - private static final String DELIMETERS = "[\\n,;]"; - - /** - * We should be able to generate RTT information for nested function parameters. - *

- * http://code.google.com/p/dart/issues/detail?id=962 - */ - public void test_nestedFunctionParameters() throws Exception { - String js = - compileSingleUnitSource( - makeCode( - "// filler filler filler filler filler filler filler filler filler filler", - "class Main {", - " foo() {", - " f1(f2(f3())) {}", - " }", - "}", - ""), - "Main"); - { - String f3 = "RTT.createFunction(null, RTT.dynamicType.$lookupRTT())"; - String f2 = "RTT.createFunction([" + f3 + "], RTT.dynamicType.$lookupRTT())"; - String f1 = "RTT.createFunction([" + f2 + "], RTT.dynamicType.$lookupRTT())"; - assertTrue(js.contains(f1 + ";")); - } - } - - public void testRuntimeTypes() throws IOException { - String js = compileSingleUnit(getName()); - { - String init = findMarkerAtOccurrence(js, "_marker_B1", DELIMETERS, 1); - assertEquals("var _marker_B1 = $intern(Test_app4a54ba$B$Dart.B$$Factory())", init); - String expr = findMarkerAtOccurrence(js, "_marker_B1", "[\\n;]", 2); - assertEquals( - "a = !!(tmp$0 = _marker_B1 , tmp$0 != null && tmp$0.$implements$Test_app4a54ba$B$Dart)", - expr); - } - { - String init = findMarkerAtOccurrence(js, "_marker_B2", DELIMETERS, 1); - assertEquals("var _marker_B2 = Test_app4a54ba$B$Dart.B$$Factory()", init); - } - { - String init = findMarkerAtOccurrence(js, "_marker_C1", DELIMETERS, 1); - assertEquals("var _marker_C1 = $intern(" - + "Test_app4a54ba$C$Dart.C$$Factory(" - + "Test_app4a54ba$C$Dart.$lookupRTT())", init); - String expr = findMarkerAtOccurrence(js, "_marker_C1", "[\\n;]", 2); - assertEquals( - "a = !!(tmp$1 = _marker_C1 , tmp$1 != null && tmp$1.$implements$Test_app4a54ba$C$Dart)", - expr); - } - { - String init = findMarkerAtOccurrence(js, "_marker_C2", DELIMETERS, 1); - assertEquals("var _marker_C2 = $intern(Test_app4a54ba$C$Dart.C$$Factory(" - + "Test_app4a54ba$C$Dart.$lookupRTT([String$Dart.$lookupRTT()]))", init); - String expr = findMarkerAtOccurrence(js, "_marker_C2", DELIMETERS, 2); - assertEquals("a = Test_app4a54ba$C$Dart.$lookupRTT([String$Dart.$lookupRTT()])" - + ".implementedBy(_marker_C2)", expr); - } - { - String init = findMarkerAtOccurrence(js, "_marker_C3", DELIMETERS, 1); - assertEquals("var _marker_C3 = " - + "Test_app4a54ba$C$Dart.C$$Factory(" - + "Test_app4a54ba$C$Dart.$lookupRTT())", init); - } - { - String init = findMarkerAtOccurrence(js, "_marker_C4", DELIMETERS, 1); - assertEquals("var _marker_C4 = " - + "Test_app4a54ba$C$Dart.C$$Factory(" - + "Test_app4a54ba$C$Dart.$lookupRTT([Object.$lookupRTT()]))", init); - String expr = findMarkerAtOccurrence(js, "_marker_C4", DELIMETERS, 2); - assertEquals("a = Test_app4a54ba$C$Dart.$lookupRTT([Object.$lookupRTT()])" - + ".implementedBy(_marker_C4)", expr); - } - { - String init = findMarkerAtOccurrence(js, "_marker_D1", DELIMETERS, 1); - assertEquals("var _marker_D1 = Test_app4a54ba$D$Dart.D$$Factory(null)", init); - String expr = findMarkerAtOccurrence(js, "_marker_D1", "[\\n;]", 2); - assertEquals( - "a = !!(tmp$2 = _marker_D1 , tmp$2 != null && tmp$2.$implements$Test_app4a54ba$D$Dart)", - expr); - } - { - String init = findMarkerAtOccurrence(js, "_marker_D2", DELIMETERS, 1); - assertEquals( - "var _marker_D2 = Test_app4a54ba$D$Dart.D$$Factory([String$Dart.$lookupRTT()])", - init); - String expr = findMarkerAtOccurrence(js, "_marker_D2", "[\\n;]", 2); - assertEquals( - "a = Test_app4a54ba$D$Dart.$lookupRTT([String$Dart.$lookupRTT()]).implementedBy(_marker_D2)", - expr); - } - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/SnippetTestCase.java b/compiler/javatests/com/google/dart/compiler/backend/js/SnippetTestCase.java deleted file mode 100644 index 157fad9a96e..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/SnippetTestCase.java +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js; - -import com.google.common.base.Strings; -import com.google.dart.compiler.CommandLineOptions.CompilerOptions; -import com.google.dart.compiler.CompilerConfiguration; -import com.google.dart.compiler.CompilerTestCase; -import com.google.dart.compiler.DartCompiler; -import com.google.dart.compiler.DartCompilerListenerTest; -import com.google.dart.compiler.DartSourceTest; -import com.google.dart.compiler.DefaultCompilerConfiguration; -import com.google.dart.compiler.MockArtifactProvider; -import com.google.dart.compiler.MockLibrarySource; - -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -/** - * Tests for binary expression optimizations. - */ -public abstract class SnippetTestCase extends CompilerTestCase { - - private static final String MARKER = "_marker_"; - - private MockArtifactProvider provider = new MockArtifactProvider(); - private JavascriptBackend jsBackend = new JavascriptBackend(); - protected AbstractJsBackend getBackend() { - return jsBackend; - } - - @Override - protected void tearDown() throws Exception { - provider = null; - jsBackend = null; - super.tearDown(); - } - - protected String compileSingleUnit(String filePath) throws IOException { - return compileSingleUnit(filePath, "Main"); - } - - protected String compileSingleUnit(String filePath, String part) throws IOException { - URL url = inputUrlFor(getClass(), filePath + ".dart"); - String source = readUrl(url); - return compileSingleUnitSource(source, part); - } - - protected String compileSingleUnitSource(String source, String part) throws IOException { - MockLibrarySource lib = new MockLibrarySource(); - DartSourceTest src = new DartSourceTest("test", source, lib); - lib.addSource(src); - CompilerOptions options = new CompilerOptions(); - CompilerConfiguration config = new DefaultCompilerConfiguration(this.getBackend(), options); - DartCompilerListenerTest listener = new DartCompilerListenerTest(src.getName()); - DartCompiler.compileLib(lib, config, provider, listener); - listener.checkAllErrorsReported(); - return provider.getArtifactString(src, part, JavascriptBackend.EXTENSION_JS); - } - - protected List findMarkerLines(String js) { - assertNotNull(js); - List lines = new ArrayList(); - - int begin = 0; - int end = 0; - while (true) { - begin = js.indexOf(MARKER, begin); - if (begin < 0) { - break; - } - end = js.indexOf(';', begin); - if (end > begin) { - lines.add(js.substring(begin + MARKER.length(), end)); - } - begin = end; - } - - return lines; - } - - /** - * Returns the specified occurence of the marker string inside of the JS code or null if there is - * none. Note that this method may miss the text around the specified occurence of the marker. - */ - protected String findMarkerAtOccurrence(String js, String marker, int occurrence) { - int begin = 0; - int end = 0; - int nOccurrence = 0; - while (true) { - begin = js.indexOf(marker, begin); - if (begin < 0) { - break; - } - nOccurrence++; - end = js.indexOf(';', begin); - if (end > begin && occurrence == nOccurrence) { - return js.substring(begin, end); - } - - begin = end; - } - - return null; - } - - /** - * Returns the specified occurrence of the marker string inside of the JS code by splitting the - * string using the specified regex and then locating the occurrence. This method allows you to - * control how much of the text around the marker occurence you are interested in. - */ - protected String findMarkerAtOccurrence(String js, String marker, String regEx, int occurrence) { - int iOccurrence = 0; - String[] strings = js.split(regEx); - for (int i = 0; i < strings.length; ++i) { - if (strings[i].indexOf(marker) != -1) { - if (++iOccurrence == occurrence) { - return strings[i].trim(); - } - } - } - return null; - } - - protected static String replaceTemps(String js) { - return Strings.isNullOrEmpty(js) ? "" : js.replaceAll("tmp\\$[0-9]+", "tmp"); - } - - protected String[] getFunctionBody(String name, String corpus) { - assertTrue(!Strings.isNullOrEmpty(name)); - int start = corpus.indexOf(name); - if (start == -1) { - return new String[0]; - } - int len = corpus.length(); - while (start < len && corpus.charAt(start) != '{') { - start++; - } - int end = start; - int count = 0; - while (end < len) { - if (corpus.charAt(end) == '{') - count++; - if (corpus.charAt(end) == '}') - count--; - end++; - if (count == 0) - break; - } - assert end >= start; - List result = new ArrayList(); - for (String s : corpus.substring(start, end).split("\\n")) { - if (s.equals("{") || s.equals("}")) - continue; - result.add(s.trim()); - } - return result.toArray(new String[0]); - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/analysis/DependencyComputerTest.java b/compiler/javatests/com/google/dart/compiler/backend/js/analysis/DependencyComputerTest.java deleted file mode 100644 index 595067c919c..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/analysis/DependencyComputerTest.java +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright 2011 Google Inc. All Rights Reserved. - -package com.google.dart.compiler.backend.js.analysis; - -import com.google.common.collect.Maps; - -import junit.framework.TestCase; - -import org.mozilla.javascript.Parser; -import org.mozilla.javascript.ast.AstNode; -import org.mozilla.javascript.ast.AstRoot; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - - -/** - * Tests that the dependency computer class reports dependencies correctly. - */ -public class DependencyComputerTest extends TestCase { - private Parser parser = new Parser(); - private Map> namesToElements = Maps.newHashMap(); - private List globals = new ArrayList(); - private TopLevelElementIndexer topLevelElementIndexer = new TopLevelElementIndexer( - namesToElements, globals); - private DependencyComputer dependencyComputer = new DependencyComputer(namesToElements); - - /** - * Tests that we don't add virtual dependencies for names that are shadowed by - * local variables. - */ - public void testLocalVariableShadowingOfMemberOfUninstantiatedClass() { - StringBuilder sb = new StringBuilder(); - sb.append("function A() {}\n"); - sb.append("A.prototype.foo = function() {}\n"); - sb.append("function B() {}\n"); - sb.append("B.prototype.foo = function() {}\n"); - sb.append("function execute() { var foo = 1; foo(); }"); - - AstRoot astRoot = parser.parse(sb.toString(), "", 1); - astRoot.visit(topLevelElementIndexer); - AstNode executeFunction = (AstNode) astRoot.getLastChild(); - List computedDependencies = - dependencyComputer.computeDependencies(executeFunction); - assertNotNull(computedDependencies); - - /* - * The foo inside of execute method should lexically resolve to the local - * variable hence foo() does not introduce a dependency on A.prototype.foo - * or B.prototype.foo. - */ - assertEquals(0, computedDependencies.size()); - } - - /** - * Tests that we can find dependencies to methods added to the prototype chain of native objects. - */ - public void testNativeDependencies() { - StringBuilder sb = new StringBuilder(); - sb.append("function A() {}\n"); - sb.append("A.prototype.foo = function() {}\n"); - sb.append("Array.prototype.foo = function() {}\n"); - sb.append("function execute() { Array.prototype.foo.call(); }"); - - AstRoot astRoot = parser.parse(sb.toString(), "", 1); - astRoot.visit(topLevelElementIndexer); - AstNode executeFunction = (AstNode) astRoot.getLastChild(); - List computedDependencies = - dependencyComputer.computeDependencies(executeFunction); - assertNotNull(computedDependencies); - - /* - * The foo method is added to the native Array object's prototype directly, ensure that we found - * it. - */ - assertEquals(1, computedDependencies.size()); - } - - /** - * Tests that we do add a virtual dependency to a member of an instantiated - * class even though its name is shadowed by a local variable. - */ - public void testLocalVariableShadowingOfMemberOfInstantiatedClass() { - StringBuilder sb = new StringBuilder(); - sb.append("function A() {}\n"); - sb.append("A.prototype.foo = function() {}\n"); - sb.append("function B() {}\n"); - sb.append("B.prototype.foo = function() {}\n"); - sb.append("function execute() { var foo = 1; new A(); this.foo(); }"); - - AstRoot astRoot = parser.parse(sb.toString(), "", 1); - astRoot.visit(topLevelElementIndexer); - AstNode executeFunction = (AstNode) astRoot.getLastChild(); - List computedDependencies = - dependencyComputer.computeDependencies(executeFunction); - assertNotNull(computedDependencies); - - /* - * The foo inside of execute method should lexically resolve to the local - * variable foo, but this.foo() introduces a dependency on A.prototype.foo since A is - * instantiated and foo is qualified. - */ - assertEquals(2, computedDependencies.size()); - } - - /** - * Tests that referencing a static method through only pulls in the static - * method and the enclosing function. - */ - public void testStaticReferencesToStaticMethods() { - StringBuilder sb = new StringBuilder(); - sb.append("function A() {}\n"); - sb.append("A.prototype.foo = function() {}\n"); - sb.append("function B() {}\n"); - sb.append("B.foo = function() {}\n"); - sb.append("function execute() { B.foo(); }"); - - AstRoot astRoot = parser.parse(sb.toString(), "", 1); - astRoot.visit(topLevelElementIndexer); - AstNode executeFunction = (AstNode) astRoot.getLastChild(); - List computedDependencies = - dependencyComputer.computeDependencies(executeFunction); - assertNotNull(computedDependencies); - - // Computed dependencies should be B and B.foo - assertEquals(2, computedDependencies.size()); - List list = new ArrayList(namesToElements.get("B")); - list.addAll(namesToElements.get("B.foo")); - assertEquals(list, computedDependencies); - } - - /** - * Tests that referencing a virtual method through a static reference doesn't - * introduce a virtual reference to the method. - */ - public void testStaticReferencesToVirtualMethods() { - StringBuilder sb = new StringBuilder(); - sb.append("function A() {}\n"); - sb.append("A.prototype.foo = function() {}\n"); - sb.append("function execute() { A.prototype.foo.call(this); }"); - AstRoot astRoot = parser.parse(sb.toString(), "", 1); - astRoot.visit(topLevelElementIndexer); - AstNode executeFunction = (AstNode) astRoot.getLastChild(); - List computedDependencies = - dependencyComputer.computeDependencies(executeFunction); - assertNotNull(computedDependencies); - assertEquals(1, computedDependencies.size()); - - // Static reference to A.prototype.foo - assertEquals(namesToElements.get("A.prototype.foo"), computedDependencies); - } - - /** - * Tests that referencing a virtual method only pulls in similarly named - * virtual methods on classes that have been instantiated.d - */ - public void testVirtualReferences() { - StringBuilder sb = new StringBuilder(); - sb.append("function A() {}\n"); - sb.append("A.prototype.foo = function() {}\n"); - sb.append("function B() {}\n"); - sb.append("B.prototype.foo = function() {}\n"); - sb.append("function execute() { new A(); foo(); }"); - - AstRoot astRoot = parser.parse(sb.toString(), "", 1); - astRoot.visit(topLevelElementIndexer); - AstNode executeFunction = (AstNode) astRoot.getLastChild(); - List computedDependencies = - dependencyComputer.computeDependencies(executeFunction); - assertNotNull(computedDependencies); - - /* - * Expect a dependency on A and A.prototype.foo, B was not instantiated so - * B.prototype.foo does not qualify - */ - assertEquals(2, computedDependencies.size()); - List list = new ArrayList(namesToElements.get("A")); - list.addAll(namesToElements.get("A.prototype.foo")); - assertEquals(list, computedDependencies); - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/analysis/JsAnalysisTests.java b/compiler/javatests/com/google/dart/compiler/backend/js/analysis/JsAnalysisTests.java deleted file mode 100644 index 8bc94baff08..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/analysis/JsAnalysisTests.java +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -package com.google.dart.compiler.backend.js.analysis; - -import junit.extensions.TestSetup; -import junit.framework.Test; -import junit.framework.TestSuite; - - -public class JsAnalysisTests extends TestSetup { - - public JsAnalysisTests(TestSuite test) { - super(test); - } - - public static Test suite() { - TestSuite suite = new TestSuite("Dart Javascript analysis test suite."); - - suite.addTestSuite(TopLevelElementIndexerTest.class); - suite.addTestSuite(DependencyComputerTest.class); - - return new JsAnalysisTests(suite); - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/analysis/TopLevelElementIndexerTest.java b/compiler/javatests/com/google/dart/compiler/backend/js/analysis/TopLevelElementIndexerTest.java deleted file mode 100644 index 1362935a97b..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/analysis/TopLevelElementIndexerTest.java +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright 2011 Google Inc. All Rights Reserved. - -package com.google.dart.compiler.backend.js.analysis; - -import com.google.common.collect.Maps; - -import junit.framework.TestCase; - -import org.mozilla.javascript.Parser; -import org.mozilla.javascript.Token; -import org.mozilla.javascript.ast.AstNode; -import org.mozilla.javascript.ast.AstRoot; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Tests how "top-level" elements are identified in Javascript code. - */ -public class TopLevelElementIndexerTest extends TestCase { - /** - * Tests that we can find top-level invocations to the RunEntry method to anchor the analysis. - */ - public void testGetEntryPoints() { - Parser parser = new Parser(); - AstRoot astRoot = parser.parse("function main() {} RunEntry(main)", "", 1); - Map> namesToElements = Maps.newHashMap(); - List globals = new ArrayList(); - TopLevelElementIndexer topLevelElementIndexer = - new TopLevelElementIndexer(namesToElements, globals); - - astRoot.visit(topLevelElementIndexer); - List entryPoints = topLevelElementIndexer.getEntryPoints(); - assertFalse(entryPoints.isEmpty()); - - // Assert that the entry point node is the "RunEntry(main) node. - assertEquals(astRoot.getLastChild(), entryPoints.get(0)); - } - - /** - * Tests that we don't find any entry point invocations. - */ - public void testGetEntryPointsEmpty() { - Parser parser = new Parser(); - AstRoot astRoot = parser.parse("function main() {}", "", 1); - Map> namesToElements = Maps.newHashMap(); - List globals = new ArrayList(); - TopLevelElementIndexer topLevelElementIndexer = - new TopLevelElementIndexer(namesToElements, globals); - astRoot.visit(topLevelElementIndexer); - List entryPoints = topLevelElementIndexer.getEntryPoints(); - assertTrue(entryPoints.isEmpty()); - } - - /** - * Test that we find global symbols. - */ - public void testGlobals() { - Parser parser = new Parser(); - AstRoot astRoot = parser.parse("if (true) {}", "", 1); - Map> namesToElements = Maps.newHashMap(); - List globals = new ArrayList(); - TopLevelElementIndexer topLevelElementIndexer = - new TopLevelElementIndexer(namesToElements, globals); - astRoot.visit(topLevelElementIndexer); - - // if (true) {} should not introduce a top level name and should be a global - assertTrue(namesToElements.isEmpty()); - - assertEquals(1, globals.size()); - } - - /** - * Checks that instance methods are associated with their parent and that their names appear - * as fully qualified "A.prototype.Hello" and virtually as "Hello". - */ - public void testInstanceFunctions() { - Parser parser = new Parser(); - AstRoot astRoot = parser.parse("function A() {} A.prototype.Hello = function(){}", "", 1); - Map> namesToElements = Maps.newHashMap(); - List globals = new ArrayList(); - TopLevelElementIndexer topLevelElementIndexer = - new TopLevelElementIndexer(namesToElements, globals); - astRoot.visit(topLevelElementIndexer); - - assertEquals(0, globals.size()); - // A, A.prototype.Hello and Hello - assertEquals(3, namesToElements.size()); - - List list = namesToElements.get("A"); - assertNotNull(list); - assertEquals(1, list.size()); - JavascriptElement a = list.get(0); - assertEquals(1, a.getMembers().size()); - - list = namesToElements.get("A.prototype.Hello"); - assertNotNull(list); - assertEquals(1, list.size()); - - JavascriptElement javascriptElement = list.get(0); - assertEquals(list.get(0), namesToElements.get("Hello").get(0)); - - assertNotNull(javascriptElement); - assertTrue(javascriptElement.isVirtual()); - AstNode node = javascriptElement.getNode(); - assertEquals(Token.EXPR_RESULT, node.getType()); - assertEquals(a, javascriptElement.getEnclosingElement()); - } - - /** - * Checks that static functions get associated with their parent. - */ - public void testStaticFunctions() { - Parser parser = new Parser(); - AstRoot astRoot = parser.parse("function A() {} A.Hello = function(){}", "", 1); - Map> namesToElements = Maps.newHashMap(); - List globals = new ArrayList(); - TopLevelElementIndexer topLevelElementIndexer = - new TopLevelElementIndexer(namesToElements, globals); - astRoot.visit(topLevelElementIndexer); - - assertEquals(0, globals.size()); - assertEquals(2, namesToElements.size()); - - List list = namesToElements.get("A"); - assertNotNull(list); - assertEquals(1, list.size()); - JavascriptElement a = list.get(0); - assertFalse(a.isVirtual()); - assertEquals(1, a.getMembers().size()); - - list = namesToElements.get("A.Hello"); - assertNotNull(list); - assertEquals(1, list.size()); - - JavascriptElement javascriptElement = list.get(0); - assertFalse(javascriptElement.isVirtual()); - - assertNotNull(javascriptElement); - AstNode node = javascriptElement.getNode(); - assertEquals(Token.EXPR_RESULT, node.getType()); - assertEquals(a, javascriptElement.getEnclosingElement()); - } - - public void testStaticFunctions2() { - Parser parser = new Parser(); - AstRoot astRoot = parser.parse("var A = new Object(); A.Hello = function(){}", "", 1); - Map> namesToElements = Maps.newHashMap(); - List globals = new ArrayList(); - TopLevelElementIndexer topLevelElementIndexer = - new TopLevelElementIndexer(namesToElements, globals); - astRoot.visit(topLevelElementIndexer); - - assertEquals(0, globals.size()); - assertEquals(2, namesToElements.size()); - - List list = namesToElements.get("A"); - assertNotNull(list); - assertEquals(1, list.size()); - JavascriptElement a = list.get(0); - assertFalse(a.isVirtual()); - assertEquals(1, a.getMembers().size()); - - list = namesToElements.get("A.Hello"); - assertNotNull(list); - assertEquals(1, list.size()); - - JavascriptElement javascriptElement = list.get(0); - assertFalse(javascriptElement.isVirtual()); - - assertNotNull(javascriptElement); - AstNode node = javascriptElement.getNode(); - assertEquals(Token.EXPR_RESULT, node.getType()); - assertEquals(a, javascriptElement.getEnclosingElement()); - } - - public void testTopLevelFunctions() { - Parser parser = new Parser(); - AstRoot astRoot = parser.parse("function Hello(){}", "", 1); - Map> namesToElements = Maps.newHashMap(); - List globals = new ArrayList(); - TopLevelElementIndexer topLevelElementIndexer = - new TopLevelElementIndexer(namesToElements, globals); - astRoot.visit(topLevelElementIndexer); - - assertEquals(0, globals.size()); - assertEquals(1, namesToElements.size()); - - List list = namesToElements.get("Hello"); - assertNotNull(list); - assertEquals(1, list.size()); - - JavascriptElement javascriptElement = list.get(0); - assertNotNull(javascriptElement); - assertEquals(Token.FUNCTION, javascriptElement.getNode().getType()); - } - - /** - * Tests that names that appear in a variable declaration map to the same node if they are in - * part of the same variable declaration. - */ - public void testVariables() { - Parser parser = new Parser(); - AstRoot astRoot = parser.parse("var A = 1, B = 2; var C;", "", 1); - Map> namesToElements = Maps.newHashMap(); - List globals = new ArrayList(); - TopLevelElementIndexer topLevelElementIndexer = - new TopLevelElementIndexer(namesToElements, globals); - astRoot.visit(topLevelElementIndexer); - - assertEquals(3, namesToElements.size()); - List a = namesToElements.get("A"); - List b = namesToElements.get("B"); - assertEquals(a.get(0).getNode(), b.get(0).getNode()); - - List c = namesToElements.get("C"); - assertEquals(1, c.size()); - assertNotSame(a.get(0).getNode(), c.get(0).getNode()); - } - - /** - * Tests that we handle "natives" correctly and that we associate virtual members with them. - */ - public void testNatives() { - Parser parser = new Parser(); - AstRoot astRoot = parser.parse("Array.prototype.foo = function() {}", "", 1); - Map> namesToElements = Maps.newHashMap(); - List globals = new ArrayList(); - TopLevelElementIndexer topLevelElementIndexer = - new TopLevelElementIndexer(namesToElements, globals); - astRoot.visit(topLevelElementIndexer); - - // Array (native), Array.prototype.foo, foo - assertEquals(3, namesToElements.size()); - - List list = namesToElements.get("Array"); - JavascriptElement javascriptElement = list.get(0); - assertTrue(javascriptElement.isNative()); - assertEquals(1, javascriptElement.getMembers().size()); - - List staticFoo = namesToElements.get("Array.prototype.foo"); - assertEquals(1, staticFoo.size()); - List virtualFoo = namesToElements.get("foo"); - assertEquals(1, virtualFoo.size()); - assertEquals(staticFoo.get(0), virtualFoo.get(0)); - assertTrue(virtualFoo.get(0).isVirtual()); - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/analysis/TreeShakerTest.java b/compiler/javatests/com/google/dart/compiler/backend/js/analysis/TreeShakerTest.java deleted file mode 100644 index 543ca4fa9f2..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/analysis/TreeShakerTest.java +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2011 Google Inc. All Rights Reserved. - -package com.google.dart.compiler.backend.js.analysis; - -import com.google.dart.compiler.DartCompilerContext; -import com.google.dart.compiler.LibrarySource; -import com.google.dart.compiler.MockLibrarySource; -import com.google.dart.compiler.Source; -import com.google.dart.compiler.testing.TestCompilerContext; - -import junit.framework.TestCase; - -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; - -/** - * Tests the JS based tree shaker used in incremental compilation. - */ -public class TreeShakerTest extends TestCase { - class MockCompilerContext extends TestCompilerContext { - private final String srcCode; - - public MockCompilerContext(String srcCode) { - this.srcCode = srcCode; - } - - @Override - public Reader getArtifactReader(Source source, String part, String extension) { - return new StringReader(srcCode); - } - } - - /** - * Tests that {@link TreeShaker#reduce(LibrarySource, DartCompilerContext, String, Writer)} can - * remove unused methods. - */ - public void testReduce() throws IOException { - StringBuffer inputSrc = new StringBuffer(); - inputSrc.append("function A() {}\n"); - inputSrc.append("A.prototype.foo = function(){}\n"); - inputSrc.append("function B() {}\n"); - inputSrc.append("B.prototype.foo = function(){}\n"); - inputSrc.append("function C() { A(); }\n"); - inputSrc.append("RunEntry(C);\n"); - - StringWriter outputCode = new StringWriter(); - - TreeShaker.reduce(new MockLibrarySource(), new MockCompilerContext(inputSrc.toString()), "", - outputCode); - - StringBuffer outputSrc = new StringBuffer(); - outputSrc.append("function A() {}\n"); - outputSrc.append("function C() { A(); }\n"); - outputSrc.append("RunEntry(C);\n"); - - assertEquals(outputSrc.toString(), outputCode.toString()); - } - - /** - * Tests that {@link TreeShaker#reduce(LibrarySource, DartCompilerContext, String, Writer)} can - * handle empty code. - */ - public void testReduceEmpty() throws IOException { - StringReader inputSrc = new StringReader(""); - StringWriter outputSrc = new StringWriter(); - TreeShaker.reduce(new MockLibrarySource(), new MockCompilerContext(""), "", outputSrc); - - assertEquals("", outputSrc.toString()); - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/testClosureOpt.dart b/compiler/javatests/com/google/dart/compiler/backend/js/testClosureOpt.dart deleted file mode 100644 index c94653582fc..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/testClosureOpt.dart +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -class A { - A(this.x); - - int x; - - testMethod(int arg1) { - int s1 = 1; - { - int s2 = 2; - { - int s3 = 3; - { - int s4 = 4; - - var _fn_0 = int _() => 0; // hoisted - - var _fn_1 = int _(p1) => p1; // hoisted - - var _fn_2 = int _(p1, p2) => p1 + p2; // hoisted - - var _fn_3 = int _(p1, p2, p3) => p1 + p2 + p3; // hoisted - - var _fn_4 = int _(p1, p2, p3, p4) => p1 + p2 + p3 + p4; // hoisted - - - var _fn_5 = int _() => s1; // bind 1-0 - - var _fn_6 = int _() => s1 + s2; // bind 2-0 - - var _fn_7 = int _() => s1 + s2 + s3; // bind 3-0 - - var _fn_8 = int _() => s1 + s2 + s3 + s4; // bind - - - var _fn_9 = int _(p1) => p1 + s1; // bind 1-1 - - var _fn_A = int _(p1, p2) => p1 + p2 + s1 + s2; // bind 2-2 - - var _fn_B = int _(p1, p2, p3) => p1 + p2 + p3 + s1 + s2 + s3; // bind 3-3 - - // bind - var _fn_C = int _(p1, p2, p3, p4) => p1 + p2 + p3 + p4 + s1 + s2 + s3 + s4; - - - // cannot inline - named args - var _fn_D = int _(p1, [n1 = 20]) => p1 + s1 + n1; - - var _fn_E = int _(p1) => p1 + s1 + this.x; - - var _fn_F = int _(p1) => p1 + s1 + arg1; - } - } - } - } -} - -class Main { - static void main() { - A a = new A(1); - a.testMethod(1); - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/testCompoundBinaryExprOpt.dart b/compiler/javatests/com/google/dart/compiler/backend/js/testCompoundBinaryExprOpt.dart deleted file mode 100644 index a39809d615c..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/testCompoundBinaryExprOpt.dart +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -class AAA { - AAA() { } - num AAAx_01; - num AAAx_02; - num AAAx_03; - num AAAx_04; - num AAAx_05; - num AAAx_06; - num AAAx_07; - - num AAAz_01; - num AAAz_02; - num AAAz_03; - num AAAz_04; - - num AAAw_01; - num AAAu_01; - - foo() { - int a = 0; - AAAw_01++; - AAAu_01 += a * 123; - } -} - -class BBB extends AAA { - BBB() : super() { } - num get AAAz_01() { } - num get AAAz_03() { } - set AAAz_02(x) { } - set AAAz_04(x) { } -} - -class AA { - AA() { } - AAA aaa_; -} - -class A { - A() { } - AA aa_; - num Ay_01; - num Ay_02; - num Ay_03; - num Ay_04; - num Ay_05; - num Ay_06; -} - -class Main { - - static void main(num _marker_5, num _marker_6, num _marker_7, num _marker_8) { - num _marker_0, _marker_1, _marker_2, _marker_3, _marker_4; - num _marker_9, _marker__10, _marker__11, _marker__12; - - // Ensure that += is not generated as shim - _marker_1 += _marker_0 + 1; - - // Ensure that -= is not generated as shim - _marker_2 -= _marker_0 + 1; - - // Ensure that *= is not generated as shim - _marker_3 *= _marker_0 + 1; - - // Ensure that /= is not generated as shim - _marker_4 /= _marker_0 + 1; - - // Ensure that += is not generated as shim - _marker_5 += _marker_0 + 1; - - // Ensure that -= is not generated as shim - _marker_6 -= _marker_0 + 1; - - // Ensure that *= is not generated as shim - _marker_7 *= _marker_0 + 1; - - // Ensure that /= is not generated as shim - _marker_8 /= _marker_0 + 1; - - A _a_ = new A(); - - // Should be optimized - simple field case. - _a_.Ay_01++; - _a_.Ay_02--; - - // all 'inline-able' operators - int tmp = 123; - _a_.Ay_03 += 2 * tmp * -123; - _a_.Ay_04 -= 2 * tmp * -123; - _a_.Ay_05 *= 2 * tmp * -123; - _a_.Ay_06 /= 2 * tmp * -123; - - // All 'inline-able' operators with long path expressions. - _a_.aa_.aaa_.AAAx_01 += 2 * tmp / -1; - _a_.aa_.aaa_.AAAx_02 -= 2 * tmp / -1; - _a_.aa_.aaa_.AAAx_03 *= 2 * tmp / -1; - _a_.aa_.aaa_.AAAx_04 /= 2 * tmp / -1; - - // add method to double check we are inlining correctly. - _a_.aa_.aaa_.AAAx_05 += call(_a_.aa_.aaa_.AAAx_05) * tmp / -1; - - // Negative test cases. - - // _AAAz_01 must call shim (derived class has an a getter with same name as parent field). - _a_.aa_.aaa_.AAAz_01++; - - // _AAAz_02 must call shim (derived class has an a setter with same name as parent field). - _a_.aa_.aaa_.AAAz_02++; - - // _AAAz_03 must call shim (derived class has an a getter with same name as parent field). - _a_.aa_.aaa_.AAAz_03 += 22 * tmp / -1; - - // _AAAz_04 must call shim (derived class has an a getter with same name as parent field). - _a_.aa_.aaa_.AAAz_04 += 222 * tmp / -1; - - // Cannot be inlined % and ~ - _a_.aa_.aaa_.AAAx_06 %= 2 * tmp / -1; - _a_.aa_.aaa_.AAAx_07 ~/= 2 * tmp / -1; - - _marker_9 |= _marker_0 & 1; - - _marker__10 &= _marker_0 & 1; - - _marker__11 ^= _marker_0 & 1; - - var _var_marker; - _marker__12 |= _var_marker & 1; - - _var_marker |= _marker__12 & 1; - } - - static double call(x) { return x; } -} - -main() { - Main.main(0, 0, 0, 0); -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/testConstantExprOpt.dart b/compiler/javatests/com/google/dart/compiler/backend/js/testConstantExprOpt.dart deleted file mode 100644 index 42fec0a8835..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/testConstantExprOpt.dart +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -class Foo { - const Foo(); -} - -class A { - static final int C1 = 10 + C2 * 2; // 20 - static final int C2 = 5; - static final Foo C3 = const Foo(); - static int foo() { return 1; } -} - -class Main { - static void main() { - int _marker_0, _marker_1, _marker_2; - Foo _marker_3; - - final int x = 50; - - _marker_0 = x * 2; - - _marker_1 = A.C1 + 5; - - _marker_2 = 5 + A.C2; - - _marker_3 = A.C3; - } -} - -main() { - Main.main(); -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/testConstructorOptTest.dart b/compiler/javatests/com/google/dart/compiler/backend/js/testConstructorOptTest.dart deleted file mode 100644 index 3e019404ae6..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/testConstructorOptTest.dart +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -class AAA { - int a; - int b = 567; - AAA(this.a) : this.c = 123 { } - int c; - int d; -} - -class BBB { - int a; - int b = 567; - int c; - BBB(this.a) { } -} - -class CCC extends BBB { - int d; - CCC(x) : d = x, super(x) { } -} - -class DDD { - int x; - int z; - DDD(this.x, [this.z = 123]); - void foo() { - new DDD(1); - } -} - -main() { - AAA _a_marker = new AAA(123); - BBB _b_marker = new BBB(999); -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/testFieldAccessExprOpt.dart b/compiler/javatests/com/google/dart/compiler/backend/js/testFieldAccessExprOpt.dart deleted file mode 100644 index a336a743a54..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/testFieldAccessExprOpt.dart +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -class A { - final int x; - - const A() : this.x = 1; - - static final A a = const A(); -} - -class WillNotOptimizeFieldAccess { - WillNotOptimizeFieldAccess(){} - int x; -} - -class WillNotOptimizeFieldAccessSubclass extends WillNotOptimizeFieldAccess { - WillNotOptimizeFieldAccessSubclass() : super() {} - - int get x() { - return this.x; - } - - void set x(v) { - } -} - -class B extends A { - B() : super() { } - - // can be inlined. - int get x_Getter_WithoutSideEffect() { - return x; - } - - // cannot be inlined - getter has side effect. - int get x_Getter_WithSideEffect() { - return x + 1; - } - - // cannot be inlined - underlying value is not a field. - int get x_Getter_WithSomeExpression() { - return foo() * 2; - } - - static foo() { return 123; } - - // cannot be inlined - underlying field is static. - A get A_Getter() { - return a; - } - - // cannot be inlined - cycle. - int get X_Getter() { - return this.X_Getter; - } -} - -class C { - C() { } - - int x; - A a; - - int get XGetter() { - return this.x; - } - - int get AXGetter() { - return a.x; - } -} - -class Main { - static void main() { - - A _marker_0 = new A(); - - _marker_0.x = 1; - - int x = _marker_0.x; - - WillNotOptimizeFieldAccessSubclass _marker_1 = new WillNotOptimizeFieldAccessSubclass(); - _marker_1.x = 1; - int y = _marker_1.x; - - B b = new B(); - int _marker_2 = b.x_Getter_WithoutSideEffect; - - int _marker_3 = b.x_Getter_WithSideEffect; - - int _marker_4 = b.x_Getter_WithSomeExpression; - - A _marker_5 = b.A_Getter; - - int _marker_6 = b.X_Getter; - - C c = new C(); - - int _marker_7 = c.XGetter; - - int _marker_8 = c.AXGetter; - } -} - -main() { - Main.main(); -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/testListExprOpt.dart b/compiler/javatests/com/google/dart/compiler/backend/js/testListExprOpt.dart deleted file mode 100644 index cb22404acd1..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/testListExprOpt.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -class MyClass { - MyClass(x) { } - T operator [](int index) { - } - void operator []=(int index, int val) { - } -} - -class Main { - static void main() { - // base case (should be inlined). - List _list0_ = new List(10); - _list0_[0] = 1; - int lhs0 = _list0_[0]; - - // final case - only 'reads' can be inlined. - final List _list1_ = new List(10); - _list1_[0] = 1; - int lhs1 = _list1_[0]; - - // operator [] - cannot inline reads or writes. - MyClass _list2_ = new MyClass(2); - _list2_[0] = "foo"; - String lhs2 = _list2_[0]; - - // untyped. - var _list3_ = new List(2); - _list3_[0] = "foo"; - String lhs3 = _list3_[0]; - - // untyped. - List _list4_ = new List(2); - int i_0 = 0; - int j_0 = 0; - _list4_[i_0 + j_0] = "foo"; - String lhs4 = _list4_[i_0 - j_0]; - - // nested list (should be inlined). - List>> _list5_ = new List>>(10); - _list5_[0] = null; - var lhs5 = _list5_[0]; - _list5_[0][1] = null; - lhs5 = _list5_[0][1]; - _list5_[0][1][2] = 1; - lhs5 = _list5_[0][1][2]; - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/testListSubTypeExprOpt.dart b/compiler/javatests/com/google/dart/compiler/backend/js/testListSubTypeExprOpt.dart deleted file mode 100644 index 40e6510db2c..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/testListSubTypeExprOpt.dart +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -class MyList implements List { - MyList() { } - T operator[](int index) { return null; } - void operator[]=(int index, T value) {} - int length; - void add(T value) {} - void addLast(T value) {} - void addAll(Collection collection) {} - void sort(int f(T, T)) {} - void copyFrom(List src, int srcStart, int dstStart, int count) {} - int indexOf(T element, [int start = 0]) { return null; } - int lastIndexOf(T element, [int start = null]) { return null; } - void setRange(int start, int length_, List from, [int startFrom = 0]) {} - void removeRange(int start, int length_) {} - void insertRange(int start, int length_, [initialValue = null]) {} - List getRange(int start, int length_) { return null; } - void clear() {} - T removeLast() { return null; } - T last() { return null; } - void forEach(void f(T)) {} - List map(f(T)) { return null; } - Collection filter(bool f(T)) { return null; } - bool every(bool f(T)) { return null; } - bool some(bool f(T)) { return null; } - bool isEmpty() { return null; } - Iterator iterator() { return null; } -} - -class Main { - static void main() { - // List subtype (we will do better in the future, for now, take the conservative path). - MyList _list0_ = new MyList(); - _list0_[0] = "foo"; - String lhs0 = _list0_[0]; - } -} - -main() { - Main.main(); -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/testLiteralExpressions.dart b/compiler/javatests/com/google/dart/compiler/backend/js/testLiteralExpressions.dart deleted file mode 100644 index 3d1db4ce0f4..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/testLiteralExpressions.dart +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -class A { - A() { } -} - -class B { - B() { } - bool operator ==(Object other) { - return this === other; - } -} - -class Main { - static void main() { - int _marker_0 = 1 + 1; - int _marker_1 = 1 - 1; - int _marker_2 = 1 * 1; - double _marker_3 = 1 / 1; - int _marker_4 = 1 % 1; - - bool _marker_5 = 1 > 1; - bool _marker_6 = 1 < 1; - bool _marker_7 = 1 >= 1; - bool _marker_8 = 1 <= 1; - - bool _marker_9 = 1 == 1; - bool _marker_10 = 1 != 1; - - bool _marker_11 = true == false; - bool _marker_12 = true != false; - - double _marker_13 = 1.0 ~/ 2.0; - - int _marker_14 = 1 | 1; - int _marker_15 = 1 & 1; - int _marker_16 = 1 << 1; - int _marker_17 = 1 >> 1; - - bool _marker_18 = true || false; - bool _marker_19 = true && false; - - A a = new A(); - B b = new B(); - String str = "foo"; - int i = 0; - - bool _marker_20 = i == 0; - bool _marker_21 = i != 0; - bool _marker_22 = str == "a"; - bool _marker_23 = str != "a"; - bool _marker_24 = a == b; - bool _marker_25 = a != b; - bool _marker_26 = b == a; - bool _marker_27 = b != a; - bool _marker_28 = a == null; - bool _marker_29 = a != null; - bool _marker_30 = null == a; - bool _marker_31 = null != a; - bool _marker_32 = b == null; - bool _marker_33 = b != null; - bool _marker_34 = null == b; - bool _marker_35 = null != b; - bool _marker_36 = i === 0; - bool _marker_37 = i !== 0; - bool _marker_38 = str === "a"; - bool _marker_39 = str !== "a"; - bool _marker_40 = a === b; - bool _marker_41 = a !== b; - bool _marker_42 = b === a; - bool _marker_43 = b !== a; - bool _marker_44 = a === null; - bool _marker_45 = a !== null; - bool _marker_46 = null === a; - bool _marker_47 = null !== a; - bool _marker_48 = b === null; - bool _marker_49 = b !== null; - bool _marker_50 = null === b; - bool _marker_51 = null !== b; - bool _marker_52 = str === null; - bool _marker_53 = str !== null; - bool _marker_54 = null === str; - bool _marker_55 = null !== str; - bool _marker_56 = null == null; - bool _marker_57 = null === null; - bool _marker_58 = false == null; - bool _marker_59 = false === null; - bool _marker_60 = str == null; - bool _marker_61 = str != null; - bool _marker_62 = null == str; - bool _marker_63 = null != str; - } -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/testRuntimeTypes.dart b/compiler/javatests/com/google/dart/compiler/backend/js/testRuntimeTypes.dart deleted file mode 100644 index e52dcf17e5c..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/testRuntimeTypes.dart +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -class B { - const B(); -} - -class C { - const C(); -} - -class D extends C { - factory D() { - return new E(); - } -} - -class E extends D { -} - - -// SnippetTestCase only returns generated JS for the Main class. -class Main { - static void main() { - var a = 0; - var _marker_0 = 1; - var _marker_B1 = const B(); - var _marker_B2 = new B(); - var _marker_C1 = const C(); - var _marker_C2 = const C(); - var _marker_C3 = new C(); - var _marker_C4 = new C(); - var _marker_D1 = new D(); - var _marker_D2 = new D(); - - a = _marker_B1 is B; - a = _marker_C1 is C; - a = _marker_C2 is C; - a = _marker_C4 is C; - a = _marker_C4 is Object; - a = _marker_D1 is D; - a = _marker_D2 is D; - } -} - -main() { - Main.main(); -} diff --git a/compiler/javatests/com/google/dart/compiler/backend/js/testUnaryDecIncExprOpt.dart b/compiler/javatests/com/google/dart/compiler/backend/js/testUnaryDecIncExprOpt.dart deleted file mode 100644 index b493493479b..00000000000 --- a/compiler/javatests/com/google/dart/compiler/backend/js/testUnaryDecIncExprOpt.dart +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -class Main { - static void main(int _marker_3) { - int _marker_0 = 0; - - // Ensure that ++_marker_0 remains ++_marker_0 on simple assignment - int i = ++_marker_0; - - // Ensure that _marker_1++ remains _marker_1++ when used in a for loop - for (int _marker_1 = 0; _marker_1 < 10; _marker_1++) { - } - - // Ensure that --_marker_0 remains --_marker_0 on simple assignment - int j = --_marker_0; - - // Ensure that _marker_2-- remains _marker_2-- when used in a for loop - for (int _marker_2 = 10; _marker_2 >= 0; _marker_2--) { - } - - // Ensure that parameter _marker_3 remains as _marker_3++ - _marker_3++; - - // Ensure that parameter _marker_3 remains as --_marker_3 - --_marker_3; - - // Ensure binary op is inlined (variable). - int _marker_4; - i = ~_marker_4; - - // Ensure binary op is inlined (parameter). - i = ~_marker_3; - - // Ensure binary op is inlined (field). - A a = new A(); - i = ~a.field_0; - - // Ensure untyped operand is not inlined - var foo; - int _marker_5; - _marker_5 = ~foo; - - // Ensure binary op is not inlined (abstract field). - A aa = new B(); - i = ++aa.field_1; - - // Ensure binary op is not inlined (abstract field). - A aaa = new B(); - i = ++aaa.field_2; - } -} - -class A { - A() { } - int field_0; - int field_1; - int field_2; -} - -class B extends A { - B() : super() { } - int get field_1() { } - set field_2(x) { } -} - -main() { - Main.main(0); -} diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java index 05c68c0d7f9..692daf7ff27 100644 --- a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java +++ b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java @@ -20,7 +20,6 @@ import com.google.dart.compiler.LibrarySource; import com.google.dart.compiler.MockArtifactProvider; import com.google.dart.compiler.Source; import com.google.dart.compiler.ast.DartUnit; -import com.google.dart.compiler.backend.js.JavascriptBackend; import com.google.dart.compiler.resolver.ResolverErrorCode; import com.google.dart.compiler.resolver.TypeErrorCode; @@ -75,7 +74,7 @@ public class IncrementalCompilation2Test extends CompilerTestCase { @Override protected void setUp() throws Exception { - config = new DefaultCompilerConfiguration(new JavascriptBackend()) { + config = new DefaultCompilerConfiguration() { @Override public boolean incremental() { return true; @@ -185,7 +184,7 @@ public class IncrementalCompilation2Test extends CompilerTestCase { * Test for "hole" feature. If we use unqualified invocation and add/remove top-level method, this * should cause compilation of invocation unit. */ - public void test_isMethodHole_useUnqualifiedInvocation() { + public void test_isMethodHole_useUnqualifiedInvocation() throws Exception { appSource.setContent( "B.dart", makeCode( @@ -222,6 +221,8 @@ public class IncrementalCompilation2Test extends CompilerTestCase { didWrite("C.dart", EXTENSION_TIMESTAMP); assertAppBuilt(); } + // Wait, because analysis is so fast that may be A will have same time as old artifact. + Thread.sleep(5); // Remove top-level foo(), so invocation of foo() in B should be bound to the super class. { appSource.setContent("A.dart", ""); @@ -281,7 +282,7 @@ public class IncrementalCompilation2Test extends CompilerTestCase { * Test for "hole" feature. If we use unqualified access and add/remove top-level field, this * should cause compilation of invocation unit. */ - public void test_fieldHole_useUnqualifiedAccess() { + public void test_fieldHole_useUnqualifiedAccess() throws Exception { appSource.setContent( "B.dart", makeCode( @@ -318,6 +319,8 @@ public class IncrementalCompilation2Test extends CompilerTestCase { didWrite("C.dart", EXTENSION_TIMESTAMP); assertAppBuilt(); } + // Wait, because analysis is so fast that may be A will have same time as old artifact. + Thread.sleep(5); // Remove top-level "foo", so access to "foo" in B should be bound to the super class. { appSource.setContent("A.dart", ""); diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationTest.java b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationTest.java index e0dd00efe4c..9e366105d1e 100644 --- a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationTest.java +++ b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationTest.java @@ -8,7 +8,6 @@ import static com.google.dart.compiler.DartCompiler.EXTENSION_DEPS; import static com.google.dart.compiler.DartCompiler.EXTENSION_TIMESTAMP; import com.google.common.collect.Lists; -import com.google.dart.compiler.CommandLineOptions.CompilerOptions; import com.google.dart.compiler.CompilerTestCase; import com.google.dart.compiler.DartCompilationError; import com.google.dart.compiler.DartCompiler; @@ -18,7 +17,6 @@ import com.google.dart.compiler.LibrarySource; import com.google.dart.compiler.MockArtifactProvider; import com.google.dart.compiler.MockBundleLibrarySource; import com.google.dart.compiler.Source; -import com.google.dart.compiler.backend.js.JavascriptBackend; import junit.framework.AssertionFailedError; @@ -68,8 +66,7 @@ public class IncrementalCompilationTest extends CompilerTestCase { @Override protected void setUp() throws Exception { - CompilerOptions compilerOptions = new CompilerOptions(); - config = new DefaultCompilerConfiguration(new JavascriptBackend()) { + config = new DefaultCompilerConfiguration() { @Override public boolean incremental() { return true; diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationWithPrefixTest.java b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationWithPrefixTest.java index ef398af6b3b..8d47aa250de 100644 --- a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationWithPrefixTest.java +++ b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationWithPrefixTest.java @@ -16,7 +16,6 @@ import com.google.dart.compiler.LibrarySource; import com.google.dart.compiler.MockArtifactProvider; import com.google.dart.compiler.MockBundleLibrarySource; import com.google.dart.compiler.Source; -import com.google.dart.compiler.backend.js.JavascriptBackend; import junit.framework.AssertionFailedError; @@ -63,7 +62,7 @@ public class IncrementalCompilationWithPrefixTest extends CompilerTestCase { @Override protected void setUp() throws Exception { - config = new DefaultCompilerConfiguration(new JavascriptBackend()) { + config = new DefaultCompilerConfiguration() { @Override public boolean incremental() { return true; diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/MemoryLibrarySource.java b/compiler/javatests/com/google/dart/compiler/end2end/inc/MemoryLibrarySource.java index e0469f23fb1..8a1bf0a3f5c 100644 --- a/compiler/javatests/com/google/dart/compiler/end2end/inc/MemoryLibrarySource.java +++ b/compiler/javatests/com/google/dart/compiler/end2end/inc/MemoryLibrarySource.java @@ -14,7 +14,6 @@ import java.io.Reader; import java.io.StringReader; import java.net.URI; import java.net.URISyntaxException; -import java.util.Date; import java.util.Map; /** @@ -103,6 +102,6 @@ public class MemoryLibrarySource implements LibrarySource { */ public void setContent(String relPath, String content) { sourceContentMap.put(relPath, content); - sourceLastModifiedMap.put(relPath, new Date().getTime()); + sourceLastModifiedMap.put(relPath, System.currentTimeMillis()); } } diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart index 70a8d39f453..a8cfc7fbd86 100644 --- a/tools/testing/dart/test_suite.dart +++ b/tools/testing/dart/test_suite.dart @@ -877,11 +877,7 @@ class DartcCompilationTestSuite extends StandardTestSuite { String shellPath() => TestUtils.compilerPath(configuration); List additionalOptions(String filename) { - filename = new File(filename).fullPathSync().replaceAll('\\', '/'); - Directory tempDir = createOutputDirectory(filename, 'dartc-test'); - return - [ '--fatal-warnings', '--fatal-type-errors', - '--out', tempDir.path]; + return ['--fatal-warnings', '--fatal-type-errors']; } void processDirectory() {