diff --git a/packages/compiler-cli/src/transformers/compiler_host.ts b/packages/compiler-cli/src/transformers/compiler_host.ts
index ab1e664b20..8bc19ec2d4 100644
--- a/packages/compiler-cli/src/transformers/compiler_host.ts
+++ b/packages/compiler-cli/src/transformers/compiler_host.ts
@@ -287,7 +287,7 @@ export class TsCompilerAotCompilerTypeCheckHostAdapter extends
`Invalid Argument: Expected a GenerateFile with statements. ${genFile.genFileUrl}`);
}
const {sourceText, context} = this.emitter.emitStatementsAndContext(
- genFile.srcFileUrl, genFile.genFileUrl, genFile.stmts, /* preamble */ '',
+ genFile.genFileUrl, genFile.stmts, /* preamble */ '',
/* emitSourceMaps */ false);
const sf = ts.createSourceFile(
genFile.genFileUrl, sourceText, this.options.target || ts.ScriptTarget.Latest);
diff --git a/packages/compiler-cli/test/ngc_spec.ts b/packages/compiler-cli/test/ngc_spec.ts
index e787aeacf9..6c38d7d75d 100644
--- a/packages/compiler-cli/test/ngc_spec.ts
+++ b/packages/compiler-cli/test/ngc_spec.ts
@@ -184,7 +184,7 @@ describe('ngc transformer command-line', () => {
const exitCode = main(['-p', basePath], errorSpy);
expect(errorSpy).toHaveBeenCalledTimes(1);
expect(errorSpy.calls.mostRecent().args[0])
- .toContain('Error at ng://' + path.join(basePath, 'mymodule.ts.MyComp.html'));
+ .toContain('Error at ' + path.join(basePath, 'mymodule.ts.MyComp.html'));
expect(errorSpy.calls.mostRecent().args[0])
.toContain(`Property 'unknownProp' does not exist on type 'MyComp'`);
@@ -215,7 +215,7 @@ describe('ngc transformer command-line', () => {
const exitCode = main(['-p', basePath], errorSpy);
expect(errorSpy).toHaveBeenCalledTimes(1);
expect(errorSpy.calls.mostRecent().args[0])
- .toContain('Error at ng://' + path.join(basePath, 'my.component.html(1,5):'));
+ .toContain('Error at ' + path.join(basePath, 'my.component.html(1,5):'));
expect(errorSpy.calls.mostRecent().args[0])
.toContain(`Property 'unknownProp' does not exist on type 'MyComp'`);
diff --git a/packages/compiler-cli/test/transformers/node_emitter_spec.ts b/packages/compiler-cli/test/transformers/node_emitter_spec.ts
index 637ca8be7a..0ac9a0a53b 100644
--- a/packages/compiler-cli/test/transformers/node_emitter_spec.ts
+++ b/packages/compiler-cli/test/transformers/node_emitter_spec.ts
@@ -422,8 +422,8 @@ describe('TypeScriptNodeEmitter', () => {
it('should produce a source map that maps back to the source', () => {
const statement = someVar.set(o.literal(1)).toDeclStmt();
const text = ' a = 1 ';
- const sourceName = 'ng://some.file.html';
- const sourceUrl = 'file:///ng:/some.file.html';
+ const sourceName = '/some/file.html';
+ const sourceUrl = '../some/file.html';
const file = new ParseSourceFile(text, sourceName);
const start = new ParseLocation(file, 0, 0, 0);
const end = new ParseLocation(file, text.length, 0, text.length);
diff --git a/packages/compiler/src/aot/compiler.ts b/packages/compiler/src/aot/compiler.ts
index 4da4cc9208..317ba315f2 100644
--- a/packages/compiler/src/aot/compiler.ts
+++ b/packages/compiler/src/aot/compiler.ts
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {CompileDirectiveMetadata, CompileDirectiveSummary, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileNgModuleSummary, CompilePipeMetadata, CompilePipeSummary, CompileProviderMetadata, CompileStylesheetMetadata, CompileSummaryKind, CompileTypeMetadata, CompileTypeSummary, componentFactoryName, flatten, identifierName, sourceUrl, templateSourceUrl} from '../compile_metadata';
+import {CompileDirectiveMetadata, CompileDirectiveSummary, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileNgModuleSummary, CompilePipeMetadata, CompilePipeSummary, CompileProviderMetadata, CompileStylesheetMetadata, CompileSummaryKind, CompileTypeMetadata, CompileTypeSummary, componentFactoryName, flatten, identifierName, templateSourceUrl} from '../compile_metadata';
import {CompilerConfig} from '../config';
import {ViewEncapsulation} from '../core';
import {MessageBundle} from '../i18n/message_bundle';
diff --git a/packages/compiler/src/aot/generated_file.ts b/packages/compiler/src/aot/generated_file.ts
index c072e57a90..0973fbaa60 100644
--- a/packages/compiler/src/aot/generated_file.ts
+++ b/packages/compiler/src/aot/generated_file.ts
@@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {sourceUrl} from '../compile_metadata';
import {Statement, areAllEquivalent} from '../output/output_ast';
import {TypeScriptEmitter} from '../output/ts_emitter';
@@ -45,6 +44,5 @@ export function toTypeScript(file: GeneratedFile, preamble: string = ''): string
if (!file.stmts) {
throw new Error(`Illegal state: No stmts present on GeneratedFile ${file.genFileUrl}`);
}
- return new TypeScriptEmitter().emitStatements(
- sourceUrl(file.srcFileUrl), file.genFileUrl, file.stmts, preamble);
+ return new TypeScriptEmitter().emitStatements(file.genFileUrl, file.stmts, preamble);
}
diff --git a/packages/compiler/src/compile_metadata.ts b/packages/compiler/src/compile_metadata.ts
index 2c1be3ddbb..174eff42f2 100644
--- a/packages/compiler/src/compile_metadata.ts
+++ b/packages/compiler/src/compile_metadata.ts
@@ -653,7 +653,7 @@ export function flatten(list: Array): T[] {
}, []);
}
-export function sourceUrl(url: string) {
+function jitSourceUrl(url: string) {
// Note: We need 3 "/" so that ng shows up as a separate domain
// in the chrome dev tools.
return url.replace(/(\w+:\/\/[\w:-]+)?(\/+)?/, 'ng:///');
@@ -674,22 +674,21 @@ export function templateSourceUrl(
} else {
url = templateMeta.templateUrl !;
}
- // always prepend ng:// to make angular resources easy to find and not clobber
- // user resources.
- return sourceUrl(url);
+ return compMeta.type.reference instanceof StaticSymbol ? url : jitSourceUrl(url);
}
export function sharedStylesheetJitUrl(meta: CompileStylesheetMetadata, id: number) {
const pathParts = meta.moduleUrl !.split(/\/\\/g);
const baseName = pathParts[pathParts.length - 1];
- return sourceUrl(`css/${id}${baseName}.ngstyle.js`);
+ return jitSourceUrl(`css/${id}${baseName}.ngstyle.js`);
}
export function ngModuleJitUrl(moduleMeta: CompileNgModuleMetadata): string {
- return sourceUrl(`${identifierName(moduleMeta.type)}/module.ngfactory.js`);
+ return jitSourceUrl(`${identifierName(moduleMeta.type)}/module.ngfactory.js`);
}
export function templateJitUrl(
ngModuleType: CompileIdentifierMetadata, compMeta: CompileDirectiveMetadata): string {
- return sourceUrl(`${identifierName(ngModuleType)}/${identifierName(compMeta.type)}.ngfactory.js`);
+ return jitSourceUrl(
+ `${identifierName(ngModuleType)}/${identifierName(compMeta.type)}.ngfactory.js`);
}
diff --git a/packages/compiler/src/output/abstract_emitter.ts b/packages/compiler/src/output/abstract_emitter.ts
index ea2d01da30..ae43117306 100644
--- a/packages/compiler/src/output/abstract_emitter.ts
+++ b/packages/compiler/src/output/abstract_emitter.ts
@@ -18,9 +18,7 @@ export const CATCH_ERROR_VAR = o.variable('error', null, null);
export const CATCH_STACK_VAR = o.variable('stack', null, null);
export interface OutputEmitter {
- emitStatements(
- srcFilePath: string, genFilePath: string, stmts: o.Statement[],
- preamble?: string|null): string;
+ emitStatements(genFilePath: string, stmts: o.Statement[], preamble?: string|null): string;
}
class _EmittedLine {
@@ -96,8 +94,7 @@ export class EmitterVisitorContext {
.join('\n');
}
- toSourceMapGenerator(sourceFilePath: string, genFilePath: string, startsAtLine: number = 0):
- SourceMapGenerator {
+ toSourceMapGenerator(genFilePath: string, startsAtLine: number = 0): SourceMapGenerator {
const map = new SourceMapGenerator(genFilePath);
let firstOffsetMapped = false;
@@ -106,7 +103,7 @@ export class EmitterVisitorContext {
// Add a single space so that tools won't try to load the file from disk.
// Note: We are using virtual urls like `ng:///`, so we have to
// provide a content here.
- map.addSource(sourceFilePath, ' ').addMapping(0, sourceFilePath, 0, 0);
+ map.addSource(genFilePath, ' ').addMapping(0, genFilePath, 0, 0);
firstOffsetMapped = true;
}
};
diff --git a/packages/compiler/src/output/js_emitter.ts b/packages/compiler/src/output/js_emitter.ts
index 5a022b74ae..16ae3138e7 100644
--- a/packages/compiler/src/output/js_emitter.ts
+++ b/packages/compiler/src/output/js_emitter.ts
@@ -15,9 +15,7 @@ import {AbstractJsEmitterVisitor} from './abstract_js_emitter';
import * as o from './output_ast';
export class JavaScriptEmitter implements OutputEmitter {
- emitStatements(
- srcFilePath: string, genFilePath: string, stmts: o.Statement[],
- preamble: string = ''): string {
+ emitStatements(genFilePath: string, stmts: o.Statement[], preamble: string = ''): string {
const converter = new JsEmitterVisitor();
const ctx = EmitterVisitorContext.createRoot();
converter.visitAllStatements(stmts, ctx);
@@ -30,8 +28,7 @@ export class JavaScriptEmitter implements OutputEmitter {
`uire('${importedModuleName}');`);
});
- const sm =
- ctx.toSourceMapGenerator(srcFilePath, genFilePath, preambleLines.length).toJsComment();
+ const sm = ctx.toSourceMapGenerator(genFilePath, preambleLines.length).toJsComment();
const lines = [...preambleLines, ctx.toSource(), sm];
if (sm) {
// always add a newline at the end, as some tools have bugs without it.
diff --git a/packages/compiler/src/output/output_jit.ts b/packages/compiler/src/output/output_jit.ts
index 1239c9280c..7fb32a64cc 100644
--- a/packages/compiler/src/output/output_jit.ts
+++ b/packages/compiler/src/output/output_jit.ts
@@ -31,7 +31,7 @@ function evalExpression(
// We don't want to hard code this fact, so we auto detect it via an empty function first.
const emptyFn = new Function(...fnArgNames.concat('return null;')).toString();
const headerLines = emptyFn.slice(0, emptyFn.indexOf('return null;')).split('\n').length - 1;
- fnBody += `\n${ctx.toSourceMapGenerator(sourceUrl, sourceUrl, headerLines).toJsComment()}`;
+ fnBody += `\n${ctx.toSourceMapGenerator(sourceUrl, headerLines).toJsComment()}`;
}
return new Function(...fnArgNames.concat(fnBody))(...fnArgValues);
}
diff --git a/packages/compiler/src/output/ts_emitter.ts b/packages/compiler/src/output/ts_emitter.ts
index 86ca3d0017..6f3b138c1e 100644
--- a/packages/compiler/src/output/ts_emitter.ts
+++ b/packages/compiler/src/output/ts_emitter.ts
@@ -39,7 +39,7 @@ export type ReferenceFilter = (reference: o.ExternalReference) => boolean;
export class TypeScriptEmitter implements OutputEmitter {
emitStatementsAndContext(
- srcFilePath: string, genFilePath: string, stmts: o.Statement[], preamble: string = '',
+ genFilePath: string, stmts: o.Statement[], preamble: string = '',
emitSourceMaps: boolean = true,
referenceFilter?: ReferenceFilter): {sourceText: string, context: EmitterVisitorContext} {
const converter = new _TsEmitterVisitor(referenceFilter);
@@ -63,7 +63,7 @@ export class TypeScriptEmitter implements OutputEmitter {
});
const sm = emitSourceMaps ?
- ctx.toSourceMapGenerator(srcFilePath, genFilePath, preambleLines.length).toJsComment() :
+ ctx.toSourceMapGenerator(genFilePath, preambleLines.length).toJsComment() :
'';
const lines = [...preambleLines, ctx.toSource(), sm];
if (sm) {
@@ -74,9 +74,8 @@ export class TypeScriptEmitter implements OutputEmitter {
return {sourceText: lines.join('\n'), context: ctx};
}
- emitStatements(
- srcFilePath: string, genFilePath: string, stmts: o.Statement[], preamble: string = '') {
- return this.emitStatementsAndContext(srcFilePath, genFilePath, stmts, preamble).sourceText;
+ emitStatements(genFilePath: string, stmts: o.Statement[], preamble: string = '') {
+ return this.emitStatementsAndContext(genFilePath, stmts, preamble).sourceText;
}
}
diff --git a/packages/compiler/test/aot/compiler_spec.ts b/packages/compiler/test/aot/compiler_spec.ts
index 1c8ed4b24a..b9e013b9bd 100644
--- a/packages/compiler/test/aot/compiler_spec.ts
+++ b/packages/compiler/test/aot/compiler_spec.ts
@@ -29,7 +29,7 @@ describe('compiler (unbundled Angular)', () => {
describe('aot source mapping', () => {
const componentPath = '/app/app.component.ts';
- const ngComponentPath = 'ng:///app/app.component.ts';
+ const ngFactoryPath = '/app/app.component.ngfactory.ts';
let rootDir: MockDirectory;
let appDir: MockDirectory;
@@ -83,7 +83,7 @@ describe('compiler (unbundled Angular)', () => {
}
describe('inline templates', () => {
- const ngUrl = `${ngComponentPath}.AppComponent.html`;
+ const ngUrl = `${componentPath}.AppComponent.html`;
function templateDecorator(template: string) { return `template: \`${template}\`,`; }
@@ -91,7 +91,7 @@ describe('compiler (unbundled Angular)', () => {
});
describe('external templates', () => {
- const ngUrl = 'ng:///app/app.component.html';
+ const ngUrl = '/app/app.component.html';
const templateUrl = '/app/app.component.html';
function templateDecorator(template: string) {
@@ -129,14 +129,14 @@ describe('compiler (unbundled Angular)', () => {
const sourceMap = extractSourceMap(genSource) !;
expect(sourceMap.file).toEqual(genFile.genFileUrl);
- // the generated file contains code that is not mapped to
- // the template but rather to the original source file (e.g. import statements, ...)
+ // Note: the generated file also contains code that is not mapped to
+ // the template (e.g. import statements, ...)
const templateIndex = sourceMap.sources.indexOf(ngUrl);
expect(sourceMap.sourcesContent[templateIndex]).toEqual(template);
// for the mapping to the original source file we don't store the source code
// as we want to keep whatever TypeScript / ... produced for them.
- const sourceIndex = sourceMap.sources.indexOf(ngComponentPath);
+ const sourceIndex = sourceMap.sources.indexOf(ngFactoryPath);
expect(sourceMap.sourcesContent[sourceIndex]).toBe(' ');
});
@@ -176,14 +176,14 @@ describe('compiler (unbundled Angular)', () => {
.toEqual({line: 2, column: 9, source: ngUrl});
});
- it('should map non template parts to the source file', () => {
+ it('should map non template parts to the factory file', () => {
appDir['app.component.ts'] = createComponentSource(templateDecorator('Hello World!'));
const genFile = compileApp();
const genSource = toTypeScript(genFile);
const sourceMap = extractSourceMap(genSource) !;
expect(originalPositionFor(sourceMap, {line: 1, column: 0}))
- .toEqual({line: 1, column: 0, source: ngComponentPath});
+ .toEqual({line: 1, column: 0, source: ngFactoryPath});
});
}
});
diff --git a/packages/compiler/test/output/abstract_emitter_node_only_spec.ts b/packages/compiler/test/output/abstract_emitter_node_only_spec.ts
index d4685d8920..a735ce9dcf 100644
--- a/packages/compiler/test/output/abstract_emitter_node_only_spec.ts
+++ b/packages/compiler/test/output/abstract_emitter_node_only_spec.ts
@@ -25,7 +25,7 @@ export function main() {
ctx.print(createSourceSpan(fileA, 1), 'o1');
ctx.print(createSourceSpan(fileB, 0), 'o2');
ctx.print(createSourceSpan(fileB, 1), 'o3');
- const sm = ctx.toSourceMapGenerator('o.ts', 'o.js').toJSON() !;
+ const sm = ctx.toSourceMapGenerator('o.ts').toJSON() !;
expect(sm.sources).toEqual([fileA.url, fileB.url]);
expect(sm.sourcesContent).toEqual([fileA.content, fileB.content]);
});
@@ -43,7 +43,7 @@ export function main() {
it('should be able to shift the content', () => {
ctx.print(createSourceSpan(fileA, 0), 'fileA-0');
- const sm = ctx.toSourceMapGenerator('o.ts', 'o.js', 10).toJSON() !;
+ const sm = ctx.toSourceMapGenerator('o.ts', 10).toJSON() !;
expect(originalPositionFor(sm, {line: 11, column: 0})).toEqual({
line: 1,
column: 0,
@@ -113,7 +113,7 @@ export function main() {
function expectMap(
ctx: EmitterVisitorContext, genLine: number, genCol: number, source: string | null = null,
srcLine: number | null = null, srcCol: number | null = null) {
- const sm = ctx.toSourceMapGenerator('o.ts', 'o.js').toJSON() !;
+ const sm = ctx.toSourceMapGenerator('o.ts').toJSON() !;
const genPosition = {line: genLine + 1, column: genCol};
const origPosition = originalPositionFor(sm, genPosition);
expect(origPosition.source).toEqual(source);
@@ -123,7 +123,7 @@ function expectMap(
// returns the number of segments per line
function nbSegmentsPerLine(ctx: EmitterVisitorContext) {
- const sm = ctx.toSourceMapGenerator('o.ts', 'o.js').toJSON() !;
+ const sm = ctx.toSourceMapGenerator('o.ts').toJSON() !;
const lines = sm.mappings.split(';');
return lines.map(l => {
const m = l.match(/,/g);
diff --git a/packages/compiler/test/output/js_emitter_node_only_spec.ts b/packages/compiler/test/output/js_emitter_node_only_spec.ts
index 3d9cc0084d..b210dbc66a 100644
--- a/packages/compiler/test/output/js_emitter_node_only_spec.ts
+++ b/packages/compiler/test/output/js_emitter_node_only_spec.ts
@@ -16,7 +16,6 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '@angular/compiler
import {extractSourceMap, originalPositionFor} from './source_map_util';
const someGenFilePath = 'somePackage/someGenFile';
-const someSourceFilePath = 'somePackage/someSourceFile';
export function main() {
describe('JavaScriptEmitter', () => {
@@ -27,7 +26,7 @@ export function main() {
function emitSourceMap(stmt: o.Statement | o.Statement[], preamble?: string): SourceMap {
const stmts = Array.isArray(stmt) ? stmt : [stmt];
- const source = emitter.emitStatements(someSourceFilePath, someGenFilePath, stmts, preamble);
+ const source = emitter.emitStatements(someGenFilePath, stmts, preamble);
return extractSourceMap(source) !;
}
@@ -40,7 +39,7 @@ export function main() {
const someVar = o.variable('someVar', null, sourceSpan);
const sm = emitSourceMap(someVar.toStmt(), '/* MyPreamble \n */');
- expect(sm.sources).toEqual([someSourceFilePath, 'in.js']);
+ expect(sm.sources).toEqual([someGenFilePath, 'in.js']);
expect(sm.sourcesContent).toEqual([' ', ';;;var']);
expect(originalPositionFor(sm, {line: 3, column: 0}))
.toEqual({line: 1, column: 3, source: 'in.js'});
diff --git a/packages/compiler/test/output/js_emitter_spec.ts b/packages/compiler/test/output/js_emitter_spec.ts
index e83b328315..a336eba6dc 100644
--- a/packages/compiler/test/output/js_emitter_spec.ts
+++ b/packages/compiler/test/output/js_emitter_spec.ts
@@ -13,7 +13,6 @@ import * as o from '@angular/compiler/src/output/output_ast';
import {stripSourceMapAndNewLine} from './abstract_emitter_spec';
const someGenFilePath = 'somePackage/someGenFile';
-const someSourceFilePath = 'somePackage/someSourceFile';
const anotherModuleUrl = 'somePackage/someOtherPath';
const sameModuleIdentifier = new o.ExternalReference(null, 'someLocalId', null);
@@ -35,7 +34,7 @@ export function main() {
});
function emitStmt(stmt: o.Statement, preamble?: string): string {
- const source = emitter.emitStatements(someSourceFilePath, someGenFilePath, [stmt], preamble);
+ const source = emitter.emitStatements(someGenFilePath, [stmt], preamble);
return stripSourceMapAndNewLine(source);
}
diff --git a/packages/compiler/test/output/ts_emitter_node_only_spec.ts b/packages/compiler/test/output/ts_emitter_node_only_spec.ts
index 00fb814cdc..54810d9122 100644
--- a/packages/compiler/test/output/ts_emitter_node_only_spec.ts
+++ b/packages/compiler/test/output/ts_emitter_node_only_spec.ts
@@ -16,7 +16,6 @@ import {ParseSourceSpan} from '@angular/compiler/src/parse_util';
import {extractSourceMap, originalPositionFor} from './source_map_util';
const someGenFilePath = 'somePackage/someGenFile';
-const someSourceFilePath = 'somePackage/someSourceFile';
export function main() {
// Not supported features of our OutputAst in TS:
@@ -34,7 +33,7 @@ export function main() {
function emitSourceMap(stmt: o.Statement | o.Statement[], preamble?: string): SourceMap {
const stmts = Array.isArray(stmt) ? stmt : [stmt];
- const source = emitter.emitStatements(someSourceFilePath, someGenFilePath, stmts, preamble);
+ const source = emitter.emitStatements(someGenFilePath, stmts, preamble);
return extractSourceMap(source) !;
}
@@ -47,7 +46,7 @@ export function main() {
const someVar = o.variable('someVar', null, sourceSpan);
const sm = emitSourceMap(someVar.toStmt(), '/* MyPreamble \n */');
- expect(sm.sources).toEqual([someSourceFilePath, 'in.js']);
+ expect(sm.sources).toEqual([someGenFilePath, 'in.js']);
expect(sm.sourcesContent).toEqual([' ', ';;;var']);
expect(originalPositionFor(sm, {line: 3, column: 0}))
.toEqual({line: 1, column: 3, source: 'in.js'});
diff --git a/packages/compiler/test/output/ts_emitter_spec.ts b/packages/compiler/test/output/ts_emitter_spec.ts
index 7efaa2fa4c..ba5b86c0bb 100644
--- a/packages/compiler/test/output/ts_emitter_spec.ts
+++ b/packages/compiler/test/output/ts_emitter_spec.ts
@@ -13,7 +13,6 @@ import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '@angular/compiler
import {stripSourceMapAndNewLine} from './abstract_emitter_spec';
const someGenFilePath = 'somePackage/someGenFile';
-const someSourceFilePath = 'somePackage/someSourceFile';
const anotherModuleUrl = 'somePackage/someOtherPath';
const sameModuleIdentifier = new o.ExternalReference(null, 'someLocalId', null);
@@ -36,7 +35,7 @@ export function main() {
function emitStmt(stmt: o.Statement | o.Statement[], preamble?: string): string {
const stmts = Array.isArray(stmt) ? stmt : [stmt];
- const source = emitter.emitStatements(someSourceFilePath, someGenFilePath, stmts, preamble);
+ const source = emitter.emitStatements(someGenFilePath, stmts, preamble);
return stripSourceMapAndNewLine(source);
}
@@ -435,7 +434,7 @@ export function main() {
new o.ReturnStatement(o.variable('someVar', null, referenceSpan), returnSpan)
])])];
const {sourceText, context} =
- emitter.emitStatementsAndContext('a.ts', 'a.ts', statements, '/* some preamble /*\n\n');
+ emitter.emitStatementsAndContext('a.ts', statements, '/* some preamble /*\n\n');
const spanOf = (text: string, after: number = 0) => {
const location = sourceText.indexOf(text, after);
const {line, col} = calculateLineCol(sourceText, location);