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.util.io.FileUtil;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import com.intellij.util.Consumer;
|
|
||||||
import com.intellij.util.Function;
|
import com.intellij.util.Function;
|
||||||
import com.intellij.util.SmartList;
|
import com.intellij.util.SmartList;
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
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.Config;
|
||||||
import org.jetbrains.kotlin.js.config.EcmaVersion;
|
import org.jetbrains.kotlin.js.config.EcmaVersion;
|
||||||
import org.jetbrains.kotlin.js.config.LibrarySourcesConfig;
|
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.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.psi.JetFile;
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics;
|
|
||||||
import org.jetbrains.kotlin.utils.PathUtil;
|
import org.jetbrains.kotlin.utils.PathUtil;
|
||||||
|
|
||||||
import java.io.File;
|
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.COMPILATION_ERROR;
|
||||||
import static org.jetbrains.kotlin.cli.common.ExitCode.OK;
|
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.cli.common.messages.CompilerMessageLocation.NO_LOCATION;
|
||||||
import static org.jetbrains.kotlin.js.facade.K2JSTranslator.translateWithMainCallParameters;
|
|
||||||
|
|
||||||
public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||||
|
|
||||||
@@ -159,22 +157,23 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MainCallParameters mainCallParameters = createMainCallParameters(arguments.main);
|
MainCallParameters mainCallParameters = createMainCallParameters(arguments.main);
|
||||||
Status<OutputFileCollection> status;
|
TranslationResult translationResult;
|
||||||
|
|
||||||
|
K2JSTranslator translator = new K2JSTranslator(config);
|
||||||
try {
|
try {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
status = translateWithMainCallParameters(mainCallParameters, sourcesFiles, outputFile, outputPrefixFile, outputPostfixFile,
|
translationResult = translator.translate(sourcesFiles, mainCallParameters);
|
||||||
config, Consumer.EMPTY_CONSUMER);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
Diagnostics diagnostics = config.getTrace().getBindingContext().getDiagnostics();
|
AnalyzerWithCompilerReport.reportDiagnostics(translationResult.getDiagnostics(), messageCollector);
|
||||||
AnalyzerWithCompilerReport.reportDiagnostics(diagnostics, 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()) {
|
if (outputFile.isDirectory()) {
|
||||||
messageCollector.report(CompilerMessageSeverity.ERROR,
|
messageCollector.report(CompilerMessageSeverity.ERROR,
|
||||||
"Cannot open output file '" + outputFile.getPath() + "': is a directory",
|
"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.EcmaVersion;
|
||||||
import org.jetbrains.kotlin.js.config.LibrarySourcesConfig;
|
import org.jetbrains.kotlin.js.config.LibrarySourcesConfig;
|
||||||
import org.jetbrains.kotlin.js.config.LibrarySourcesConfigWithCaching;
|
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.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.rhino.RhinoResultChecker;
|
||||||
import org.jetbrains.kotlin.js.test.utils.JsTestUtils;
|
import org.jetbrains.kotlin.js.test.utils.JsTestUtils;
|
||||||
import org.jetbrains.kotlin.js.translate.context.Namer;
|
import org.jetbrains.kotlin.js.translate.context.Namer;
|
||||||
@@ -57,7 +58,6 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.rhino.RhinoUtils.runRhinoTest;
|
||||||
import static org.jetbrains.kotlin.js.test.utils.JsTestUtils.convertFileNameToDotJsFile;
|
import static org.jetbrains.kotlin.js.test.utils.JsTestUtils.convertFileNameToDotJsFile;
|
||||||
|
|
||||||
@@ -175,15 +175,18 @@ public abstract class BasicTest extends KotlinTestWithEnvironment {
|
|||||||
@NotNull MainCallParameters mainCallParameters,
|
@NotNull MainCallParameters mainCallParameters,
|
||||||
@NotNull Config config
|
@NotNull Config config
|
||||||
) throws Exception {
|
) throws Exception {
|
||||||
Status<OutputFileCollection> status = translateWithMainCallParameters(mainCallParameters, jetFiles, outputFile,
|
K2JSTranslator translator = new K2JSTranslator(config);
|
||||||
getOutputPrefixFile(), getOutputPostfixFile(),
|
TranslationResult translationResult = translator.translate(jetFiles, mainCallParameters);
|
||||||
config, getConsumer());
|
|
||||||
|
|
||||||
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();
|
File outputDir = outputFile.getParentFile();
|
||||||
assert outputDir != null : "Parent file for output file should not be null, outputFilePath: " + outputFile.getPath();
|
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() {
|
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 FLUSH_SYSTEM_OUT = "Kotlin.out.flush();\n";
|
||||||
public static final String GET_SYSTEM_OUT = "Kotlin.out.buffer;\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
|
@NotNull
|
||||||
private final Config config;
|
private final Config config;
|
||||||
|
|
||||||
@@ -115,38 +73,10 @@ public final class K2JSTranslator {
|
|||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: web demo related method
|
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Status<String> translateStringWithCallToMain(@NotNull String programText, @NotNull String argumentsString) throws TranslationException {
|
public TranslationResult translate(
|
||||||
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(
|
|
||||||
@NotNull List<JetFile> files,
|
@NotNull List<JetFile> files,
|
||||||
@NotNull MainCallParameters mainCallParameters,
|
@NotNull MainCallParameters mainCallParameters
|
||||||
@NotNull TextOutputImpl output,
|
|
||||||
@Nullable SourceMapBuilder sourceMapBuilder,
|
|
||||||
@NotNull Consumer<JsNode> astConsumer
|
|
||||||
) throws TranslationException {
|
) throws TranslationException {
|
||||||
JsAnalysisResult analysisResult = TopDownAnalyzerFacadeForJS.analyzeFiles(files, Predicates.<PsiFile>alwaysTrue(), config);
|
JsAnalysisResult analysisResult = TopDownAnalyzerFacadeForJS.analyzeFiles(files, Predicates.<PsiFile>alwaysTrue(), config);
|
||||||
BindingTrace bindingTrace = analysisResult.getBindingTrace();
|
BindingTrace bindingTrace = analysisResult.getBindingTrace();
|
||||||
@@ -155,17 +85,9 @@ public final class K2JSTranslator {
|
|||||||
JsProgram program = Translation.generateAst(bindingTrace, files, mainCallParameters, moduleDescriptor, config);
|
JsProgram program = Translation.generateAst(bindingTrace, files, mainCallParameters, moduleDescriptor, config);
|
||||||
Diagnostics diagnostics = bindingTrace.getBindingContext().getDiagnostics();
|
Diagnostics diagnostics = bindingTrace.getBindingContext().getDiagnostics();
|
||||||
|
|
||||||
if (hasError(diagnostics)) return Status.fail();
|
if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics);
|
||||||
|
|
||||||
program = JsInliner.process(program);
|
program = JsInliner.process(program);
|
||||||
program.accept(new JsSourceGenerationVisitor(output, sourceMapBuilder));
|
return new TranslationResult.Success(config, files, program, diagnostics);
|
||||||
astConsumer.consume(program);
|
|
||||||
|
|
||||||
return Status.success(output.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Project getProject() {
|
|
||||||
return config.getProject();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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