JS: added TranslationResult
This commit is contained in:
@@ -23,7 +23,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -55,10 +54,10 @@ import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS;
|
||||
import org.jetbrains.kotlin.js.config.Config;
|
||||
import org.jetbrains.kotlin.js.config.EcmaVersion;
|
||||
import org.jetbrains.kotlin.js.config.LibrarySourcesConfig;
|
||||
import org.jetbrains.kotlin.js.facade.K2JSTranslator;
|
||||
import org.jetbrains.kotlin.js.facade.MainCallParameters;
|
||||
import org.jetbrains.kotlin.js.facade.Status;
|
||||
import org.jetbrains.kotlin.js.facade.TranslationResult;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics;
|
||||
import org.jetbrains.kotlin.utils.PathUtil;
|
||||
|
||||
import java.io.File;
|
||||
@@ -67,7 +66,6 @@ import java.util.List;
|
||||
import static org.jetbrains.kotlin.cli.common.ExitCode.COMPILATION_ERROR;
|
||||
import static org.jetbrains.kotlin.cli.common.ExitCode.OK;
|
||||
import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation.NO_LOCATION;
|
||||
import static org.jetbrains.kotlin.js.facade.K2JSTranslator.translateWithMainCallParameters;
|
||||
|
||||
public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
|
||||
@@ -159,22 +157,23 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
}
|
||||
|
||||
MainCallParameters mainCallParameters = createMainCallParameters(arguments.main);
|
||||
Status<OutputFileCollection> status;
|
||||
TranslationResult translationResult;
|
||||
|
||||
K2JSTranslator translator = new K2JSTranslator(config);
|
||||
try {
|
||||
//noinspection unchecked
|
||||
status = translateWithMainCallParameters(mainCallParameters, sourcesFiles, outputFile, outputPrefixFile, outputPostfixFile,
|
||||
config, Consumer.EMPTY_CONSUMER);
|
||||
translationResult = translator.translate(sourcesFiles, mainCallParameters);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Diagnostics diagnostics = config.getTrace().getBindingContext().getDiagnostics();
|
||||
AnalyzerWithCompilerReport.reportDiagnostics(diagnostics, messageCollector);
|
||||
AnalyzerWithCompilerReport.reportDiagnostics(translationResult.getDiagnostics(), messageCollector);
|
||||
|
||||
if (status.isFail()) return ExitCode.COMPILATION_ERROR;
|
||||
if (!(translationResult instanceof TranslationResult.Success)) return ExitCode.COMPILATION_ERROR;
|
||||
|
||||
TranslationResult.Success successResult = (TranslationResult.Success) translationResult;
|
||||
OutputFileCollection outputFiles = successResult.getOutputFiles(outputFile, outputPrefixFile, outputPostfixFile);
|
||||
|
||||
OutputFileCollection outputFiles = status.getResult();
|
||||
if (outputFile.isDirectory()) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR,
|
||||
"Cannot open output file '" + outputFile.getPath() + "': is a directory",
|
||||
|
||||
@@ -39,8 +39,9 @@ import org.jetbrains.kotlin.js.config.Config;
|
||||
import org.jetbrains.kotlin.js.config.EcmaVersion;
|
||||
import org.jetbrains.kotlin.js.config.LibrarySourcesConfig;
|
||||
import org.jetbrains.kotlin.js.config.LibrarySourcesConfigWithCaching;
|
||||
import org.jetbrains.kotlin.js.facade.K2JSTranslator;
|
||||
import org.jetbrains.kotlin.js.facade.MainCallParameters;
|
||||
import org.jetbrains.kotlin.js.facade.Status;
|
||||
import org.jetbrains.kotlin.js.facade.TranslationResult;
|
||||
import org.jetbrains.kotlin.js.test.rhino.RhinoResultChecker;
|
||||
import org.jetbrains.kotlin.js.test.utils.JsTestUtils;
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer;
|
||||
@@ -57,7 +58,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.js.facade.K2JSTranslator.translateWithMainCallParameters;
|
||||
import static org.jetbrains.kotlin.js.test.rhino.RhinoUtils.runRhinoTest;
|
||||
import static org.jetbrains.kotlin.js.test.utils.JsTestUtils.convertFileNameToDotJsFile;
|
||||
|
||||
@@ -175,15 +175,18 @@ public abstract class BasicTest extends KotlinTestWithEnvironment {
|
||||
@NotNull MainCallParameters mainCallParameters,
|
||||
@NotNull Config config
|
||||
) throws Exception {
|
||||
Status<OutputFileCollection> status = translateWithMainCallParameters(mainCallParameters, jetFiles, outputFile,
|
||||
getOutputPrefixFile(), getOutputPostfixFile(),
|
||||
config, getConsumer());
|
||||
K2JSTranslator translator = new K2JSTranslator(config);
|
||||
TranslationResult translationResult = translator.translate(jetFiles, mainCallParameters);
|
||||
|
||||
if (status.isFail()) return;
|
||||
if (!(translationResult instanceof TranslationResult.Success)) return;
|
||||
|
||||
TranslationResult.Success successResult = (TranslationResult.Success) translationResult;
|
||||
getConsumer().consume(successResult.getProgram());
|
||||
|
||||
OutputFileCollection outputFiles = successResult.getOutputFiles(outputFile, getOutputPrefixFile(), getOutputPostfixFile());
|
||||
File outputDir = outputFile.getParentFile();
|
||||
assert outputDir != null : "Parent file for output file should not be null, outputFilePath: " + outputFile.getPath();
|
||||
OutputUtilsPackage.writeAllTo(status.getResult(), outputDir);
|
||||
OutputUtilsPackage.writeAllTo(outputFiles, outputDir);
|
||||
}
|
||||
|
||||
protected File getOutputPostfixFile() {
|
||||
|
||||
@@ -66,48 +66,6 @@ public final class K2JSTranslator {
|
||||
public static final String FLUSH_SYSTEM_OUT = "Kotlin.out.flush();\n";
|
||||
public static final String GET_SYSTEM_OUT = "Kotlin.out.buffer;\n";
|
||||
|
||||
public static Status<OutputFileCollection> translateWithMainCallParameters(
|
||||
@NotNull MainCallParameters mainCall,
|
||||
@NotNull List<JetFile> files,
|
||||
@NotNull File outputFile,
|
||||
@Nullable File outputPrefixFile,
|
||||
@Nullable File outputPostfixFile,
|
||||
@NotNull Config config,
|
||||
@NotNull Consumer<JsNode> astConsumer // hack for tests
|
||||
) throws TranslationException, IOException {
|
||||
K2JSTranslator translator = new K2JSTranslator(config);
|
||||
TextOutputImpl output = new TextOutputImpl();
|
||||
SourceMapBuilder sourceMapBuilder = config.isSourcemap() ? new SourceMap3Builder(outputFile, output, new SourceMapBuilderConsumer()) : null;
|
||||
Status<String> codeStatus = translator.generateProgramCode(files, mainCall, output, sourceMapBuilder, astConsumer);
|
||||
|
||||
if (codeStatus.isFail()) return Status.fail();
|
||||
|
||||
String programCode = codeStatus.getResult();
|
||||
String prefix = FileUtilsPackage.readTextOrEmpty(outputPrefixFile);
|
||||
String postfix = FileUtilsPackage.readTextOrEmpty(outputPostfixFile);
|
||||
|
||||
List<File> sourceFiles = ContainerUtil.map(files, new Function<JetFile, File>() {
|
||||
@Override
|
||||
public File fun(JetFile file) {
|
||||
VirtualFile virtualFile = file.getOriginalFile().getVirtualFile();
|
||||
if (virtualFile == null) return new File(file.getName());
|
||||
return VfsUtilCore.virtualToIoFile(virtualFile);
|
||||
}
|
||||
});
|
||||
|
||||
SimpleOutputFile jsFile = new SimpleOutputFile(sourceFiles, outputFile.getName(), prefix + programCode + postfix);
|
||||
List<SimpleOutputFile> outputFiles = new SmartList<SimpleOutputFile>(jsFile);
|
||||
|
||||
if (sourceMapBuilder != null) {
|
||||
sourceMapBuilder.skipLinesAtBeginning(StringUtil.getLineBreakCount(prefix));
|
||||
SimpleOutputFile sourceMapFile = new SimpleOutputFile(sourceFiles, sourceMapBuilder.getOutFile().getName(), sourceMapBuilder.build());
|
||||
outputFiles.add(sourceMapFile);
|
||||
}
|
||||
|
||||
OutputFileCollection outputFileCollection = new SimpleOutputFileCollection(outputFiles);
|
||||
return Status.success(outputFileCollection);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private final Config config;
|
||||
|
||||
@@ -115,38 +73,10 @@ public final class K2JSTranslator {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
//NOTE: web demo related method
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
@NotNull
|
||||
public Status<String> translateStringWithCallToMain(@NotNull String programText, @NotNull String argumentsString) throws TranslationException {
|
||||
JetFile file = JetPsiFactory(getProject()).createFile("test", programText);
|
||||
Status<String> status = generateProgramCode(file, MainCallParameters.mainWithArguments(parseString(argumentsString)));
|
||||
|
||||
if (status.isFail()) return status;
|
||||
|
||||
String code = FLUSH_SYSTEM_OUT + status.getResult() + "\n" + GET_SYSTEM_OUT;
|
||||
return Status.success(code);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Status<String> generateProgramCode(@NotNull JetFile file, @NotNull MainCallParameters mainCallParameters) throws TranslationException {
|
||||
return generateProgramCode(Collections.singletonList(file), mainCallParameters);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Status<String> generateProgramCode(@NotNull List<JetFile> files, @NotNull MainCallParameters mainCallParameters)
|
||||
throws TranslationException {
|
||||
//noinspection unchecked
|
||||
return generateProgramCode(files, mainCallParameters, new TextOutputImpl(), null, Consumer.EMPTY_CONSUMER);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Status<String> generateProgramCode(
|
||||
public TranslationResult translate(
|
||||
@NotNull List<JetFile> files,
|
||||
@NotNull MainCallParameters mainCallParameters,
|
||||
@NotNull TextOutputImpl output,
|
||||
@Nullable SourceMapBuilder sourceMapBuilder,
|
||||
@NotNull Consumer<JsNode> astConsumer
|
||||
@NotNull MainCallParameters mainCallParameters
|
||||
) throws TranslationException {
|
||||
JsAnalysisResult analysisResult = TopDownAnalyzerFacadeForJS.analyzeFiles(files, Predicates.<PsiFile>alwaysTrue(), config);
|
||||
BindingTrace bindingTrace = analysisResult.getBindingTrace();
|
||||
@@ -155,17 +85,9 @@ public final class K2JSTranslator {
|
||||
JsProgram program = Translation.generateAst(bindingTrace, files, mainCallParameters, moduleDescriptor, config);
|
||||
Diagnostics diagnostics = bindingTrace.getBindingContext().getDiagnostics();
|
||||
|
||||
if (hasError(diagnostics)) return Status.fail();
|
||||
if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics);
|
||||
|
||||
program = JsInliner.process(program);
|
||||
program.accept(new JsSourceGenerationVisitor(output, sourceMapBuilder));
|
||||
astConsumer.consume(program);
|
||||
|
||||
return Status.success(output.toString());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Project getProject() {
|
||||
return config.getProject();
|
||||
return new TranslationResult.Success(config, files, program, diagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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 kotlin.platform.platformStatic
|
||||
|
||||
public class Status<out T> private (private val _result: T, private val type: Status.Type) {
|
||||
class object {
|
||||
platformStatic fun fail<T>(): Status<T> = Status<T>(null, Type.Fail)
|
||||
|
||||
platformStatic fun success<T>(value: T): Status<T> = Status(value, Type.Success)
|
||||
}
|
||||
|
||||
public val result: T
|
||||
get() {
|
||||
assert(type == Type.Success) { "Getting result from fail status is illegal" }
|
||||
return _result
|
||||
}
|
||||
|
||||
public fun isFail(): Boolean = type == Type.Fail
|
||||
|
||||
public fun isSuccess(): Boolean = type == Type.Success
|
||||
|
||||
private enum class Type {
|
||||
Fail
|
||||
Success
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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 org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import com.google.dart.compiler.backend.js.ast.JsProgram
|
||||
import kotlin.properties.Delegates
|
||||
import org.jetbrains.kotlin.js.sourceMap.SourceMapBuilder
|
||||
import com.google.dart.compiler.util.TextOutputImpl
|
||||
import org.jetbrains.kotlin.js.config.Config
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection
|
||||
import org.jetbrains.kotlin.js.sourceMap.JsSourceGenerationVisitor
|
||||
import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
|
||||
import com.google.dart.compiler.util.TextOutput
|
||||
import java.io.File
|
||||
import org.jetbrains.kotlin.utils.fileUtils.readTextOrEmpty
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFile
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection
|
||||
|
||||
public abstract class TranslationResult protected (public val diagnostics: Diagnostics) {
|
||||
|
||||
public class Fail(diagnostics: Diagnostics) : TranslationResult(diagnostics)
|
||||
|
||||
public class Success(
|
||||
private val config: Config,
|
||||
private val files: List<JetFile>,
|
||||
public val program: JsProgram,
|
||||
diagnostics: Diagnostics
|
||||
) : TranslationResult(diagnostics) {
|
||||
public fun getCode(): String = getCode(TextOutputImpl(), sourceMapBuilder = null)
|
||||
|
||||
public fun getOutputFiles(outputFile: File, outputPrefixFile: File?, outputPostfixFile: File?): OutputFileCollection {
|
||||
val output = TextOutputImpl()
|
||||
val sourceMapBuilder = when {
|
||||
config.isSourcemap() -> SourceMap3Builder(outputFile, output, SourceMapBuilderConsumer())
|
||||
else -> null
|
||||
}
|
||||
|
||||
val code = getCode(output, sourceMapBuilder)
|
||||
val prefix = outputPrefixFile?.readTextOrEmpty() ?: ""
|
||||
val postfix = outputPostfixFile?.readTextOrEmpty() ?: ""
|
||||
val sourceFiles = files.map {
|
||||
val virtualFile = it.getOriginalFile().getVirtualFile()
|
||||
|
||||
when {
|
||||
virtualFile == null -> File(it.getName())
|
||||
else -> VfsUtilCore.virtualToIoFile(virtualFile)
|
||||
}
|
||||
}
|
||||
|
||||
val jsFile = SimpleOutputFile(sourceFiles, outputFile.getName(), prefix + code + postfix)
|
||||
val outputFiles = arrayListOf(jsFile)
|
||||
|
||||
if (sourceMapBuilder != null) {
|
||||
sourceMapBuilder.skipLinesAtBeginning(StringUtil.getLineBreakCount(prefix))
|
||||
val sourceMapFile = SimpleOutputFile(sourceFiles, sourceMapBuilder.getOutFile().getName(), sourceMapBuilder.build())
|
||||
outputFiles.add(sourceMapFile)
|
||||
}
|
||||
|
||||
return SimpleOutputFileCollection(outputFiles)
|
||||
}
|
||||
|
||||
private fun getCode(output: TextOutput, sourceMapBuilder: SourceMapBuilder?): String {
|
||||
program.accept(JsSourceGenerationVisitor(output, sourceMapBuilder))
|
||||
return output.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user