001    /*
002     * Copyright 2010-2013 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.k2js.facade;
018    
019    import com.google.dart.compiler.backend.js.ast.JsProgram;
020    import com.google.dart.compiler.util.TextOutputImpl;
021    import com.intellij.openapi.project.Project;
022    import com.intellij.openapi.util.io.FileUtil;
023    import org.jetbrains.annotations.NotNull;
024    import org.jetbrains.annotations.Nullable;
025    import org.jetbrains.jet.lang.psi.JetFile;
026    import org.jetbrains.jet.lang.resolve.BindingContext;
027    import org.jetbrains.js.compiler.JsSourceGenerationVisitor;
028    import org.jetbrains.js.compiler.SourceMapBuilder;
029    import org.jetbrains.js.compiler.sourcemap.SourceMap3Builder;
030    import org.jetbrains.k2js.analyze.AnalyzerFacadeForJS;
031    import org.jetbrains.k2js.config.Config;
032    import org.jetbrains.k2js.facade.exceptions.TranslationException;
033    import org.jetbrains.k2js.translate.general.Translation;
034    import org.jetbrains.k2js.utils.JetFileUtils;
035    
036    import java.io.File;
037    import java.io.IOException;
038    import java.util.Collections;
039    import java.util.List;
040    
041    import static org.jetbrains.k2js.facade.FacadeUtils.parseString;
042    
043    /**
044     * An entry point of translator.
045     */
046    public final class K2JSTranslator {
047    
048        public static final String FLUSH_SYSTEM_OUT = "Kotlin.System.flush();\n";
049        public static final String GET_SYSTEM_OUT = "Kotlin.System.output();\n";
050    
051        public static void translateWithMainCallParametersAndSaveToFile(@NotNull MainCallParameters mainCall,
052                @NotNull List<JetFile> files,
053                @NotNull String outputPath,
054                @NotNull Config config) throws TranslationException, IOException {
055            K2JSTranslator translator = new K2JSTranslator(config);
056            File outFile = new File(outputPath);
057            TextOutputImpl output = new TextOutputImpl();
058            SourceMapBuilder sourceMapBuilder = config.isSourcemap() ? new SourceMap3Builder(outFile, output, new SourceMapBuilderConsumer()) : null;
059            String programCode = translator.generateProgramCode(files, mainCall, output, sourceMapBuilder);
060            FileUtil.writeToFile(outFile, programCode);
061            if (sourceMapBuilder != null) {
062                FileUtil.writeToFile(sourceMapBuilder.getOutFile(), sourceMapBuilder.build());
063            }
064        }
065    
066        @NotNull
067        private final Config config;
068    
069    
070        public K2JSTranslator(@NotNull Config config) {
071            this.config = config;
072        }
073    
074        //NOTE: web demo related method
075        @SuppressWarnings("UnusedDeclaration")
076        @NotNull
077        public String translateStringWithCallToMain(@NotNull String programText, @NotNull String argumentsString) throws TranslationException {
078            JetFile file = JetFileUtils.createJetFile("test", programText, getProject());
079            String programCode = generateProgramCode(file, MainCallParameters.mainWithArguments(parseString(argumentsString))) + "\n";
080            return FLUSH_SYSTEM_OUT + programCode + GET_SYSTEM_OUT;
081        }
082    
083        @NotNull
084        public String generateProgramCode(@NotNull JetFile file, @NotNull MainCallParameters mainCallParameters) throws TranslationException {
085            return generateProgramCode(Collections.singletonList(file), mainCallParameters);
086        }
087    
088        @NotNull
089        public String generateProgramCode(@NotNull List<JetFile> files, @NotNull MainCallParameters mainCallParameters)
090                throws TranslationException {
091            return generateProgramCode(files, mainCallParameters, new TextOutputImpl(), null);
092        }
093    
094        @NotNull
095        public String generateProgramCode(
096                @NotNull List<JetFile> files,
097                @NotNull MainCallParameters mainCallParameters,
098                @NotNull TextOutputImpl output,
099                @Nullable SourceMapBuilder sourceMapBuilder
100        ) throws TranslationException {
101            JsProgram program = generateProgram(files, mainCallParameters);
102            JsSourceGenerationVisitor sourceGenerator = new JsSourceGenerationVisitor(output, sourceMapBuilder);
103            program.accept(sourceGenerator);
104            return output.toString();
105        }
106    
107        @NotNull
108        public JsProgram generateProgram(@NotNull List<JetFile> filesToTranslate,
109                @NotNull MainCallParameters mainCallParameters)
110                throws TranslationException {
111            BindingContext bindingContext = AnalyzerFacadeForJS.analyzeFilesAndCheckErrors(filesToTranslate, config);
112            return Translation.generateAst(bindingContext, filesToTranslate, mainCallParameters, config);
113        }
114    
115        @NotNull
116        private Project getProject() {
117            return config.getProject();
118        }
119    }