diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java deleted file mode 100644 index 5cca0323b9d..00000000000 --- a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.js.facade; - -import com.intellij.openapi.vfs.VfsUtilCore; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.config.CommonConfigurationKeys; -import org.jetbrains.kotlin.config.CommonConfigurationKeysKt; -import org.jetbrains.kotlin.config.LanguageVersionSettings; -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; -import org.jetbrains.kotlin.descriptors.ModuleDescriptor; -import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer; -import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS; -import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult; -import org.jetbrains.kotlin.js.backend.ast.JsImportedModule; -import org.jetbrains.kotlin.js.backend.ast.JsProgramFragment; -import org.jetbrains.kotlin.js.config.JSConfigurationKeys; -import org.jetbrains.kotlin.js.config.JsConfig; -import org.jetbrains.kotlin.js.coroutine.CoroutineTransformer; -import org.jetbrains.kotlin.js.facade.exceptions.TranslationException; -import org.jetbrains.kotlin.js.inline.JsInliner; -import org.jetbrains.kotlin.js.inline.clean.LabeledBlockToDoWhileTransformation; -import org.jetbrains.kotlin.js.inline.clean.RemoveDuplicateImportsKt; -import org.jetbrains.kotlin.js.inline.clean.RemoveUnusedImportsKt; -import org.jetbrains.kotlin.js.inline.clean.ResolveTemporaryNamesKt; -import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver; -import org.jetbrains.kotlin.js.translate.general.AstGenerationResult; -import org.jetbrains.kotlin.js.translate.general.Translation; -import org.jetbrains.kotlin.js.translate.utils.ExpandIsCallsKt; -import org.jetbrains.kotlin.metadata.ProtoBuf; -import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion; -import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus; -import org.jetbrains.kotlin.psi.KtFile; -import org.jetbrains.kotlin.resolve.BindingTrace; -import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics; -import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil; -import org.jetbrains.kotlin.serialization.js.ast.JsAstSerializer; -import org.jetbrains.kotlin.utils.JsMetadataVersion; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static org.jetbrains.kotlin.diagnostics.DiagnosticUtils.hasError; - -/** - * An entry point of translator. - */ -public final class K2JSTranslator { - - @NotNull - private final JsConfig config; - - @Nullable - private final IncrementalResultsConsumer incrementalResults; - - public K2JSTranslator(@NotNull JsConfig config) { - this.config = config; - this.incrementalResults = config.getConfiguration().get(JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER); - } - - @NotNull - public TranslationResult translate( - @NotNull JsConfig.Reporter reporter, - @NotNull List files, - @NotNull MainCallParameters mainCallParameters - ) throws TranslationException { - return translate(reporter, files, mainCallParameters, null); - } - - @NotNull - public TranslationResult translate( - @NotNull JsConfig.Reporter reporter, - @NotNull List files, - @NotNull MainCallParameters mainCallParameters, - @Nullable JsAnalysisResult analysisResult - ) throws TranslationException { - List units = new ArrayList<>(); - for (KtFile file : files) { - units.add(new TranslationUnit.SourceFile(file)); - } - return translateUnits(reporter, units, mainCallParameters, analysisResult); - } - - @NotNull - public TranslationResult translateUnits( - @NotNull JsConfig.Reporter reporter, - @NotNull List units, - @NotNull MainCallParameters mainCallParameters - ) throws TranslationException { - return translateUnits(reporter, units, mainCallParameters, null); - } - - @NotNull - public TranslationResult translateUnits( - @NotNull JsConfig.Reporter reporter, - @NotNull List units, - @NotNull MainCallParameters mainCallParameters, - @Nullable JsAnalysisResult analysisResult - ) throws TranslationException { - List files = new ArrayList<>(); - for (TranslationUnit unit : units) { - if (unit instanceof TranslationUnit.SourceFile) { - files.add(((TranslationUnit.SourceFile) unit).getFile()); - } - } - - if (analysisResult == null) { - analysisResult = TopDownAnalyzerFacadeForJS.analyzeFiles(files, config); - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); - } - - BindingTrace bindingTrace = analysisResult.getBindingTrace(); - TopDownAnalyzerFacadeForJS.checkForErrors(files, bindingTrace.getBindingContext()); - ModuleDescriptor moduleDescriptor = analysisResult.getModuleDescriptor(); - Diagnostics diagnostics = bindingTrace.getBindingContext().getDiagnostics(); - - SourceFilePathResolver pathResolver = SourceFilePathResolver.create(config); - - AstGenerationResult translationResult = Translation.generateAst( - bindingTrace, units, mainCallParameters, moduleDescriptor, config, pathResolver); - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); - if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics); - - List newFragments = new ArrayList<>(translationResult.getNewFragments()); - List allFragments = new ArrayList<>(translationResult.getFragments()); - - JsInliner.process(reporter, config, analysisResult.getBindingTrace(), translationResult.getInnerModuleName(), - allFragments, newFragments, translationResult.getImportStatements()); - - LabeledBlockToDoWhileTransformation.INSTANCE.apply(newFragments); - - CoroutineTransformer coroutineTransformer = new CoroutineTransformer(); - for (JsProgramFragment fragment : newFragments) { - coroutineTransformer.accept(fragment.getDeclarationBlock()); - coroutineTransformer.accept(fragment.getInitializerBlock()); - } - RemoveUnusedImportsKt.removeUnusedImports(translationResult.getProgram()); - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); - if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics); - - ExpandIsCallsKt.expandIsCalls(newFragments); - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); - JsAstSerializer serializer = new JsAstSerializer(file -> { - try { - return pathResolver.getPathRelativeToSourceRoots(file); - } - catch (IOException e) { - throw new RuntimeException("IO error occurred resolving path to source file", e); - } - }); - - if (incrementalResults != null) { - KotlinJavascriptSerializationUtil serializationUtil = KotlinJavascriptSerializationUtil.INSTANCE; - - for (KtFile file : files) { - JsProgramFragment fragment = translationResult.getFragmentMap().get(file); - assert fragment != null : "Could not find AST for file: " + file; - ByteArrayOutputStream output = new ByteArrayOutputStream(); - serializer.serialize(fragment, output); - byte[] binaryAst = output.toByteArray(); - - List scope = translationResult.getFileMemberScopes().get(file); - assert scope != null : "Could not find descriptors for file: " + file; - BinaryVersion metadataVersion = config.getConfiguration().get(CommonConfigurationKeys.METADATA_VERSION); - ProtoBuf.PackageFragment packagePart = serializationUtil.serializeDescriptors( - bindingTrace.getBindingContext(), moduleDescriptor, scope, file.getPackageFqName(), - CommonConfigurationKeysKt.getLanguageVersionSettings(config.getConfiguration()), - metadataVersion != null ? metadataVersion : JsMetadataVersion.INSTANCE - ); - - File ioFile = VfsUtilCore.virtualToIoFile(file.getVirtualFile()); - incrementalResults.processPackagePart(ioFile, packagePart.toByteArray(), binaryAst); - } - - LanguageVersionSettings settings = CommonConfigurationKeysKt.getLanguageVersionSettings(config.getConfiguration()); - incrementalResults.processHeader(serializationUtil.serializeHeader(moduleDescriptor, null, settings).toByteArray()); - } - - RemoveDuplicateImportsKt.removeDuplicateImports(translationResult.getProgram()); - ResolveTemporaryNamesKt.resolveTemporaryNames(translationResult.getProgram()); - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); - if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics); - - List importedModules = new ArrayList<>(); - for (JsImportedModule module : translationResult.getImportedModuleList()) { - importedModules.add(module.getExternalName()); - } - - return new TranslationResult.Success(config, files, translationResult.getProgram(), diagnostics, importedModules, - moduleDescriptor, bindingTrace.getBindingContext()); - } -} diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt new file mode 100644 index 00000000000..97003cb0722 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt @@ -0,0 +1,174 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.js.facade + +import com.intellij.openapi.vfs.VfsUtilCore +import org.jetbrains.kotlin.config.CommonConfigurationKeys +import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer +import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS +import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.config.JsConfig +import org.jetbrains.kotlin.js.coroutine.CoroutineTransformer +import org.jetbrains.kotlin.js.facade.exceptions.TranslationException +import org.jetbrains.kotlin.js.inline.JsInliner +import org.jetbrains.kotlin.js.inline.clean.LabeledBlockToDoWhileTransformation +import org.jetbrains.kotlin.js.inline.clean.* +import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver +import org.jetbrains.kotlin.js.translate.general.Translation +import org.jetbrains.kotlin.js.translate.utils.* +import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil +import org.jetbrains.kotlin.serialization.js.ast.JsAstSerializer +import org.jetbrains.kotlin.utils.JsMetadataVersion + +import java.io.ByteArrayOutputStream +import java.io.IOException +import java.util.ArrayList + +import org.jetbrains.kotlin.diagnostics.DiagnosticUtils.hasError + +/** + * An entry point of translator. + */ +class K2JSTranslator(private val config: JsConfig) { + + private val incrementalResults = config.configuration.get(JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER) + + @Throws(TranslationException::class) + @JvmOverloads + fun translate( + reporter: JsConfig.Reporter, + files: List, + mainCallParameters: MainCallParameters, + analysisResult: JsAnalysisResult? = null + ): TranslationResult { + val units = ArrayList() + for (file in files) { + units.add(TranslationUnit.SourceFile(file)) + } + return translateUnits(reporter, units, mainCallParameters, analysisResult) + } + + @Throws(TranslationException::class) + @JvmOverloads + fun translateUnits( + reporter: JsConfig.Reporter, + units: List, + mainCallParameters: MainCallParameters, + analysisResult: JsAnalysisResult? = null + ): TranslationResult { + var analysisResult = analysisResult + val files = ArrayList() + for (unit in units) { + if (unit is TranslationUnit.SourceFile) { + files.add(unit.file) + } + } + + if (analysisResult == null) { + analysisResult = TopDownAnalyzerFacadeForJS.analyzeFiles(files, config) + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + } + + val bindingTrace = analysisResult.bindingTrace + TopDownAnalyzerFacadeForJS.checkForErrors(files, bindingTrace.bindingContext) + val moduleDescriptor = analysisResult.moduleDescriptor + val diagnostics = bindingTrace.bindingContext.diagnostics + + val pathResolver = SourceFilePathResolver.create(config) + + val translationResult = Translation.generateAst( + bindingTrace, units, mainCallParameters, moduleDescriptor, config, pathResolver + ) + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + if (hasError(diagnostics)) return TranslationResult.Fail(diagnostics) + + val newFragments = ArrayList(translationResult.newFragments) + val allFragments = ArrayList(translationResult.fragments) + + JsInliner.process( + reporter, config, analysisResult.bindingTrace, translationResult.innerModuleName, + allFragments, newFragments, translationResult.importStatements + ) + + LabeledBlockToDoWhileTransformation.apply(newFragments) + + val coroutineTransformer = CoroutineTransformer() + for (fragment in newFragments) { + coroutineTransformer.accept(fragment.declarationBlock) + coroutineTransformer.accept(fragment.initializerBlock) + } + removeUnusedImports(translationResult.program) + + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + if (hasError(diagnostics)) return TranslationResult.Fail(diagnostics) + + expandIsCalls(newFragments) + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + val serializer = JsAstSerializer { file -> + try { + pathResolver.getPathRelativeToSourceRoots(file) + } catch (e: IOException) { + throw RuntimeException("IO error occurred resolving path to source file", e) + } + } + + if (incrementalResults != null) { + val serializationUtil = KotlinJavascriptSerializationUtil + + for (file in files) { + val fragment = translationResult.fragmentMap[file] ?: error("Could not find AST for file: $file") + val output = ByteArrayOutputStream() + serializer.serialize(fragment, output) + val binaryAst = output.toByteArray() + + val scope = translationResult.fileMemberScopes[file] ?: error("Could not find descriptors for file: $file") + val metadataVersion = config.configuration.get(CommonConfigurationKeys.METADATA_VERSION) + val packagePart = serializationUtil.serializeDescriptors( + bindingTrace.bindingContext, moduleDescriptor, scope, file.packageFqName, + config.configuration.languageVersionSettings, + metadataVersion ?: JsMetadataVersion.INSTANCE + ) + + val ioFile = VfsUtilCore.virtualToIoFile(file.virtualFile) + incrementalResults.processPackagePart(ioFile, packagePart.toByteArray(), binaryAst) + } + + val settings = config.configuration.languageVersionSettings + incrementalResults.processHeader(serializationUtil.serializeHeader(moduleDescriptor, null, settings).toByteArray()) + } + + removeDuplicateImports(translationResult.program) + translationResult.program.resolveTemporaryNames() + + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + if (hasError(diagnostics)) return TranslationResult.Fail(diagnostics) + + val importedModules = ArrayList() + for (module in translationResult.importedModuleList) { + importedModules.add(module.externalName) + } + + return TranslationResult.Success( + config, files, translationResult.program, diagnostics, importedModules, + moduleDescriptor, bindingTrace.bindingContext + ) + } +}