|
|
|
@ -1,9 +1,8 @@
|
|
|
|
|
import yargs from 'yargs/yargs';
|
|
|
|
|
import ts from 'typescript';
|
|
|
|
|
import crypto from 'crypto';
|
|
|
|
|
|
|
|
|
|
import { compile } from '@syndicate-lang/compiler';
|
|
|
|
|
import { dataURL, sourceMappingComment } from './util.js';
|
|
|
|
|
import { SourcePositionIndex } from '@syndicate-lang/compiler/lib/compiler/codegen';
|
|
|
|
|
|
|
|
|
|
function reportDiagnostic(diagnostic: ts.Diagnostic) {
|
|
|
|
|
if (diagnostic.file) {
|
|
|
|
@ -21,6 +20,13 @@ function reportErrorSummary(n: number) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface SyndicateInfo {
|
|
|
|
|
originalSource: string;
|
|
|
|
|
positionIndex: SourcePositionIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const syndicateInfo: Map<string, SyndicateInfo> = new Map();
|
|
|
|
|
|
|
|
|
|
function createProgram(rootNames: readonly string[] | undefined,
|
|
|
|
|
options: ts.CompilerOptions | undefined,
|
|
|
|
|
host?: ts.CompilerHost,
|
|
|
|
@ -50,18 +56,15 @@ function createProgram(rootNames: readonly string[] | undefined,
|
|
|
|
|
onError?.(`Could not read input file ${fileName}`);
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
const { text: baseExpandedText, map: sourceMap } = compile({
|
|
|
|
|
const { text: expandedText, positionIndex } = compile({
|
|
|
|
|
source: inputText,
|
|
|
|
|
name: fileName,
|
|
|
|
|
typescript: true,
|
|
|
|
|
});
|
|
|
|
|
sourceMap.sourcesContent = [inputText];
|
|
|
|
|
const expandedText = baseExpandedText + sourceMappingComment(dataURL(JSON.stringify(sourceMap)));
|
|
|
|
|
|
|
|
|
|
// console.log('\n\n', fileName);
|
|
|
|
|
// expandedText.split(/\n/).forEach((line, i) => {
|
|
|
|
|
// console.log(i + 1, line);
|
|
|
|
|
// });
|
|
|
|
|
syndicateInfo.set(fileName, {
|
|
|
|
|
originalSource: inputText,
|
|
|
|
|
positionIndex,
|
|
|
|
|
});
|
|
|
|
|
const sf = ts.createSourceFile(fileName, expandedText, languageVersion, true);
|
|
|
|
|
(sf as any).version = crypto.createHash('sha256').update(expandedText).digest('hex');
|
|
|
|
|
return sf;
|
|
|
|
@ -82,6 +85,44 @@ function createProgram(rootNames: readonly string[] | undefined,
|
|
|
|
|
projectReferences);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fixSourceMap(ctx: ts.TransformationContext): ts.Transformer<ts.SourceFile> {
|
|
|
|
|
return sf => {
|
|
|
|
|
const fileName = sf.fileName;
|
|
|
|
|
const info = syndicateInfo.get(fileName);
|
|
|
|
|
if (info === void 0) throw new Error("No Syndicate info available for " + fileName);
|
|
|
|
|
const positionIndex = info.positionIndex;
|
|
|
|
|
|
|
|
|
|
// console.log('fixSourceMap', fileName, sf.text.length, info.originalSource.length);
|
|
|
|
|
|
|
|
|
|
const syndicateSource = ts.createSourceMapSource(fileName, info.originalSource);
|
|
|
|
|
const expandedSource = ts.createSourceMapSource(fileName + '.expanded', sf.text);
|
|
|
|
|
|
|
|
|
|
function adjustSourceMap(n: ts.Node) {
|
|
|
|
|
const ps = positionIndex.sourcePositionAt(n.pos);
|
|
|
|
|
const pe = positionIndex.sourcePositionAt(n.end);
|
|
|
|
|
if (ps.name === fileName && pe.name === fileName) {
|
|
|
|
|
ts.setSourceMapRange(n, { pos: ps.pos, end: pe.pos, source: syndicateSource });
|
|
|
|
|
// console.group(ts.SyntaxKind[n.kind], `${n.pos}-${n.end} ==> ${ps.pos}-${pe.pos}`);
|
|
|
|
|
} else if (ps.name === null && pe.name === null) {
|
|
|
|
|
ts.setSourceMapRange(n, { pos: ps.pos, end: pe.pos, source: expandedSource });
|
|
|
|
|
// console.group(ts.SyntaxKind[n.kind], n.pos, 'synthetic');
|
|
|
|
|
} else if (ps.name === null) {
|
|
|
|
|
ts.setSourceMapRange(n, { pos: pe.pos, end: pe.pos, source: expandedSource });
|
|
|
|
|
// console.group(ts.SyntaxKind[n.kind], n.pos, 'mixed end');
|
|
|
|
|
} else {
|
|
|
|
|
ts.setSourceMapRange(n, { pos: ps.pos, end: ps.pos, source: expandedSource });
|
|
|
|
|
// console.group(ts.SyntaxKind[n.kind], n.pos, 'mixed start');
|
|
|
|
|
}
|
|
|
|
|
ts.forEachChild(n, adjustSourceMap);
|
|
|
|
|
// console.groupEnd();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
adjustSourceMap(sf);
|
|
|
|
|
|
|
|
|
|
return sf;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function main(argv: string[]) {
|
|
|
|
|
const sbh = ts.createSolutionBuilderHost(ts.sys,
|
|
|
|
|
createProgram,
|
|
|
|
@ -91,5 +132,12 @@ export function main(argv: string[]) {
|
|
|
|
|
const sb = ts.createSolutionBuilder(sbh, ['.'], {
|
|
|
|
|
verbose: true,
|
|
|
|
|
});
|
|
|
|
|
ts.sys.exit(sb.build());
|
|
|
|
|
while (true) {
|
|
|
|
|
const project = sb.getNextInvalidatedProject();
|
|
|
|
|
if (project === void 0) break;
|
|
|
|
|
project.done(void 0, void 0, {
|
|
|
|
|
before: [fixSourceMap]
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
ts.sys.exit(0);
|
|
|
|
|
}
|
|
|
|
|