mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Adds source maps generation
This commit is contained in:
parent
5b0506d158
commit
7cb3ce70c3
|
@ -62,6 +62,10 @@ public class TeaVMRunner {
|
||||||
.withDescription("Generate debug information")
|
.withDescription("Generate debug information")
|
||||||
.withLongOpt("debug")
|
.withLongOpt("debug")
|
||||||
.create('D'));
|
.create('D'));
|
||||||
|
options.addOption(OptionBuilder
|
||||||
|
.withDescription("Generate source maps")
|
||||||
|
.withLongOpt("sourcemaps")
|
||||||
|
.create());
|
||||||
options.addOption(OptionBuilder
|
options.addOption(OptionBuilder
|
||||||
.withArgName("number")
|
.withArgName("number")
|
||||||
.hasArg()
|
.hasArg()
|
||||||
|
@ -126,6 +130,9 @@ public class TeaVMRunner {
|
||||||
}
|
}
|
||||||
if (commandLine.hasOption('D')) {
|
if (commandLine.hasOption('D')) {
|
||||||
tool.setDebugInformation(new File(tool.getTargetDirectory(), tool.getTargetFileName() + ".teavmdbg"));
|
tool.setDebugInformation(new File(tool.getTargetDirectory(), tool.getTargetFileName() + ".teavmdbg"));
|
||||||
|
if (commandLine.hasOption("sourcemaps")) {
|
||||||
|
tool.setSourceMapsFileGenerated(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
args = commandLine.getArgs();
|
args = commandLine.getArgs();
|
||||||
if (args.length > 1) {
|
if (args.length > 1) {
|
||||||
|
|
|
@ -15,10 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.debugging;
|
package org.teavm.debugging;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.teavm.common.IntegerArray;
|
import org.teavm.common.IntegerArray;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
|
@ -296,6 +293,10 @@ public class DebugInformation {
|
||||||
writer.write(this);
|
writer.write(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeAsSourceMaps(Writer output, String sourceFile) throws IOException {
|
||||||
|
new SourceMapsWriter(output).write(sourceFile, this);
|
||||||
|
}
|
||||||
|
|
||||||
public static DebugInformation read(InputStream input) throws IOException {
|
public static DebugInformation read(InputStream input) throws IOException {
|
||||||
DebugInformationReader reader = new DebugInformationReader(input);
|
DebugInformationReader reader = new DebugInformationReader(input);
|
||||||
return reader.read();
|
return reader.read();
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* 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.teavm.debugging;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
class SourceMapsWriter {
|
||||||
|
private static final String BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
private Writer output;
|
||||||
|
private int lastLine;
|
||||||
|
private int lastColumn;
|
||||||
|
private int sourceLine;
|
||||||
|
private int lastSourceLine;
|
||||||
|
private int sourceFile;
|
||||||
|
private int lastSourceFile;
|
||||||
|
private boolean first;
|
||||||
|
|
||||||
|
public SourceMapsWriter(Writer output) {
|
||||||
|
this.output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(String generatedFile, DebugInformation debugInfo) throws IOException {
|
||||||
|
output.write("{\"version\":3");
|
||||||
|
output.write(",\"file\":\"");
|
||||||
|
writeEscapedString(generatedFile);
|
||||||
|
output.write("\"");
|
||||||
|
output.write(",\"sourceRoot\":\"\"");
|
||||||
|
output.write(",\"sources\":[");
|
||||||
|
for (int i = 0; i < debugInfo.fileNames.length; ++i) {
|
||||||
|
if (i > 0) {
|
||||||
|
output.write(',');
|
||||||
|
}
|
||||||
|
output.write("\"");
|
||||||
|
writeEscapedString(debugInfo.fileNames[i]);
|
||||||
|
output.write("\"");
|
||||||
|
}
|
||||||
|
output.write("]");
|
||||||
|
output.write(",\"names\":[]");
|
||||||
|
output.write(",\"mappings\":\"");
|
||||||
|
first = true;
|
||||||
|
lastLine = 0;
|
||||||
|
lastColumn = 0;
|
||||||
|
sourceLine = -1;
|
||||||
|
sourceFile = -1;
|
||||||
|
lastSourceFile = 0;
|
||||||
|
lastSourceLine = 0;
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
while (i < debugInfo.lineMapping.lines.length && j < debugInfo.fileMapping.lines.length) {
|
||||||
|
GeneratedLocation a = debugInfo.lineMapping.key(i);
|
||||||
|
GeneratedLocation b = debugInfo.fileMapping.key(j);
|
||||||
|
int cmp = a.compareTo(b);
|
||||||
|
if (cmp < 0) {
|
||||||
|
writeSegment(a, sourceFile, debugInfo.lineMapping.values[i++]);
|
||||||
|
} else if (cmp > 0) {
|
||||||
|
writeSegment(b, debugInfo.fileMapping.values[j++], sourceLine);
|
||||||
|
} else {
|
||||||
|
writeSegment(a, debugInfo.fileMapping.values[j++], debugInfo.lineMapping.values[i++] - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (i < debugInfo.lineMapping.lines.length) {
|
||||||
|
GeneratedLocation a = debugInfo.lineMapping.key(i);
|
||||||
|
writeSegment(a, sourceFile, debugInfo.lineMapping.values[i++]);
|
||||||
|
}
|
||||||
|
while (j < debugInfo.fileMapping.lines.length) {
|
||||||
|
GeneratedLocation b = debugInfo.fileMapping.key(j);
|
||||||
|
writeSegment(b, debugInfo.fileMapping.values[j++], sourceLine);
|
||||||
|
}
|
||||||
|
output.write("\"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeSegment(GeneratedLocation loc, int sourceFile, int sourceLine) throws IOException {
|
||||||
|
while (loc.getLine() > lastLine) {
|
||||||
|
output.write(';');
|
||||||
|
++lastLine;
|
||||||
|
first = true;
|
||||||
|
lastColumn = 0;
|
||||||
|
}
|
||||||
|
if (!first) {
|
||||||
|
output.write(',');
|
||||||
|
}
|
||||||
|
writeVLQ(loc.getColumn() - lastColumn);
|
||||||
|
if (sourceFile >= 0 && sourceLine >= 0) {
|
||||||
|
writeVLQ(sourceFile - lastSourceFile);
|
||||||
|
writeVLQ(sourceLine - lastSourceLine);
|
||||||
|
writeVLQ(0);
|
||||||
|
lastSourceFile = sourceFile;
|
||||||
|
lastSourceLine = sourceLine;
|
||||||
|
}
|
||||||
|
lastColumn = loc.getColumn();
|
||||||
|
this.sourceFile = sourceFile;
|
||||||
|
this.sourceLine = sourceLine;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeEscapedString(String str) throws IOException {
|
||||||
|
for (int i = 0; i < str.length(); ++i) {
|
||||||
|
char c = str.charAt(i);
|
||||||
|
switch (c) {
|
||||||
|
case '\n':
|
||||||
|
output.write("\\n");
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
output.write("\\r");
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
output.write("\\t");
|
||||||
|
break;
|
||||||
|
case '\b':
|
||||||
|
output.write("\\b");
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
output.write("\\\\");
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
output.write("\\\"");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
output.write(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeVLQ(int number) throws IOException {
|
||||||
|
if (number < 0) {
|
||||||
|
number = ((-number) << 1) | 1;
|
||||||
|
} else {
|
||||||
|
number = number << 1;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
int digit = number & 0x1F;
|
||||||
|
int next = number >>> 5;
|
||||||
|
if (next != 0) {
|
||||||
|
digit |= 0x20;
|
||||||
|
}
|
||||||
|
output.write(BASE64_CHARS.charAt(digit));
|
||||||
|
number = next;
|
||||||
|
} while (number != 0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.teavm.common.ThreadPoolFiniteExecutor;
|
import org.teavm.common.ThreadPoolFiniteExecutor;
|
||||||
|
import org.teavm.debugging.DebugInformation;
|
||||||
import org.teavm.debugging.DebugInformationBuilder;
|
import org.teavm.debugging.DebugInformationBuilder;
|
||||||
import org.teavm.javascript.RenderingContext;
|
import org.teavm.javascript.RenderingContext;
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
|
@ -45,6 +46,8 @@ public class TeaVMTool {
|
||||||
private boolean mainPageIncluded;
|
private boolean mainPageIncluded;
|
||||||
private boolean bytecodeLogging;
|
private boolean bytecodeLogging;
|
||||||
private File debugInformation;
|
private File debugInformation;
|
||||||
|
private String sourceMapsFileName;
|
||||||
|
private boolean sourceMapsFileGenerated;
|
||||||
private int numThreads = 1;
|
private int numThreads = 1;
|
||||||
private List<ClassHolderTransformer> transformers = new ArrayList<>();
|
private List<ClassHolderTransformer> transformers = new ArrayList<>();
|
||||||
private List<ClassAlias> classAliases = new ArrayList<>();
|
private List<ClassAlias> classAliases = new ArrayList<>();
|
||||||
|
@ -124,6 +127,22 @@ public class TeaVMTool {
|
||||||
this.numThreads = numThreads;
|
this.numThreads = numThreads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSourceMapsFileName() {
|
||||||
|
return sourceMapsFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceMapsFileName(String sourceMapsFileName) {
|
||||||
|
this.sourceMapsFileName = sourceMapsFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSourceMapsFileGenerated() {
|
||||||
|
return sourceMapsFileGenerated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated) {
|
||||||
|
this.sourceMapsFileGenerated = sourceMapsFileGenerated;
|
||||||
|
}
|
||||||
|
|
||||||
public Properties getProperties() {
|
public Properties getProperties() {
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
@ -218,10 +237,23 @@ public class TeaVMTool {
|
||||||
vm.checkForMissingItems();
|
vm.checkForMissingItems();
|
||||||
log.info("JavaScript file successfully built");
|
log.info("JavaScript file successfully built");
|
||||||
if (debugInformation != null) {
|
if (debugInformation != null) {
|
||||||
|
DebugInformation debugInfo = debugEmitter.getDebugInformation();
|
||||||
try (OutputStream debugInfoOut = new FileOutputStream(debugInformation)) {
|
try (OutputStream debugInfoOut = new FileOutputStream(debugInformation)) {
|
||||||
debugEmitter.getDebugInformation().write(debugInfoOut);
|
debugInfo.write(debugInfoOut);
|
||||||
}
|
}
|
||||||
log.info("Debug information successfully written");
|
log.info("Debug information successfully written");
|
||||||
|
if (sourceMapsFileGenerated) {
|
||||||
|
String sourceMapsFileName = this.sourceMapsFileName;
|
||||||
|
if (sourceMapsFileName == null) {
|
||||||
|
sourceMapsFileName = targetFileName + ".map";
|
||||||
|
}
|
||||||
|
writer.append("\n//# sourceMappingURL=").append(sourceMapsFileName);
|
||||||
|
try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream(
|
||||||
|
new File(targetDirectory, sourceMapsFileName)), "UTF-8")) {
|
||||||
|
debugInfo.writeAsSourceMaps(sourceMapsOut, targetFileName);
|
||||||
|
}
|
||||||
|
log.info("Source maps successfully written");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (runtime == RuntimeCopyOperation.SEPARATE) {
|
if (runtime == RuntimeCopyOperation.SEPARATE) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user