use of org.eclipse.n4js.transpiler.AbstractTranspiler.SourceMapInfo in project n4js by eclipse.
the class EcmaScriptSubGenerator method internalDoGenerate.
@Override
protected void internalDoGenerate(Resource resource, GeneratorOption[] options, IFileSystemAccess fsa) {
if (!(resource instanceof N4JSResource)) {
if (IN4JSProject.N4MF_MANIFEST.equals(resource.getURI().lastSegment())) {
return;
}
throw new IllegalArgumentException("Given resource is not an N4JSResource. " + resource);
}
final N4JSResource resourceCasted = (N4JSResource) resource;
if (resourceCasted.getModule().isStaticPolyfillModule()) {
// do not transpile static polyfill modules (i.e. the fillers)
return;
}
Measurement measurement = this.collector.getMeasurement(resource.getURI().toString());
/*
* In addition to here, check for cancellation is done also on file-emit boundaries, see fsa.generateFile().
*/
CancelIndicator monitor = ciExtractor.extractCancelIndicator(fsa);
// if the transpile-conditions are all met, then transpile:
if (shouldBeCompiled(resource, monitor)) {
final String compiledFileExtension = getCompiledFileExtension(resource);
final String filename = getTargetFileName(resource, compiledFileExtension);
final String sourceMapFileExtension = getCompiledFileSourceMapExtension(resource);
final String sourceMapFileName = getTargetFileName(resource, sourceMapFileExtension);
// used within the file-content to refer to sibling-file:
final String simpleSourceMapFileName = new File(sourceMapFileName).toPath().getFileName().toString();
final String simpleCompiledFileName = new File(filename).toPath().getFileName().toString();
// the next two variables store the navigation-prefix to get to the sources
final Path relativeNavigationToSrc = calculateNavigationFromOutputToSourcePath(fsa, getCompilerID(), resourceCasted);
final Path explicitNavigationToSrc = Paths.get("/sources");
// true use explicitNavigationToSrc | false use relativeNavigationToSrc
boolean useExplicitSourceRef = true;
boolean createSourceMap = true;
if (filename != null) {
final EObject root = rootElement(resource);
if (root != null) {
final Writer buffCode = new StringWriter();
Optional<SourceMapInfo> optSourceMapData = Optional.absent();
if (createSourceMap) {
SourceMapInfo sourceMapDataInstance = getTranspiler().new SourceMapInfo();
sourceMapDataInstance.sourceMapBuff = new StringWriter();
sourceMapDataInstance.simpleSourceMapFileName = simpleSourceMapFileName;
sourceMapDataInstance.simpleCompiledFileName = simpleCompiledFileName;
sourceMapDataInstance.isExplicitSourceRef = useExplicitSourceRef;
sourceMapDataInstance.explicitNavigationToSrc = explicitNavigationToSrc;
sourceMapDataInstance.n4jsFilePath = relativeNavigationToSrc.resolve(resourceCasted.getURI().lastSegment()).toString();
sourceMapDataInstance.sourceMapFileExtension = sourceMapFileExtension;
optSourceMapData = Optional.of(sourceMapDataInstance);
}
getTranspiler().transpile(resourceCasted, options, buffCode, optSourceMapData);
fsa.generateFile(filename, COMPILER_ID, buffCode.toString());
if (createSourceMap) {
fsa.generateFile(sourceMapFileName, COMPILER_ID, optSourceMapData.get().sourceMapBuff.toString());
}
}
}
}
measurement.end();
}
use of org.eclipse.n4js.transpiler.AbstractTranspiler.SourceMapInfo in project n4js by eclipse.
the class PrettyPrinter method print.
/**
* Serialize the intermediate model in the given transpiler state to <code>outCode</code> and emit source maps to
* <code>optSourceMapData</code>.
*
* @param optPreamble
* an optional preamble that will be prepended to the output code. Use '\n' as line separator. If absent,
* no preamble will be prepended.<br>
* If present, a single line break will be used to separate the preamble from the main output, but
* additional line feed characters may be added at the end of the preamble string if empty lines are
* desired between preamble and main output.
*/
public void print(TranspilerState state, Writer outCode, Optional<String> optPreamble, Optional<SourceMapInfo> optSourceMapInfo) throws IOException {
final boolean emitSourceMaps = optSourceMapInfo.isPresent();
final SourceMapAwareAppendable out = new SourceMapAwareAppendable(outCode, INDENT, emitSourceMaps);
if (optPreamble.isPresent()) {
// #append(CharSequence) will convert '\n' to correct line separator
out.append(optPreamble.get());
out.newLine();
}
PrettyPrinterSwitch.append(out, state);
if (emitSourceMaps) {
final SourceMapInfo sourceMapInfo = optSourceMapInfo.get();
final SourceMapGenerator generator = new SourceMapGeneratorDummy();
// append link to source maps to outCode
out.newLine();
out.append("//# sourceMappingURL=" + sourceMapInfo.simpleSourceMapFileName);
out.newLine();
// get the mappings collected by SourceMapAwareAppendable
final List<SourceOutputMapping> mappings = new ArrayList<>(out.getSourceMapData());
// perform some tweaks on the mappings (TEMPORARY)
removeCatchAllMapping(mappings);
sortMappings(mappings);
// Convert the source/output mappings produced by SourceMapAwareAppendable to the API of the
// Google Closure compiler source map library and add them to our SourceMapGenerator 'generator'
final PositionProvider positionProvider = PositionProvider.from(state.resource);
for (SourceOutputMapping m : mappings) {
final EObject originalASTNode = state.tracer.getOriginalASTNode(m.elementInIM);
if (// it's ok if this is null
originalASTNode != null && originalASTNode.eResource() instanceof N4JSResource) {
final ITextRegion region = locationInFileProvider.getSignificantTextRegion(originalASTNode);
// get the resource and compute the path.
final String path = sourceMapInfo.resolve((N4JSResource) originalASTNode.eResource());
final FilePosition sourceStartPosition = positionProvider.toPosition(region.getOffset());
generator.addMapping(path, // TODO source maps: support for original symbol name
null, sourceStartPosition, m.outputStart, m.outputEnd);
}
}
// append actual source maps to the buffer passed in via 'sourceMapInfo'
generator.appendTo(sourceMapInfo.sourceMapBuff, sourceMapInfo.simpleCompiledFileName);
}
}
Aggregations