Skip to content

Commit fd6a872

Browse files
committed
Adapt TS 4.4 Beta version
1 parent 8d07206 commit fd6a872

File tree

9 files changed

+108
-48
lines changed

9 files changed

+108
-48
lines changed

lsif.json .lsifrc.json

File renamed without changes.

build/azure-pipelines/test-repositories/vscode-extension-samples.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"tests": [
99
{
1010
"cwd": ".",
11-
"config": "lsif.json"
11+
"config": ".lsifrc.json"
1212
}
1313
]
1414
}

protocol/src/protocol.ts

+3
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,9 @@ export namespace Range {
693693
export function is(value: any): value is Range {
694694
return descriptor.validate(value);
695695
}
696+
export function key(value: Range): string {
697+
return `${value.start.line},${value.start.character},${value.end.line},${value.end.character}`;
698+
}
696699
}
697700

698701
/**

samples/parent.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function foo(): number {
2+
return 10;
3+
}

samples/typescript/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
import { URI } from 'vscode-uri';
1+
import * as parent from '../parent';
22

3-
URI.parse('file:///abc.txt');
3+
parent.foo();

tooling/src/validate.ts

+33-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* ------------------------------------------------------------------------------------------ */
55
import * as fs from 'fs';
66

7-
import { Cardinality, Edge, EdgeLabels, ElementTypes, EventKind, Id, V, Vertex, VertexDescriptor, VertexLabels } from 'lsif-protocol';
7+
import { Cardinality, Edge, EdgeLabels, ElementTypes, EventKind, EventScope, Id, Range, V, Vertex, VertexDescriptor, VertexLabels } from 'lsif-protocol';
88

99
import { Command, DiagnosticReporter } from './command';
1010

@@ -22,6 +22,8 @@ export class ValidateCommand extends Command {
2222
private readonly openElements: Set<Id>;
2323
private readonly closedElements: Set<Id>;
2424
private readonly associatedRanges: Set<Id>;
25+
private readonly ranges: Map<Id, Range>;
26+
private readonly rangesPreDocument: Map<Id, Set<string>>;
2527

2628
constructor(input: NodeJS.ReadStream | fs.ReadStream | IterableIterator<Edge | Vertex>, options: ValidateOptions, reporter: DiagnosticReporter) {
2729
super(input, reporter);
@@ -33,6 +35,8 @@ export class ValidateCommand extends Command {
3335
this.openElements = new Set();
3436
this.closedElements = new Set();
3537
this.associatedRanges = new Set();
38+
this.ranges = new Map();
39+
this.rangesPreDocument = new Map();
3640
this.options;
3741
}
3842

@@ -57,11 +61,20 @@ export class ValidateCommand extends Command {
5761
isClosed = vertex.data;
5862
}
5963
this.openElements.add(vertex.data);
64+
if (vertex.scope === EventScope.document) {
65+
this.rangesPreDocument.set(vertex.data, new Set());
66+
}
6067
} else if (vertex.kind === EventKind.end) {
6168
this.openElements.delete(vertex.data);
6269
this.closedElements.add(vertex.data);
70+
if (vertex.scope === EventScope.document) {
71+
this.rangesPreDocument.delete(vertex.data);
72+
}
6373
}
6474
}
75+
if (vertex.label === VertexLabels.range) {
76+
this.ranges.set(vertex.id, vertex);
77+
}
6578
}
6679

