Skip to content

createProgram corrupts updated SourceFile #26166

@ajafff

Description

@ajafff

TypeScript Version: 3.1.0-dev.20180801

Search Terms:

Code

For the last two days I'm investigating a crash of my linter when fixing files, updating existing SourceFiles and creating a Program from these SourceFiles: fimbullinter/wotan#361

First you need 2 files that are processed by the repro script:

tsconfig.json

{
  "include": [
    "test.ts"
  ]
}

test.ts

export class Rule {
    private getPropertyInfo() {
        return
    }
}

(name) => b;

Now add the following script (using __dirname in the script assumes it's in the same directory as the above files, that can be changed though):

repro.js

"use strict";

const ts = require("typescript");
const {strictEqual} = require("assert");

const config = ts.parseJsonConfigFileContent(ts.readJsonConfigFile(__dirname + '/tsconfig.json', ts.sys.readFile), ts.sys, __dirname, undefined, __dirname + '/tsconfig.json');
let program = ts.createProgram(config.fileNames, config.options, ts.createCompilerHost(config.options, true));

let sourceFile = program.getSourceFile(__dirname + '/test.ts');
// add a semicolon after `return`
const newCode = sourceFile.text.slice(0, 66) + ';' + sourceFile.text.slice(66);
sourceFile = ts.updateSourceFile(sourceFile, newCode, { newLength: 1, span: { start: 66, length: 0 } });
strictEqual(sourceFile.statements[1].getSourceFile(), sourceFile, 'parent reference should be updated')

const originalHost = ts.createCompilerHost(config.options, true);
const host = {
    ...originalHost,
    getSourceFile(path, version) {
        if (path === sourceFile.fileName)
            return sourceFile;
        return originalHost.getSourceFile(path, version);
    },
};
program = ts.createProgram(program.getRootFileNames(), program.getCompilerOptions(), host, program);
strictEqual(program.getSourceFile(__dirname + '/test.ts'), sourceFile, 'new Program should contain the updated SourceFile');
strictEqual(sourceFile.statements[1].getSourceFile(), sourceFile, 'parent reference should still be the same');

Execute node repro.js

Expected behavior:

All assertions pass

Actual behavior:

Last assertion fails.
There is no error if I use ts.createSourceFile instead of ts.updateSourceFile

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions