JS backend: started to implement source maps
#KT-927 in progress (cherry picked from commits 5543cda, 6ed296b, 11186f9, 5b84d0b)
This commit is contained in:
@@ -153,11 +153,11 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
EcmaVersion ecmaVersion = EcmaVersion.fromString(arguments.target);
|
||||
String moduleId = FileUtil.getNameWithoutExtension(new File(arguments.outputFile));
|
||||
if (arguments.libraryFiles != null) {
|
||||
return new LibrarySourcesConfig(project, moduleId, Arrays.asList(arguments.libraryFiles), ecmaVersion);
|
||||
return new LibrarySourcesConfig(project, moduleId, Arrays.asList(arguments.libraryFiles), ecmaVersion, arguments.sourcemap);
|
||||
}
|
||||
else {
|
||||
// lets discover the JS library definitions on the classpath
|
||||
return new ClassPathLibraryDefintionsConfig(project, moduleId, ecmaVersion);
|
||||
return new ClassPathLibraryDefintionsConfig(project, moduleId, ecmaVersion, arguments.sourcemap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,9 @@ public class K2JSCompilerArguments extends CompilerArguments {
|
||||
@Argument(value = "sourceFiles", description = "Source files (dir or file)")
|
||||
public String[] sourceFiles;
|
||||
|
||||
@Argument(value = "sourcemap", description = "Generate SourceMap")
|
||||
public boolean sourcemap;
|
||||
|
||||
@Argument(value = "target", description = "Generate js files for specific ECMA version (3 or 5, default ECMA 3)")
|
||||
public String target;
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class JSDeclarationsCacheProvider extends DeclarationsCacheProvider {
|
||||
LibrarySourcesConfig config = new LibrarySourcesConfig(
|
||||
project, "default",
|
||||
KotlinFrameworkDetector.getLibLocationAndTargetForProject(project).first,
|
||||
EcmaVersion.defaultVersion());
|
||||
EcmaVersion.defaultVersion(), false);
|
||||
|
||||
AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJS.analyzeFiles(
|
||||
JetFilesProvider.getInstance(project).allInScope(GlobalSearchScope.allScope(project)),
|
||||
|
||||
@@ -18,12 +18,13 @@ package org.jetbrains.jet.plugin.project;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector;
|
||||
import org.jetbrains.k2js.config.EcmaVersion;
|
||||
import org.jetbrains.k2js.config.LibrarySourcesConfig;
|
||||
|
||||
import static org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector.getLibLocationAndTargetForProject;
|
||||
|
||||
public final class IDEAConfig extends LibrarySourcesConfig {
|
||||
public IDEAConfig(@NotNull Project project) {
|
||||
super(project, "default", KotlinFrameworkDetector.getLibLocationAndTargetForProject(project).first, EcmaVersion.defaultVersion());
|
||||
super(project, "default", getLibLocationAndTargetForProject(project).first, EcmaVersion.defaultVersion(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.k2js.test.utils;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.dart.compiler.backend.js.ast.JsProgram;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -32,11 +31,13 @@ import org.jetbrains.k2js.config.Config;
|
||||
import org.jetbrains.k2js.config.EcmaVersion;
|
||||
import org.jetbrains.k2js.facade.K2JSTranslator;
|
||||
import org.jetbrains.k2js.facade.MainCallParameters;
|
||||
import org.jetbrains.k2js.generate.CodeGenerator;
|
||||
import org.jetbrains.k2js.test.config.TestConfigFactory;
|
||||
import org.jetbrains.k2js.utils.JetFileUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.List;
|
||||
|
||||
@@ -70,6 +71,7 @@ public final class TranslationUtils {
|
||||
Predicate<PsiFile> filesWithCode = new Predicate<PsiFile>() {
|
||||
@Override
|
||||
public boolean apply(@javax.annotation.Nullable PsiFile file) {
|
||||
assert file != null;
|
||||
return isFileWithCode((JetFile) file);
|
||||
}
|
||||
};
|
||||
@@ -102,14 +104,8 @@ public final class TranslationUtils {
|
||||
@NotNull MainCallParameters mainCallParameters,
|
||||
@NotNull EcmaVersion version, TestConfigFactory configFactory) throws Exception {
|
||||
List<JetFile> psiFiles = createPsiFileList(inputFiles, project);
|
||||
JsProgram program = new K2JSTranslator(getConfig(project, version, configFactory)).generateProgram(psiFiles, mainCallParameters);
|
||||
FileWriter writer = new FileWriter(new File(outputFile));
|
||||
try {
|
||||
writer.write(CodeGenerator.generateProgramToString(program));
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
K2JSTranslator translator = new K2JSTranslator(getConfig(project, version, configFactory));
|
||||
FileUtil.writeToFile(new File(outputFile), translator.generateProgramCode(psiFiles, mainCallParameters));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+2
-2
@@ -30,8 +30,8 @@ public class ClassPathLibraryDefintionsConfig extends Config {
|
||||
@NotNull
|
||||
public static final String META_INF_SERVICES_FILE = "META-INF/services/org.jetbrains.kotlin.js.libraryDefinitions";
|
||||
|
||||
public ClassPathLibraryDefintionsConfig(@NotNull Project project, @NotNull String moduleId, @NotNull EcmaVersion version) {
|
||||
super(project, moduleId, version);
|
||||
public ClassPathLibraryDefintionsConfig(@NotNull Project project, @NotNull String moduleId, @NotNull EcmaVersion version, boolean sourcemap) {
|
||||
super(project, moduleId, version, sourcemap);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -149,10 +149,21 @@ public abstract class Config {
|
||||
@NotNull
|
||||
private final String moduleId;
|
||||
|
||||
private final boolean sourcemap;
|
||||
|
||||
public Config(@NotNull Project project, @NotNull String moduleId, @NotNull EcmaVersion ecmaVersion) {
|
||||
this(project, moduleId, ecmaVersion, false);
|
||||
}
|
||||
|
||||
public Config(@NotNull Project project, @NotNull String moduleId, @NotNull EcmaVersion ecmaVersion, boolean sourcemap) {
|
||||
this.project = project;
|
||||
this.target = ecmaVersion;
|
||||
this.moduleId = moduleId;
|
||||
this.sourcemap = sourcemap;
|
||||
}
|
||||
|
||||
public boolean isSourcemap() {
|
||||
return sourcemap;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.k2js.config;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.k2js.utils.JetFileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class LibrarySourceDirectoriesConfig extends Config {
|
||||
@NotNull
|
||||
protected final String[] directories;
|
||||
|
||||
public LibrarySourceDirectoriesConfig(@NotNull Project project, @NotNull String moduleId, @NotNull String[] directories, @NotNull EcmaVersion ecmaVersion) {
|
||||
super(project, moduleId, ecmaVersion);
|
||||
this.directories = directories;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetFile> generateLibFiles() {
|
||||
try {
|
||||
List<JetFile> results = Lists.newArrayList();
|
||||
for (String directory : directories) {
|
||||
File rootDir = new File(directory);
|
||||
results.addAll(traverseDirectory(rootDir, rootDir));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.out.println("Caught: " + e);
|
||||
e.printStackTrace();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JetFile> traverseDirectory(@NotNull File rootDir, @NotNull File dir) throws IOException {
|
||||
File[] files = dir.listFiles();
|
||||
File[] children = dir.listFiles();
|
||||
List<JetFile> result = Lists.newArrayList();
|
||||
if (children != null && children.length > 0) {
|
||||
for (File child : children) {
|
||||
if (child.isDirectory()) {
|
||||
List<JetFile> childFiles = traverseDirectory(rootDir, child);
|
||||
result.addAll(childFiles);
|
||||
}
|
||||
else {
|
||||
String name = child.getName();
|
||||
if (name.toLowerCase().endsWith(".kt")) {
|
||||
String text = FileUtil.loadFile(child);
|
||||
//String path = FileUtil.getRelativePath(directoryFile, child);
|
||||
String path = child.getPath();
|
||||
JetFile jfile = JetFileUtils.createPsiFile(path, text, getProject());
|
||||
result.add(jfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -47,11 +47,14 @@ public class LibrarySourcesConfig extends Config {
|
||||
@NotNull
|
||||
private final List<String> files;
|
||||
|
||||
public LibrarySourcesConfig(@NotNull Project project,
|
||||
public LibrarySourcesConfig(
|
||||
@NotNull Project project,
|
||||
@NotNull String moduleId,
|
||||
@NotNull List<String> files,
|
||||
@NotNull EcmaVersion ecmaVersion) {
|
||||
super(project, moduleId, ecmaVersion);
|
||||
@NotNull EcmaVersion ecmaVersion,
|
||||
boolean sourcemap
|
||||
) {
|
||||
super(project, moduleId, ecmaVersion, sourcemap);
|
||||
this.files = files;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
|
||||
package org.jetbrains.k2js.facade;
|
||||
|
||||
import com.google.dart.compiler.backend.js.JsSourceGenerationVisitor;
|
||||
import com.google.dart.compiler.backend.js.ast.JsProgram;
|
||||
import com.google.dart.compiler.util.TextOutputImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.js.compiler.SourceMapBuilder;
|
||||
import org.jetbrains.k2js.analyze.AnalyzerFacadeForJS;
|
||||
import org.jetbrains.k2js.config.Config;
|
||||
import org.jetbrains.k2js.facade.exceptions.TranslationException;
|
||||
@@ -30,11 +34,10 @@ import org.jetbrains.k2js.utils.JetFileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.facade.FacadeUtils.parseString;
|
||||
import static org.jetbrains.k2js.generate.CodeGenerator.generateProgramToString;
|
||||
|
||||
/**
|
||||
* An entry point of translator.
|
||||
@@ -49,8 +52,14 @@ public final class K2JSTranslator {
|
||||
@NotNull String outputPath,
|
||||
@NotNull Config config) throws TranslationException, IOException {
|
||||
K2JSTranslator translator = new K2JSTranslator(config);
|
||||
String programCode = translator.generateProgramCode(files, mainCall);
|
||||
FileUtil.writeToFile(new File(outputPath), programCode);
|
||||
File outFile = new File(outputPath);
|
||||
TextOutputImpl output = new TextOutputImpl();
|
||||
SourceMapBuilder sourceMapBuilder = config.isSourcemap() ? new SourceMapBuilder(outFile.getName(), output, new SourceMapBuilderConsumer()) : null;
|
||||
String programCode = translator.generateProgramCode(files, mainCall, output, sourceMapBuilder);
|
||||
FileUtil.writeToFile(outFile, programCode);
|
||||
if (sourceMapBuilder != null) {
|
||||
FileUtil.writeToFile(new File(outFile.getParentFile(), sourceMapBuilder.getOutFilename()), sourceMapBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -72,15 +81,26 @@ public final class K2JSTranslator {
|
||||
|
||||
@NotNull
|
||||
public String generateProgramCode(@NotNull JetFile file, @NotNull MainCallParameters mainCallParameters) throws TranslationException {
|
||||
JsProgram program = generateProgram(Arrays.asList(file), mainCallParameters);
|
||||
return generateProgramToString(program);
|
||||
return generateProgramCode(Collections.singletonList(file), mainCallParameters);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String generateProgramCode(@NotNull List<JetFile> files, @NotNull MainCallParameters mainCallParameters)
|
||||
throws TranslationException {
|
||||
return generateProgramCode(files, mainCallParameters, new TextOutputImpl(), null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String generateProgramCode(
|
||||
@NotNull List<JetFile> files,
|
||||
@NotNull MainCallParameters mainCallParameters,
|
||||
@NotNull TextOutputImpl output,
|
||||
@Nullable SourceMapBuilder sourceMapBuilder
|
||||
) throws TranslationException {
|
||||
JsProgram program = generateProgram(files, mainCallParameters);
|
||||
return generateProgramToString(program);
|
||||
JsSourceGenerationVisitor sourceGenerator = new JsSourceGenerationVisitor(output, sourceMapBuilder);
|
||||
program.traverse(sourceGenerator, null);
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -95,4 +115,4 @@ public final class K2JSTranslator {
|
||||
private Project getProject() {
|
||||
return config.getProject();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.k2js.facade;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.PairConsumer;
|
||||
import org.jetbrains.js.compiler.SourceMapBuilder;
|
||||
|
||||
class SourceMapBuilderConsumer implements PairConsumer<SourceMapBuilder, Object> {
|
||||
@Override
|
||||
public void consume(SourceMapBuilder builder, Object sourceInfo) {
|
||||
if (!(sourceInfo instanceof PsiElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement element = (PsiElement) sourceInfo;
|
||||
PsiFile file = element.getContainingFile();
|
||||
int offset = element.getNode().getStartOffset();
|
||||
Document document = file.getViewProvider().getDocument();
|
||||
assert document != null;
|
||||
int line = document.getLineNumber(offset);
|
||||
int column = offset - document.getLineStartOffset(line);
|
||||
builder.addMapping(file.getViewProvider().getVirtualFile().getPath(), line, column);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.k2js.generate;
|
||||
|
||||
import com.google.dart.compiler.backend.js.JsSourceGenerationVisitor;
|
||||
import com.google.dart.compiler.backend.js.ast.JsProgram;
|
||||
import com.google.dart.compiler.util.TextOutputImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class CodeGenerator {
|
||||
private CodeGenerator() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String generateProgramToString(@NotNull JsProgram program) {
|
||||
TextOutputImpl output = new TextOutputImpl();
|
||||
JsSourceGenerationVisitor sourceGenerator = new JsSourceGenerationVisitor(output);
|
||||
program.traverse(sourceGenerator, null);
|
||||
return output.toString();
|
||||
}
|
||||
}
|
||||
@@ -121,8 +121,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
@NotNull TranslationContext context) {
|
||||
JetExpression returnedExpression = jetReturnExpression.getReturnedExpression();
|
||||
if (returnedExpression != null) {
|
||||
JsExpression jsExpression = translateAsExpression(returnedExpression, context);
|
||||
return new JsReturn(jsExpression);
|
||||
return new JsReturn(translateAsExpression(returnedExpression, context));
|
||||
}
|
||||
return new JsReturn();
|
||||
}
|
||||
|
||||
@@ -88,7 +88,9 @@ public final class Translation {
|
||||
//NOTE: use with care
|
||||
@NotNull
|
||||
public static JsNode doTranslateExpression(JetExpression expression, TranslationContext context) {
|
||||
return expression.accept(new ExpressionVisitor(), context);
|
||||
JsNode jsNode = expression.accept(new ExpressionVisitor(), context);
|
||||
jsNode.setSourceInfo(expression);
|
||||
return jsNode;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -16,19 +16,13 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.utils;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.common.SourceInfo;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class ErrorReportingUtils {
|
||||
private ErrorReportingUtils() {
|
||||
}
|
||||
@@ -66,17 +60,4 @@ public final class ErrorReportingUtils {
|
||||
@NotNull BindingContext bindingContext) {
|
||||
throw reportErrorWithLocation(e, DiagnosticUtils.atLocation(bindingContext, descriptor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String atLocation(@Nullable JsExpression expression, @NotNull List<JsExpression> arguments) {
|
||||
List<JsExpression> list = Lists.newArrayList(expression);
|
||||
list.addAll(arguments);
|
||||
for (JsExpression value : arguments) {
|
||||
SourceInfo info = value.getSourceInfo();
|
||||
if (info != null) {
|
||||
return "at " + info.getSource().getUri() + " " + info.getLine() + ":" + info.getColumn();
|
||||
}
|
||||
}
|
||||
return "at unknown location";
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -45,14 +45,14 @@ public final class LastExpressionMutator {
|
||||
if (node instanceof JsIf) {
|
||||
return applyToIf((JsIf) node);
|
||||
}
|
||||
if (node instanceof JsExprStmt) {
|
||||
return applyToStatement((JsExprStmt) node);
|
||||
if (node instanceof JsExpressionStatement) {
|
||||
return applyToStatement((JsExpressionStatement) node);
|
||||
}
|
||||
return mutator.mutate(node);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsNode applyToStatement(@NotNull JsExprStmt node) {
|
||||
private JsNode applyToStatement(@NotNull JsExpressionStatement node) {
|
||||
return convertToStatement(apply(node.getExpression()));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user