6780
if (!valid || isClosed !== undefined) {
@@ -138,9 +151,28 @@ export class ValidateCommand extends Command {
138151
if (edge.label === EdgeLabels.contains) {
139152
const vertexLabel = this.vertices.get(edge.outV);
140153
if (vertexLabel === VertexLabels.document) {
154+
const ranges = this.rangesPreDocument.get(edge.outV);
155+
if (ranges === undefined) {
156+
this.reporter.error(edge, `edge points to a range vertex for which no document ranges can be found`);
157+
}
141158
for (const range of edge.inVs) {
142159
this.associatedRanges.add(range);
160+
const rangeVertex = this.ranges.get(range);
161+
this.ranges.delete(range);
162+
if (rangeVertex === undefined) {
163+
this.reporter.error(edge, `edge points to a range vertex that can't be found.`);
164+
continue;
165+
}
166+
if (ranges !== undefined) {
167+
const key = Range.key(rangeVertex);
168+
if (ranges.has(key)) {
169+
this.reporter.error(edge, `a range with [${JSON.stringify(rangeVertex.start)},${JSON.stringify(rangeVertex.end)}] is emitted twice for the document with Id: ${edge.outV}`);
170+
} else {
171+
ranges.add(key);
172+
}
173+
}
143174
}
175+
144176
}
145177
}
146178
if (edge.label === EdgeLabels.item) {

tsc/package-lock.json

+7-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tsc/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"dependencies": {
2020
"latest-version": "5.1.0",
2121
"lsif-protocol": "0.6.0-next.5",
22-
"typescript": "https://github.com/dbaeumer/TypeScript/releases/download/4.3.0-lsif.1/typescript-4.3.0-lsif.1.tgz",
22+
"typescript": "https://github.com/dbaeumer/TypeScript/releases/download/4.4.0-beta-lsif.1/lsif-typescript-4.4.0-beta-lsif.1.tgz",
2323
"uuid": "^8.3.2",
2424
"vscode-uri": "^3.0.2",
2525
"yargs": "16.2.0"

tsc/src/lsif.ts

+58-37
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ class DocumentData extends LSIFData<EmitterContext> {
247247
public readonly external: boolean;
248248
public readonly next: DocumentData | undefined;
249249
private _isClosed: boolean;
250+
private readonly recorded: Set<string>;
250251
private ranges: Range[];
251252
private rangesEmitted: boolean;
252253
private diagnostics: lsp.Diagnostic[];
@@ -262,6 +263,7 @@ class DocumentData extends LSIFData<EmitterContext> {
262263
this.external = external;
263264
this.next = next;
264265
this._isClosed = false;
266+
this.recorded = new Set();
265267
this.ranges = [];
266268
this.rangesEmitted = false;
267269
this.diagnostics = DocumentData.EMPTY_ARRAY;
@@ -293,10 +295,25 @@ class DocumentData extends LSIFData<EmitterContext> {
293295
this.emit(this.vertex.event(EventScope.document, EventKind.begin, this.document));
294296
}
295297

296-
public addRange(range: Range): void {
298+
public addRange(range: Range): boolean {
299+
const key = Range.key(range);
300+
// export type Uri = string;
301+
// export namespace Uri { ... }
302+
//
303+
// In the example above the symbol for type Uri has one declaration node
304+
// and the symbol for namespace Uri two, where the first one is the same
305+
// as for type Uri. To avoid recording ranges twice we ignore double
306+
// ranges and treat the first recorded one as the primary. This is what
307+
// the TS server does as well.
308+
if (this.recorded.has(key)) {
309+
return false;
310+
} else {
311+
this.recorded.add(key);
312+
}
297313
this.checkClosed();
298314
this.emit(range);
299315
this.ranges.push(range);
316+
return true;
300317
}
301318

302319
public addDiagnostics(diagnostics: lsp.Diagnostic[]): void {
@@ -1262,7 +1279,7 @@ abstract class SymbolWalker {
12621279
if (symbolData !== undefined) {
12631280
symbolData.changeVisibility(SymbolDataVisibility.indirectExported);
12641281
} else {
1265-
this.symbols.storeSymbolInitializationData(symbol, SymbolDataVisibility.indirectExported);
1282+
Symbols.storeSymbolInitializationData(this.symbols.getSymbolId(symbol), SymbolDataVisibility.indirectExported);
12661283
}
12671284
}
12681285

@@ -1556,12 +1573,34 @@ class Symbols {
15561573
return symbol.declarations !== undefined && symbol.declarations.length > 0 ? symbol.declarations[0] : undefined;
15571574
}
15581575

1576+
private static readonly symbolInitializationData: Map<SymbolId, SymbolDataVisibility> = new Map();
1577+
1578+
public static storeSymbolInitializationData(symbolId: SymbolId, visibility: SymbolDataVisibility): void {
1579+
this.symbolInitializationData.set(symbolId, visibility);
1580+
}
1581+
1582+
private static getVisibility(symbolId: SymbolId, symbol: ts.Symbol, exportPath: string | undefined | null): SymbolDataVisibility {
1583+
const initVisibility = this.symbolInitializationData.get(symbolId);
1584+
if (initVisibility !== undefined) {
1585+
this.symbolInitializationData.delete(symbolId);
1586+
}
1587+
1588+
// The symbol is exported.
1589+
if (exportPath === null || exportPath !== undefined) {
1590+
return SymbolDataVisibility.exported;
1591+
}
1592+
if (Symbols.isTransient(symbol)) {
1593+
return SymbolDataVisibility.transient;
1594+
}
1595+
1596+
return initVisibility ?? SymbolDataVisibility.unknown;
1597+
}
1598+
15591599
public readonly types: Types;
15601600

15611601
private readonly baseSymbolCache: LRUCache<string, ts.Symbol[]>;
15621602
private readonly baseMemberCache: LRUCache<string, LRUCache<string, ts.Symbol[]>>;
15631603
private readonly symbolCache: LRUCache<ts.Symbol, CachedSymbolInformation>;
1564-
private readonly symbolInitializationData: Map<string, SymbolDataVisibility>;
15651604

15661605
private readonly sourceFilesContainingAmbientDeclarations: Set<string>;
15671606

@@ -1570,7 +1609,6 @@ class Symbols {
15701609
this.baseSymbolCache = new LRUCache(2048);
15711610
this.baseMemberCache = new LRUCache(2048);
15721611
this.symbolCache = new LRUCache(4096);
1573-
this.symbolInitializationData = new Map();
15741612

15751613
this.sourceFilesContainingAmbientDeclarations = new Set();
15761614

@@ -1908,34 +1946,12 @@ class Symbols {
19081946
return true;
19091947
}
19101948

1911-
public storeSymbolInitializationData(symbol: ts.Symbol, visibility: SymbolDataVisibility): void {
1912-
const key = this.getSymbolId(symbol);
1913-
this.symbolInitializationData.set(key, visibility);
1914-
}
1915-
19161949
public getSymbolInitializationData(symbol: ts.Symbol): [string | undefined, ModuleSystemKind, SymbolDataVisibility, boolean] {
19171950
const [exportPath, moduleSystem, ] = this.getCachedSymbolInformation(symbol);
1918-
const visibility = this.getVisibility(symbol, exportPath);
1951+
const symbolId = this.getSymbolId(symbol);
1952+
const visibility = Symbols.getVisibility(symbolId, symbol, exportPath);
19191953
return [exportPath === null ? undefined : exportPath, moduleSystem, visibility, !Symbols.isInternal(symbol)];
19201954
}
1921-
1922-
private getVisibility(symbol: ts.Symbol, exportPath: string | undefined | null): SymbolDataVisibility {
1923-
const id = this.getSymbolId(symbol);
1924-
const initVisibility = this.symbolInitializationData.get(id);
1925-
if (initVisibility !== undefined) {
1926-
this.symbolInitializationData.delete(id);
1927-
}
1928-
1929-
// The symbol is exported.
1930-
if (exportPath === null || exportPath !== undefined) {
1931-
return SymbolDataVisibility.exported;
1932-
}
1933-
if (Symbols.isTransient(symbol)) {
1934-
return SymbolDataVisibility.transient;
1935-
}
1936-
1937-
return initVisibility ?? SymbolDataVisibility.unknown;
1938-
}
19391955
}
19401956

19411957

@@ -2424,13 +2440,11 @@ class WorkspaceProjectDataManager extends LazyProjectDataManager {
24242440

24252441
class TSConfigProjectDataManager extends ProjectDataManager {
24262442

2427-
private readonly sourceRoot: string;
24282443
private readonly projectFiles: Set<string>;
24292444
private readonly managedDocuments: Set<Document>;
24302445

2431-
public constructor(id: ProjectId, context: ProjectDataManagerContext, project: Project, sourceRoot: string, projectFiles: ReadonlyArray<string> | undefined, reporter: Reporter) {
2446+
public constructor(id: ProjectId, context: ProjectDataManagerContext, project: Project, _sourceRoot: string, projectFiles: ReadonlyArray<string> | undefined, reporter: Reporter) {
24322447
super(id, context, project, reporter);
2433-
this.sourceRoot = sourceRoot;
24342448
this.projectFiles = new Set(projectFiles);
24352449
this.managedDocuments = new Set();
24362450
}
@@ -2441,7 +2455,7 @@ class TSConfigProjectDataManager extends ProjectDataManager {
24412455

24422456
public handles(sourceFile: ts.SourceFile): boolean {
24432457
const fileName = sourceFile.fileName;
2444-
return this.projectFiles.has(fileName) || paths.isParent(this.sourceRoot, fileName);
2458+
return this.projectFiles.has(fileName);
24452459
}
24462460

24472461
public createDocumentData(fileName: string, document: Document, moduleSystem: ModuleSystemKind, monikerPath: string | undefined, external: boolean, next: DocumentData | undefined): DocumentData {
@@ -2805,9 +2819,10 @@ class TSProject {
28052819
kind: Converter.asSymbolKind(declaration),
28062820
fullRange: Converter.rangeFromNode(sourceFile, declaration),
28072821
});
2808-
documentData.addRange(definition);
2809-
symbolData.addDefinition(documentData.document, definition);
2810-
symbolData.recordDefinitionInfo(tss.createDefinitionInfo(sourceFile, identifierNode));
2822+
if (documentData.addRange(definition)) {
2823+
symbolData.addDefinition(documentData.document, definition);
2824+
symbolData.recordDefinitionInfo(tss.createDefinitionInfo(sourceFile, identifierNode));
2825+
}
28112826
if (hover === undefined && tss.Node.isNamedDeclaration(declaration)) {
28122827
// let start = Date.now();
28132828
hover = this.getHover(declaration.name, sourceFile);
@@ -3038,6 +3053,11 @@ export class DataManager implements SymbolDataContext, ProjectDataManagerContext
30383053
if (this.currentTSProject !== tsProject || this.currentPDM === undefined) {
30393054
throw new Error(`Current project is not the one passed to end.`);
30403055
}
3056+
// Make sure we close partitions opened because of type folding in global files.
3057+
const documents = this.currentPDM.getDocuments();
3058+
for (const manager of [this.workspacePDM, this.machinePDM, this.defaultLibsPDM]) {
3059+
manager.endPartitions(documents);
3060+
}
30413061
this.currentPDM.end();
30423062
this.currentPDM = undefined;
30433063
this.currentTSProject = undefined;
@@ -3194,8 +3214,9 @@ export class DataManager implements SymbolDataContext, ProjectDataManagerContext
31943214
}
31953215

31963216
const reference = this.vertex.range(Converter.rangeFromNode(sourceFile, location), { type: RangeTagTypes.reference, text: location.getText() });
3197-
documentData.addRange(reference);
3198-
symbolData.addReference(documentData.document, reference, ItemEdgeProperties.references);
3217+
if (documentData.addRange(reference)) {
3218+
symbolData.addReference(documentData.document, reference, ItemEdgeProperties.references);
3219+
}
31993220
}
32003221

32013222
public getSymbolData(symbol: SymbolId | ts.Symbol): SymbolData | undefined {

0 commit comments

Comments
 (0)