Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 88 additions & 43 deletions _packages/native-preview/src/api/async/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/// <reference path="../node/node.ts" preserve="true" />

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by: at one point node.ts performed module augmentation, but that’s been gone for a while, so this is no longer needed.

import { CheckFlags } from "#enums/checkFlags";
import { CompletionItemKind } from "#enums/completionItemKind";
import { DiagnosticCategory } from "#enums/diagnosticCategory";
Expand Down Expand Up @@ -703,6 +702,7 @@ export class Project {
readonly program: Program;
readonly checker: Checker;
readonly emitter: Emitter;
readonly languageService: LanguageService;
private client: Client;
private snapshotId: number;

Expand Down Expand Up @@ -736,6 +736,40 @@ export class Project {
objectRegistry,
);
this.emitter = new Emitter(client);
this.languageService = new LanguageService(snapshotId, this, client, objectRegistry);
}

/** @deprecated Use `languageService.getImportAdderEdits`. */
getImportAdderEdits(file: DocumentIdentifier, actions: readonly ImportAdderAction[]): Promise<readonly TextEdit[]> {
return this.languageService.getImportAdderEdits(file, actions);
}

/** @deprecated Use `languageService.getImportEditsForSymbols`. */
getImportEditsForSymbols(file: DocumentIdentifier, symbols: readonly Symbol[], options: GetImportEditsForSymbolsOptions = {}): Promise<readonly TextEdit[]> {
return this.languageService.getImportEditsForSymbols(file, symbols, options);
}

dispose(): void {
this.checker.dispose();
}
}

