mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
next step for source map #6
This commit is contained in:
parent
e5036cc053
commit
0b1ff00ae5
@ -34,6 +34,7 @@ import de.inetsoftware.jwebassembly.module.FunctionName;
|
|||||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||||
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
||||||
import de.inetsoftware.jwebassembly.module.WasmTarget;
|
import de.inetsoftware.jwebassembly.module.WasmTarget;
|
||||||
|
import de.inetsoftware.jwebassembly.sourcemap.SourceMapWriter;
|
||||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||||
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
|
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
|
||||||
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
||||||
@ -82,6 +83,8 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
|
|
||||||
private int exceptionSignatureIndex = -1;
|
private int exceptionSignatureIndex = -1;
|
||||||
|
|
||||||
|
private String javaSourceFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new instance.
|
* Create new instance.
|
||||||
*
|
*
|
||||||
@ -202,12 +205,16 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
if( size == 0 ) {
|
if( size == 0 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
SourceMapWriter sourceMap = new SourceMapWriter();
|
||||||
WasmOutputStream stream = new WasmOutputStream();
|
WasmOutputStream stream = new WasmOutputStream();
|
||||||
stream.writeVaruint32( size );
|
stream.writeVaruint32( size );
|
||||||
for( Function func : functions.values() ) {
|
for( Function func : functions.values() ) {
|
||||||
func.functionsStream.writeTo( stream );
|
func.functionsStream.writeTo( stream );
|
||||||
}
|
}
|
||||||
wasm.writeSection( SectionType.Code, stream );
|
wasm.writeSection( SectionType.Code, stream );
|
||||||
|
if( createSourceMap ) {
|
||||||
|
sourceMap.generate( target.getSourceMapOutput() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -358,9 +365,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
@Override
|
@Override
|
||||||
protected void writeMethodStart( FunctionName name, String sourceFile ) throws IOException {
|
protected void writeMethodStart( FunctionName name, String sourceFile ) throws IOException {
|
||||||
function = getFunction( name );
|
function = getFunction( name );
|
||||||
if( createSourceMap ) {
|
this.javaSourceFile = sourceFile;
|
||||||
function.sourceFile = sourceFile;
|
|
||||||
}
|
|
||||||
functionType = new FunctionTypeEntry();
|
functionType = new FunctionTypeEntry();
|
||||||
codeStream.reset();
|
codeStream.reset();
|
||||||
locals.clear();
|
locals.clear();
|
||||||
@ -409,7 +414,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
@Override
|
@Override
|
||||||
protected void markCodePosition( int javaCodePosition ) {
|
protected void markCodePosition( int javaCodePosition ) {
|
||||||
if( createSourceMap ) {
|
if( createSourceMap ) {
|
||||||
function.markCodePosition( codeStream.size(), javaCodePosition );
|
function.markCodePosition( codeStream.size(), javaCodePosition, javaSourceFile );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,11 @@
|
|||||||
package de.inetsoftware.jwebassembly.binary;
|
package de.inetsoftware.jwebassembly.binary;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.inetsoftware.jwebassembly.sourcemap.SourceMapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An entry in the function section of the WebAssembly.
|
* An entry in the function section of the WebAssembly.
|
||||||
*
|
*
|
||||||
@ -25,15 +28,15 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
class Function extends SectionEntry {
|
class Function extends SectionEntry {
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
int typeId;
|
int typeId;
|
||||||
|
|
||||||
List<String> paramNames;
|
List<String> paramNames;
|
||||||
|
|
||||||
WasmOutputStream functionsStream;
|
WasmOutputStream functionsStream;
|
||||||
|
|
||||||
String sourceFile;
|
ArrayList<SourceMapping> sourceMappings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
@ -48,12 +51,15 @@ class Function extends SectionEntry {
|
|||||||
*
|
*
|
||||||
* @param streamPosition
|
* @param streamPosition
|
||||||
* the position in the function stream
|
* the position in the function stream
|
||||||
* @param javaCodePosition
|
* @param javaSourceLine
|
||||||
* the position in the Java Source file
|
* the position in the Java Source file
|
||||||
|
* @param sourceFileName
|
||||||
|
* the name of the Java source file
|
||||||
*/
|
*/
|
||||||
void markCodePosition( int streamPosition, int javaCodePosition ) {
|
void markCodePosition( int streamPosition, int javaSourceLine, String sourceFileName ) {
|
||||||
if( sourceFile != null ) {
|
if( sourceMappings == null ) {
|
||||||
// TODO Auto-generated method stub
|
sourceMappings = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
sourceMappings.add( new SourceMapping( streamPosition, javaSourceLine, sourceFileName ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,9 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@ -33,6 +36,8 @@ public class WasmTarget implements Closeable {
|
|||||||
|
|
||||||
private OutputStream output;
|
private OutputStream output;
|
||||||
|
|
||||||
|
private Writer sourceMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a target with a file.
|
* Create a target with a file.
|
||||||
*
|
*
|
||||||
@ -68,6 +73,21 @@ public class WasmTarget implements Closeable {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the source map OutputStream
|
||||||
|
*
|
||||||
|
* @return the stream
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public Writer getSourceMapOutput() throws IOException {
|
||||||
|
if( sourceMap == null && file != null ) {
|
||||||
|
sourceMap = new OutputStreamWriter( new BufferedOutputStream( new FileOutputStream( file + ".map" ) ), StandardCharsets.UTF_8 );
|
||||||
|
}
|
||||||
|
return sourceMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close all streams
|
* Close all streams
|
||||||
*
|
*
|
||||||
@ -76,6 +96,11 @@ public class WasmTarget implements Closeable {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
output.close();
|
if( output != null ) {
|
||||||
|
output.close();
|
||||||
|
}
|
||||||
|
if( sourceMap != null ) {
|
||||||
|
sourceMap.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
75
src/de/inetsoftware/jwebassembly/sourcemap/Base64VLQ.java
Normal file
75
src/de/inetsoftware/jwebassembly/sourcemap/Base64VLQ.java
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Volker Berlin (i-net software)
|
||||||
|
*
|
||||||
|
* 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 de.inetsoftware.jwebassembly.sourcemap;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode an integer value as Base64VLQ
|
||||||
|
*/
|
||||||
|
class Base64VLQ {
|
||||||
|
private static final int VLQ_BASE_SHIFT = 5;
|
||||||
|
|
||||||
|
private static final int VLQ_BASE = 1 << VLQ_BASE_SHIFT;
|
||||||
|
|
||||||
|
private static final int VLQ_BASE_MASK = VLQ_BASE - 1;
|
||||||
|
|
||||||
|
private static final int VLQ_CONTINUATION_BIT = VLQ_BASE;
|
||||||
|
|
||||||
|
private static final String BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* no instance
|
||||||
|
*/
|
||||||
|
private Base64VLQ() {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the signet bit from the first position (two-complement value) to the last bit position.
|
||||||
|
*
|
||||||
|
* examples: 1 -> 2; -1 -> 3; 2 -> 4; -2 -> 5
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* two-complement value
|
||||||
|
* @return converted value
|
||||||
|
*/
|
||||||
|
private static int toVLQSigned( int value ) {
|
||||||
|
return (value < 0) ? (((-value) << 1) + 1) : ((value << 1) + 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a VLQ encoded value to the provide target.
|
||||||
|
*
|
||||||
|
* @param out
|
||||||
|
* the target
|
||||||
|
* @param value
|
||||||
|
* the value
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
static void appendBase64VLQ( Appendable out, int value ) throws IOException {
|
||||||
|
value = toVLQSigned( value );
|
||||||
|
do {
|
||||||
|
int digit = value & VLQ_BASE_MASK;
|
||||||
|
value >>>= VLQ_BASE_SHIFT;
|
||||||
|
if( value > 0 ) {
|
||||||
|
digit |= VLQ_CONTINUATION_BIT;
|
||||||
|
}
|
||||||
|
out.append( BASE64_MAP.charAt( digit ) );
|
||||||
|
} while( value > 0 );
|
||||||
|
}
|
||||||
|
}
|
240
src/de/inetsoftware/jwebassembly/sourcemap/SourceMapWriter.java
Normal file
240
src/de/inetsoftware/jwebassembly/sourcemap/SourceMapWriter.java
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Volker Berlin (i-net software)
|
||||||
|
*
|
||||||
|
* 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 de.inetsoftware.jwebassembly.sourcemap;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates Source Map version 3.
|
||||||
|
*
|
||||||
|
* https://sourcemaps.info/spec.html
|
||||||
|
*/
|
||||||
|
public class SourceMapWriter {
|
||||||
|
|
||||||
|
private List<SourceMapping> mappings = new ArrayList<>();
|
||||||
|
|
||||||
|
private LinkedHashMap<String, Integer> sourceFileNames = new LinkedHashMap<String, Integer>();
|
||||||
|
|
||||||
|
private int nextSourceFileNameIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a mapping for the given node. Mappings must be added in order.
|
||||||
|
*
|
||||||
|
* @param mapping
|
||||||
|
* the mapping
|
||||||
|
*/
|
||||||
|
public void addMapping( SourceMapping mapping ) {
|
||||||
|
if( !sourceFileNames.containsKey( mapping.getSourceFileName() ) ) {
|
||||||
|
sourceFileNames.put( mapping.getSourceFileName(), nextSourceFileNameIndex );
|
||||||
|
nextSourceFileNameIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mappings.add( mapping );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://sourcemaps.info/spec.html
|
||||||
|
*
|
||||||
|
* @param out
|
||||||
|
* the target
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
public void generate( Appendable out ) throws IOException {
|
||||||
|
out.append( "{\n" );
|
||||||
|
appendJsonField( out, "version", "3" );
|
||||||
|
|
||||||
|
// the source file names
|
||||||
|
out.append( ",\n" );
|
||||||
|
appendJsonField( out, "sources", "[" );
|
||||||
|
appendSourceFileNames( out );
|
||||||
|
out.append( "]" );
|
||||||
|
|
||||||
|
// WebAssembly does not have symbol names
|
||||||
|
out.append( ",\n" );
|
||||||
|
appendJsonField( out, "names", "[]" );
|
||||||
|
|
||||||
|
// generate the mappings
|
||||||
|
out.append( ",\n" );
|
||||||
|
appendJsonField( out, "mappings", "" );
|
||||||
|
(new Generator( out )).appendLineMappings();
|
||||||
|
out.append( "\n}" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write source file names.
|
||||||
|
*
|
||||||
|
* @param out
|
||||||
|
* the target
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
private void appendSourceFileNames( Appendable out ) throws IOException {
|
||||||
|
boolean isFirst = true;
|
||||||
|
for( Entry<String, Integer> entry : sourceFileNames.entrySet() ) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
if( isFirst ) {
|
||||||
|
isFirst = false;
|
||||||
|
} else {
|
||||||
|
out.append( ',' );
|
||||||
|
}
|
||||||
|
appendQuoteString( out, key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the field name to JSON source map.
|
||||||
|
*
|
||||||
|
* @param out
|
||||||
|
* the target
|
||||||
|
* @param name
|
||||||
|
* the field name
|
||||||
|
* @param value
|
||||||
|
* optional value
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
private static void appendJsonField( Appendable out, String name, CharSequence value ) throws IOException {
|
||||||
|
out.append( '\"' );
|
||||||
|
out.append( name );
|
||||||
|
out.append( "\":" );
|
||||||
|
out.append( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a quoted string to the JSON.
|
||||||
|
*
|
||||||
|
* @param out
|
||||||
|
* the target
|
||||||
|
* @param str
|
||||||
|
* the unquoted string
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
private static void appendQuoteString( Appendable out, String str ) throws IOException {
|
||||||
|
out.append( '"' );
|
||||||
|
for( int i = 0; i < str.length(); i++ ) {
|
||||||
|
char ch = str.charAt( i );
|
||||||
|
switch( ch ) {
|
||||||
|
case '\\':
|
||||||
|
case '\"':
|
||||||
|
out.append( '\\' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if( ch <= 0x1f ) {
|
||||||
|
out.append( "\\u" );
|
||||||
|
out.append( Character.forDigit( (ch >> 12) & 0xF, 16 ) );
|
||||||
|
out.append( Character.forDigit( (ch >> 8) & 0xF, 16 ) );
|
||||||
|
out.append( Character.forDigit( (ch >> 4) & 0xF, 16 ) );
|
||||||
|
out.append( Character.forDigit( ch & 0xF, 16 ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.append( ch );
|
||||||
|
}
|
||||||
|
out.append( '\"' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The generator of the source map
|
||||||
|
*/
|
||||||
|
private class Generator {
|
||||||
|
|
||||||
|
private final Appendable out;
|
||||||
|
|
||||||
|
private int previousLine = -1;
|
||||||
|
|
||||||
|
private int previousColumn;
|
||||||
|
|
||||||
|
private int previousSourceFileNameId;
|
||||||
|
|
||||||
|
private int previousSourceLine;
|
||||||
|
|
||||||
|
private int previousSourceColumn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an instance.
|
||||||
|
*
|
||||||
|
* @param out
|
||||||
|
* the target for the source map
|
||||||
|
*/
|
||||||
|
Generator( Appendable out ) {
|
||||||
|
this.out = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append the mappings to the source map.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
void appendLineMappings() throws IOException {
|
||||||
|
out.append( '\"' );
|
||||||
|
for( SourceMapping mapping : mappings ) {
|
||||||
|
int generatedLine = 1; // ever 1 for WebAssembly
|
||||||
|
int generatedColumn = mapping.getGeneratedColumn();
|
||||||
|
|
||||||
|
if( generatedLine > 0 && previousLine != generatedLine ) {
|
||||||
|
int start = previousLine == -1 ? 0 : previousLine;
|
||||||
|
for( int i = start; i < generatedLine; i++ ) {
|
||||||
|
out.append( ';' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( previousLine != generatedLine ) {
|
||||||
|
previousColumn = 0;
|
||||||
|
} else {
|
||||||
|
out.append( ',' );
|
||||||
|
}
|
||||||
|
|
||||||
|
writeEntry( mapping );
|
||||||
|
previousLine = generatedLine;
|
||||||
|
previousColumn = generatedColumn;
|
||||||
|
}
|
||||||
|
out.append( ";\"" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a single single mapping to the source map.
|
||||||
|
*
|
||||||
|
* @param mapping
|
||||||
|
* the mapping
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
void writeEntry( SourceMapping mapping ) throws IOException {
|
||||||
|
int column = mapping.getGeneratedColumn();
|
||||||
|
Base64VLQ.appendBase64VLQ( out, column - previousColumn );
|
||||||
|
previousColumn = column;
|
||||||
|
|
||||||
|
int sourceId = sourceFileNames.get( mapping.getSourceFileName() );
|
||||||
|
Base64VLQ.appendBase64VLQ( out, sourceId - previousSourceFileNameId );
|
||||||
|
previousSourceFileNameId = sourceId;
|
||||||
|
|
||||||
|
int srcline = mapping.getSourceLine();
|
||||||
|
int srcColumn = 0; // ever 0 for Java byte code because the line table does not support columns
|
||||||
|
Base64VLQ.appendBase64VLQ( out, srcline - previousSourceLine );
|
||||||
|
previousSourceLine = srcline;
|
||||||
|
|
||||||
|
Base64VLQ.appendBase64VLQ( out, srcColumn - previousSourceColumn );
|
||||||
|
previousSourceColumn = srcColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Volker Berlin (i-net software)
|
||||||
|
*
|
||||||
|
* 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 de.inetsoftware.jwebassembly.sourcemap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping for Source Map.
|
||||||
|
*/
|
||||||
|
public class SourceMapping {
|
||||||
|
private final int generatedColumn;
|
||||||
|
|
||||||
|
private final int sourceLine;
|
||||||
|
|
||||||
|
private final String sourceFileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a mapping between a Java code line and a WebAssembly code position
|
||||||
|
*
|
||||||
|
* @param generatedColumn
|
||||||
|
* position in WebAssembly
|
||||||
|
* @param sourceLine
|
||||||
|
* Java source line
|
||||||
|
* @param sourceFileName
|
||||||
|
* Java source file
|
||||||
|
*/
|
||||||
|
public SourceMapping( int generatedColumn, int sourceLine, String sourceFileName ) {
|
||||||
|
this.generatedColumn = generatedColumn;
|
||||||
|
this.sourceLine = sourceLine;
|
||||||
|
this.sourceFileName = sourceFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The generated column. This is equals to the binary offset in the *.wasm file
|
||||||
|
*
|
||||||
|
* @return binary offset
|
||||||
|
*/
|
||||||
|
int getGeneratedColumn() {
|
||||||
|
return generatedColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The source line
|
||||||
|
*
|
||||||
|
* @return the line number
|
||||||
|
*/
|
||||||
|
int getSourceLine() {
|
||||||
|
return sourceLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source file name
|
||||||
|
*
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
String getSourceFileName() {
|
||||||
|
return sourceFileName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package de.inetsoftware.jwebassembly.sourcemap;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class SourceMapWriterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simple() throws IOException {
|
||||||
|
SourceMapWriter map = new SourceMapWriter();
|
||||||
|
|
||||||
|
map.addMapping( new SourceMapping( 0, 0, "Test1.java" ) );
|
||||||
|
map.addMapping( new SourceMapping( 5, 1, "Test1.java" ) );
|
||||||
|
map.addMapping( new SourceMapping( 0, 4, "Test2.java" ) );
|
||||||
|
map.addMapping( new SourceMapping( 5, 9, "Test2.java" ) );
|
||||||
|
|
||||||
|
StringBuilder generate = new StringBuilder();
|
||||||
|
map.generate( generate );
|
||||||
|
String expected = "{\n" +
|
||||||
|
"\"version\":3,\n" +
|
||||||
|
"\"sources\":[\"Test1.java\",\"Test2.java\"],\n" +
|
||||||
|
"\"names\":[],\n" +
|
||||||
|
"\"mappings\":\";AAAA,KACA,LCGA,KAKA;\"\n" +
|
||||||
|
"}";
|
||||||
|
assertEquals( expected, generate.toString() );
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user