Skip to content

Commit a00b970

Browse files
committed
Merge branch 'main' into weswigham/negated-types
2 parents fd347a9 + 28534d7 commit a00b970

60 files changed

Lines changed: 2123 additions & 877 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ name: CI
22

33
on:
44
push:
5-
branches: [main, main-ts7, ts7-release, 'release-*']
5+
branches: [main, main-ts7, ts7-release, 'release-*', 'weswigham/*']
66
pull_request:
7-
branches: [main, main-ts7, ts7-release, 'release-*']
7+
branches: [main, main-ts7, ts7-release, 'release-*', 'weswigham/*']
88
merge_group:
9-
branches: [main, main-ts7, ts7-release, 'release-*']
9+
branches: [main, main-ts7, ts7-release, 'release-*', 'weswigham/*']
1010

1111
permissions:
1212
contents: read

‎packages/typescript/src/api/async/api.ts‎

Lines changed: 222 additions & 157 deletions
Large diffs are not rendered by default.

‎packages/typescript/src/api/node/node.ts‎

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
import {
3535
HEADER_OFFSET_EXTENDED_DATA,
3636
HEADER_OFFSET_NODES,
37+
HEADER_OFFSET_SOURCE_FILE_ID,
3738
HEADER_OFFSET_STRING_TABLE,
3839
HEADER_OFFSET_STRING_TABLE_OFFSETS,
3940
HEADER_OFFSET_STRUCTURED_DATA,
@@ -106,6 +107,7 @@ export class RemoteSourceFile extends RemoteNode implements SourceFileInfo {
106107
private _cachedSupplementalSourceFileNames: readonly RootedFilePath[] | undefined;
107108
private _cachedDiagnosticDirectives: readonly MappedDiagnosticDirective[] | undefined;
108109
private _diagnosticDirectivesRead = false;
110+
private _handleFileKey: string | undefined;
109111

110112
constructor(
111113
data: Uint8Array,
@@ -147,6 +149,22 @@ export class RemoteSourceFile extends RemoteNode implements SourceFileInfo {
147149
return readSourceFileNodeId(this.view);
148150
}
149151

152+
/**
153+
* The file component of node handles sent to the server: `#` followed by the
154+
* server's identity for this exact source file.
155+
* @internal
156+
*/
157+
get handleFileKey(): string {
158+
if (this._handleFileKey === undefined) {
159+
const nodeId = this.view.getBigUint64(HEADER_OFFSET_SOURCE_FILE_ID, true);
160+
if (nodeId === 0n) {
161+
throw new Error("Node has no server source-file identity");
162+
}
163+
this._handleFileKey = `#${nodeId}`;
164+
}
165+
return this._handleFileKey;
166+
}
167+
150168
readFileReferences(structuredDataOffset: number): readonly FileReference[] {
151169
if (structuredDataOffset === NO_STRUCTURED_DATA) {
152170
return [];
@@ -477,12 +495,13 @@ export function findDescendant(root: Node, pos: number, end: number, kind: Synta
477495
export interface ParsedNodeHandle {
478496
index: number;
479497
kind: SyntaxKind;
498+
sourceFileId: string;
480499
path: PathKey;
481500
}
482501

483502
/**
484503
* Parse a compiler-produced node handle into its components.
485-
* Handle format: "index.kind.path" where path may contain dots.
504+
* Handle format: "index.kind.#sourceFileId.path" where path may contain dots.
486505
*/
487506
export function parseNodeHandleFromCompiler(handle: string): ParsedNodeHandle {
488507
const firstDot = handle.indexOf(".");
@@ -496,7 +515,13 @@ export function parseNodeHandleFromCompiler(handle: string): ParsedNodeHandle {
496515

497516
const indexText = handle.slice(0, firstDot);
498517
const kindText = handle.slice(firstDot + 1, secondDot);
499-
const path = handle.slice(secondDot + 1);
518+
const thirdDot = handle.indexOf(".", secondDot + 1);
519+
if (thirdDot === -1) {
520+
throw new Error(`Invalid node handle: ${handle}`);
521+
}
522+
const fileKey = handle.slice(secondDot + 1, thirdDot);
523+
const sourceFileId = fileKey.slice(1);
524+
const path = handle.slice(thirdDot + 1);
500525
const index = Number(indexText);
501526
const kind = Number(kindText);
502527
const key = tryPathKeyFromCanonical(path);
@@ -507,13 +532,16 @@ export function parseNodeHandleFromCompiler(handle: string): ParsedNodeHandle {
507532
!Number.isSafeInteger(kind) ||
508533
kind < 0 ||
509534
String(kind) !== kindText ||
535+
!/^#[1-9][0-9]*$/.test(fileKey) ||
536+
BigInt(sourceFileId) > 0xFFFFFFFFFFFFFFFFn ||
510537
key === undefined
511538
) {
512539
throw new Error(`Invalid node handle: ${handle}`);
513540
}
514541
return {
515542
index,
516543
kind: kind as SyntaxKind,
544+
sourceFileId,
517545
path: key,
518546
};
519547
}
@@ -536,5 +564,24 @@ export function getNodeId(node: Node): string {
536564
if (!(node instanceof RemoteNode)) {
537565
throw new Error("getNodeId requires a RemoteNode");
538566
}
539-
return node.id;
567+
const sourceFile = node["_sourceFile"];
568+
if (sourceFile instanceof RemoteSourceFile) {
569+
return `${node["index"]}.${node.kind}.${sourceFile.handleFileKey}.${sourceFile.path}`;
570+
}
571+
throw new Error("Node has no server source-file identity");
572+
}
573+
574+
/**
575+
* Get the compact handle identifying a node in its exact server source-file AST.
576+
* @internal
577+
*/
578+
export function getNodeRequestHandle(node: Node): string {
579+
if (!(node instanceof RemoteNode)) {
580+
throw new Error("getNodeRequestHandle requires a RemoteNode");
581+
}
582+
const sourceFile = node["_sourceFile"];
583+
if (sourceFile instanceof RemoteSourceFile) {
584+
return `${node["index"]}.${sourceFile.handleFileKey}`;
585+
}
586+
throw new Error("Node has no server source-file identity");
540587
}

0 commit comments

Comments
 (0)