export class LanguageService {
private snapshotId: number;
private project: Project;
private client: Client;
private objectRegistry: ProjectObjectRegistry;

constructor(
snapshotId: number,
project: Project,
client: Client,
objectRegistry: ProjectObjectRegistry,
) {
this.snapshotId = snapshotId;
this.project = project;
this.client = client;
this.objectRegistry = objectRegistry;
}

async getImportAdderEdits(file: DocumentIdentifier, actions: readonly ImportAdderAction[]): Promise<readonly TextEdit[]> {
Expand All @@ -757,7 +791,7 @@ export class Project {

const data = await this.client.apiRequest<TextEdit[]>("getImportAdderEdits", {
snapshot: this.snapshotId,
project: this.id,
project: this.project.id,
file,
actions: requestActions,
});
Expand All @@ -783,8 +817,49 @@ export class Project {
);
}

dispose(): void {
this.checker.dispose();
async getReferencedSymbolsForNode(node: Node, position: number): Promise<ReferencedSymbolEntry[]> {
const data = await this.client.apiRequest<{ definition: string; symbol?: SymbolResponse; references: string[]; }[] | null>("getReferencedSymbolsForNode", {
snapshot: this.snapshotId,
project: this.project.id,
node: getNodeId(node),
position,
});
return (data ?? []).map(entry => ({
definition: new NodeHandle(entry.definition, this.project),
symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
references: (entry.references ?? []).map(h => new NodeHandle(h, this.project)),
}));
}

async getSignatureUsage(signatureDecl: Node): Promise<SignatureUsage[]> {
const data = await this.client.apiRequest<{ name: string; call?: string; }[] | null>("getSignatureUsages", {
snapshot: this.snapshotId,
project: this.project.id,
signatureDecl: getNodeId(signatureDecl),
});
return (data ?? []).map(entry => ({
name: new NodeHandle(entry.name, this.project),
call: entry.call ? new NodeHandle(entry.call, this.project) : undefined,
}));
}

async getCompletionsAtPosition(document: string, position: number, options?: CompletionOptions): Promise<CompletionInfo | undefined> {
const data = await this.client.apiRequest<CompletionInfoResponse | null>("getCompletionsAtPosition", {
snapshot: this.snapshotId,
project: this.project.id,
file: document,
position,
triggerCharacter: options?.triggerCharacter,
includeSymbol: options?.includeSymbol,
});
if (!data) return undefined;
return {
isIncomplete: data.isIncomplete,
entries: data.entries.map(e => ({
...e,
symbol: e.symbol ? this.objectRegistry.getOrCreateSymbol(e.symbol) : undefined,
})),
};
}
}

Expand Down Expand Up @@ -1207,49 +1282,19 @@ export class Checker {
return (data ?? []).map(h => new NodeHandle(h, this.project));
}

async getReferencedSymbolsForNode(node: Node, position: number): Promise<ReferencedSymbolEntry[]> {
const data = await this.client.apiRequest<{ definition: string; symbol?: SymbolResponse; references: string[]; }[] | null>("getReferencedSymbolsForNode", {
snapshot: this.snapshotId,
project: this.project.id,
node: getNodeId(node),
position,
});
return (data ?? []).map(entry => ({
definition: new NodeHandle(entry.definition, this.project),
symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
references: (entry.references ?? []).map(h => new NodeHandle(h, this.project)),
}));
/** @deprecated Use `project.languageService.getReferencedSymbolsForNode`. */
getReferencedSymbolsForNode(node: Node, position: number): Promise<ReferencedSymbolEntry[]> {
return this.project.languageService.getReferencedSymbolsForNode(node, position);
}

async getSignatureUsage(signatureDecl: Node): Promise<SignatureUsage[]> {
const data = await this.client.apiRequest<{ name: string; call?: string; }[] | null>("getSignatureUsages", {
snapshot: this.snapshotId,
project: this.project.id,
signatureDecl: getNodeId(signatureDecl),
});
return (data ?? []).map(entry => ({
name: new NodeHandle(entry.name, this.project),
call: entry.call ? new NodeHandle(entry.call, this.project) : undefined,
}));
/** @deprecated Use `project.languageService.getSignatureUsage`. */
getSignatureUsage(signatureDecl: Node): Promise<SignatureUsage[]> {
return this.project.languageService.getSignatureUsage(signatureDecl);
}

async getCompletionsAtPosition(document: string, position: number, options?: CompletionOptions): Promise<CompletionInfo | undefined> {
const data = await this.client.apiRequest<CompletionInfoResponse | null>("getCompletionsAtPosition", {
snapshot: this.snapshotId,
project: this.project.id,
file: document,
position,
triggerCharacter: options?.triggerCharacter,
includeSymbol: options?.includeSymbol,
});
if (!data) return undefined;
return {
isIncomplete: data.isIncomplete,
entries: data.entries.map(e => ({
...e,
symbol: e.symbol ? this.objectRegistry.getOrCreateSymbol(e.symbol) : undefined,
})),
};
/** @deprecated Use `project.languageService.getCompletionsAtPosition`. */
getCompletionsAtPosition(document: string, position: number, options?: CompletionOptions): Promise<CompletionInfo | undefined> {
return this.project.languageService.getCompletionsAtPosition(document, position, options);
}

/**
Expand Down
6 changes: 3 additions & 3 deletions _packages/native-preview/src/api/async/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,14 @@ export interface CompletionEntryLabelDetails {
description?: string | undefined;
}

/** Options for {@link Checker.getCompletionsAtPosition}. */
/** Options for {@link LanguageService.getCompletionsAtPosition}. */
export interface CompletionOptions {
triggerCharacter?: string | undefined;
/** Include a `symbol` property on each completion entry. Only populated for symbol-based completions (not keywords or literals). */
includeSymbol?: boolean | undefined;
}

/** A single completion item returned by {@link Checker.getCompletionsAtPosition}. */
/** A single completion item returned by {@link LanguageService.getCompletionsAtPosition}. */
export interface CompletionEntry {
readonly name: string;
readonly kind?: CompletionItemKind | undefined;
Expand All @@ -355,7 +355,7 @@ export interface CompletionEntry {
readonly symbol?: Symbol | undefined;
}

/** The result of {@link Checker.getCompletionsAtPosition}. */
/** The result of {@link LanguageService.getCompletionsAtPosition}. */
export interface CompletionInfo {
readonly isIncomplete: boolean;
readonly entries: readonly CompletionEntry[];
Expand Down
125 changes: 85 additions & 40 deletions _packages/native-preview/src/api/sync/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
// Source: src/api/async/api.ts
// Regenerate: npm run generate (from _packages/native-preview)
//
/// <reference path="../node/node.ts" preserve="true" />
import { CheckFlags } from "#enums/checkFlags";
import { CompletionItemKind } from "#enums/completionItemKind";
import { DiagnosticCategory } from "#enums/diagnosticCategory";
Expand Down Expand Up @@ -711,6 +710,7 @@ export class Project {
readonly program: Program;
readonly checker: Checker;
readonly emitter: Emitter;
readonly languageService: LanguageService;
private client: Client;
private snapshotId: number;

Expand Down Expand Up @@ -744,6 +744,40 @@ export class Project {
objectRegistry,
);
this.emitter = new Emitter(client);
this.languageService = new LanguageService(snapshotId, this, client, objectRegistry);
}

/** @deprecated Use `languageService.getImportAdderEdits`. */
getImportAdderEdits(file: DocumentIdentifier, actions: readonly ImportAdderAction[]): readonly TextEdit[] {
return this.languageService.getImportAdderEdits(file, actions);
}

/** @deprecated Use `languageService.getImportEditsForSymbols`. */
getImportEditsForSymbols(file: DocumentIdentifier, symbols: readonly Symbol[], options: GetImportEditsForSymbolsOptions = {}): readonly TextEdit[] {
return this.languageService.getImportEditsForSymbols(file, symbols, options);
}

dispose(): void {
this.checker.dispose();
}
}

export class LanguageService {
private snapshotId: number;
private project: Project;
private client: Client;
private objectRegistry: ProjectObjectRegistry;

constructor(
snapshotId: number,
project: Project,
client: Client,
objectRegistry: ProjectObjectRegistry,
) {
this.snapshotId = snapshotId;
this.project = project;
this.client = client;
this.objectRegistry = objectRegistry;
}

getImportAdderEdits(file: DocumentIdentifier, actions: readonly ImportAdderAction[]): readonly TextEdit[] {
Expand All @@ -765,7 +799,7 @@ export class Project {

const data = this.client.apiRequest<TextEdit[]>("getImportAdderEdits", {
snapshot: this.snapshotId,
project: this.id,
project: this.project.id,
file,
actions: requestActions,
});
Expand All @@ -791,8 +825,49 @@ export class Project {
);
}

dispose(): void {
this.checker.dispose();
getReferencedSymbolsForNode(node: Node, position: number): ReferencedSymbolEntry[] {
const data = this.client.apiRequest<{ definition: string; symbol?: SymbolResponse; references: string[]; }[] | null>("getReferencedSymbolsForNode", {
snapshot: this.snapshotId,
project: this.project.id,
node: getNodeId(node),
position,
});
return (data ?? []).map(entry => ({
definition: new NodeHandle(entry.definition, this.project),
symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
references: (entry.references ?? []).map(h => new NodeHandle(h, this.project)),
}));
}

getSignatureUsage(signatureDecl: Node): SignatureUsage[] {
const data = this.client.apiRequest<{ name: string; call?: string; }[] | null>("getSignatureUsages", {
snapshot: this.snapshotId,
project: this.project.id,
signatureDecl: getNodeId(signatureDecl),
});
return (data ?? []).map(entry => ({
name: new NodeHandle(entry.name, this.project),
call: entry.call ? new NodeHandle(entry.call, this.project) : undefined,
}));
}

getCompletionsAtPosition(document: string, position: number, options?: CompletionOptions): CompletionInfo | undefined {
const data = this.client.apiRequest<CompletionInfoResponse | null>("getCompletionsAtPosition", {
snapshot: this.snapshotId,
project: this.project.id,
file: document,
position,
triggerCharacter: options?.triggerCharacter,
includeSymbol: options?.includeSymbol,
});
if (!data) return undefined;
return {
isIncomplete: data.isIncomplete,
entries: data.entries.map(e => ({
...e,
symbol: e.symbol ? this.objectRegistry.getOrCreateSymbol(e.symbol) : undefined,
})),
};
}
}

Expand Down Expand Up @@ -1215,49 +1290,19 @@ export class Checker {
return (data ?? []).map(h => new NodeHandle(h, this.project));
}

/** @deprecated Use `project.languageService.getReferencedSymbolsForNode`. */
getReferencedSymbolsForNode(node: Node, position: number): ReferencedSymbolEntry[] {
const data = this.client.apiRequest<{ definition: string; symbol?: SymbolResponse; references: string[]; }[] | null>("getReferencedSymbolsForNode", {
snapshot: this.snapshotId,
project: this.project.id,
node: getNodeId(node),
position,
});
return (data ?? []).map(entry => ({
definition: new NodeHandle(entry.definition, this.project),
symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
references: (entry.references ?? []).map(h => new NodeHandle(h, this.project)),
}));
return this.project.languageService.getReferencedSymbolsForNode(node, position);
}

/** @deprecated Use `project.languageService.getSignatureUsage`. */
getSignatureUsage(signatureDecl: Node): SignatureUsage[] {
const data = this.client.apiRequest<{ name: string; call?: string; }[] | null>("getSignatureUsages", {
snapshot: this.snapshotId,
project: this.project.id,
signatureDecl: getNodeId(signatureDecl),
});
return (data ?? []).map(entry => ({
name: new NodeHandle(entry.name, this.project),
call: entry.call ? new NodeHandle(entry.call, this.project) : undefined,
}));
return this.project.languageService.getSignatureUsage(signatureDecl);
}

/** @deprecated Use `project.languageService.getCompletionsAtPosition`. */
getCompletionsAtPosition(document: string, position: number, options?: CompletionOptions): CompletionInfo | undefined {
const data = this.client.apiRequest<CompletionInfoResponse | null>("getCompletionsAtPosition", {
snapshot: this.snapshotId,
project: this.project.id,
file: document,
position,
triggerCharacter: options?.triggerCharacter,
includeSymbol: options?.includeSymbol,
});
if (!data) return undefined;
return {
isIncomplete: data.isIncomplete,
entries: data.entries.map(e => ({
...e,
symbol: e.symbol ? this.objectRegistry.getOrCreateSymbol(e.symbol) : undefined,
})),
};
return this.project.languageService.getCompletionsAtPosition(document, position, options);
}

/**
Expand Down
6 changes: 3 additions & 3 deletions _packages/native-preview/src/api/sync/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,14 @@ export interface CompletionEntryLabelDetails {
description?: string | undefined;
}

/** Options for {@link Checker.getCompletionsAtPosition}. */
/** Options for {@link LanguageService.getCompletionsAtPosition}. */
export interface CompletionOptions {
triggerCharacter?: string | undefined;
/** Include a `symbol` property on each completion entry. Only populated for symbol-based completions (not keywords or literals). */
includeSymbol?: boolean | undefined;
}

/** A single completion item returned by {@link Checker.getCompletionsAtPosition}. */
/** A single completion item returned by {@link LanguageService.getCompletionsAtPosition}. */
export interface CompletionEntry {
readonly name: string;
readonly kind?: CompletionItemKind | undefined;
Expand All @@ -363,7 +363,7 @@ export interface CompletionEntry {
readonly symbol?: Symbol | undefined;
}

/** The result of {@link Checker.getCompletionsAtPosition}. */
/** The result of {@link LanguageService.getCompletionsAtPosition}. */
export interface CompletionInfo {
readonly isIncomplete: boolean;
readonly entries: readonly CompletionEntry[];
Expand Down
Loading