Skip to content

Commit 3e87b7f

Browse files
committed
Merge branch 'main' into guyllian.gomez/yarn-pnp
2 parents 515e20b + 88d31a4 commit 3e87b7f

670 files changed

Lines changed: 28662 additions & 5800 deletions

File tree

Some content is hidden

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

Herebyfile.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import pc from "picocolors";
1717
import tmp from "tmp";
1818
import which from "which";
1919

20+
if (process.platform === "win32") {
21+
process.chdir(fs.realpathSync.native(process.cwd()));
22+
}
23+
2024
const __filename = url.fileURLToPath(new URL(import.meta.url));
2125
const __dirname = path.dirname(__filename);
2226

_extension/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
"type": "git",
1313
"url": "https://github.com/microsoft/typescript-go"
1414
},
15+
"enabledApiProposals": [
16+
"editorHoverVerbosityLevel"
17+
],
1518
"engines": {
16-
"vscode": "^1.106.0"
19+
"vscode": "^1.110.0"
1720
},
1821
"capabilities": {
1922
"untrustedWorkspaces": {
@@ -197,7 +200,7 @@
197200
"vscode-languageclient": "^10.0.0-next.21"
198201
},
199202
"devDependencies": {
200-
"@types/vscode": "~1.106.1",
203+
"@types/vscode": "~1.110.0",
201204
"@vscode/vsce": "^3.7.1",
202205
"esbuild": "^0.27.4"
203206
}

_extension/src/client.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from "vscode";
22

33
import {
4+
ClientCapabilities,
45
CloseAction,
56
CloseHandlerResult,
67
ErrorAction,
@@ -11,6 +12,7 @@ import {
1112
Message,
1213
NotebookDocumentFilter,
1314
ServerOptions,
15+
StaticFeature,
1416
TextDocumentFilter,
1517
TransportKind,
1618
} from "vscode-languageclient/node";
@@ -20,6 +22,7 @@ import {
2022
configurationMiddleware,
2123
sendNotificationMiddleware,
2224
} from "./configurationMiddleware";
25+
import { registerHoverFeature } from "./languageFeatures/hover";
2326
import { registerSourceDefinitionFeature } from "./languageFeatures/sourceDefinition";
2427
import { registerTagClosingFeature } from "./languageFeatures/tagClosing";
2528
import * as tr from "./telemetryReporting";
@@ -75,6 +78,7 @@ export class Client implements vscode.Disposable {
7578
...configurationMiddleware,
7679
},
7780
sendNotification: sendNotificationMiddleware,
81+
provideHover: () => undefined,
7882
},
7983
diagnosticPullOptions: {
8084
onChange: true,
@@ -173,6 +177,22 @@ export class Client implements vscode.Disposable {
173177
);
174178
this.disposables.push(this.client);
175179

180+
// Register a static feature to advertise verbosityLevel support in hover capabilities.
181+
this.client.registerFeature(
182+
{
183+
fillClientCapabilities(capabilities: ClientCapabilities): void {
184+
capabilities.textDocument = capabilities.textDocument ?? {};
185+
capabilities.textDocument.hover = capabilities.textDocument.hover ?? {};
186+
(capabilities.textDocument.hover as { verbosityLevel?: boolean; }).verbosityLevel = true;
187+
},
188+
initialize(): void {},
189+
getState() {
190+
return { kind: "static" as const };
191+
},
192+
clear(): void {},
193+
} satisfies StaticFeature,
194+
);
195+
176196
this.outputChannel.appendLine(`Starting language server...`);
177197
await this.client.start();
178198
this.isInitialized = true;
@@ -209,6 +229,7 @@ export class Client implements vscode.Disposable {
209229
this.disposables.push(
210230
serverTelemetryListener,
211231
registerSourceDefinitionFeature(this.client),
232+
registerHoverFeature(this.documentSelector, this.client),
212233
registerTagClosingFeature("typescript", this.documentSelector, this.client),
213234
registerTagClosingFeature("javascript", this.documentSelector, this.client),
214235
);
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import * as vscode from "vscode";
2+
import {
3+
Hover,
4+
HoverRequest,
5+
LanguageClient,
6+
TextDocumentPositionParams,
7+
} from "vscode-languageclient/node";
8+
9+
interface HoverResult extends Hover {
10+
canIncreaseVerbosity?: boolean;
11+
}
12+
13+
interface HoverParamsWithVerbosity extends TextDocumentPositionParams {
14+
verbosityLevel?: number;
15+
}
16+
17+
class VerboseHoverProvider implements vscode.HoverProvider {
18+
private lastHoverAndLevel: [vscode.Hover, number] | undefined;
19+
20+
constructor(private readonly client: LanguageClient) {}
21+
22+
async provideHover(
23+
document: vscode.TextDocument,
24+
position: vscode.Position,
25+
token: vscode.CancellationToken,
26+
context?: vscode.HoverContext,
27+
): Promise<vscode.VerboseHover | vscode.Hover | undefined> {
28+
// HoverContext and VerboseHover are proposed API; guard against missing or unexpected properties.
29+
const verbosityDelta = typeof context?.verbosityDelta === "number" ? context.verbosityDelta : undefined;
30+
const previousHover = context?.previousHover instanceof vscode.Hover ? context.previousHover : undefined;
31+
const verbosityLevel = verbosityDelta !== undefined ? Math.max(0, this.getPreviousLevel(previousHover) + verbosityDelta) : undefined;
32+
33+
const params: HoverParamsWithVerbosity = {
34+
...this.client.code2ProtocolConverter.asTextDocumentPositionParams(document, position),
35+
verbosityLevel,
36+
};
37+
38+
let response: HoverResult | null;
39+
try {
40+
response = await this.client.sendRequest(HoverRequest.type, params, token);
41+
}
42+
catch (error) {
43+
return this.client.handleFailedRequest(HoverRequest.type, token, error, null) ?? undefined;
44+
}
45+
46+
if (!response || token.isCancellationRequested) {
47+
return undefined;
48+
}
49+
50+
const hover = this.client.protocol2CodeConverter.asHover(response);
51+
// VerboseHover is proposed API; guard against missing or changed constructor.
52+
try {
53+
const verboseHover = new vscode.VerboseHover(
54+
hover.contents,
55+
hover.range,
56+
response.canIncreaseVerbosity,
57+
(verbosityLevel ?? 0) > 0,
58+
);
59+
60+
this.lastHoverAndLevel = [verboseHover, verbosityLevel ?? 0];
61+
return verboseHover;
62+
}
63+
catch {
64+
return hover;
65+
}
66+
}
67+
68+
private getPreviousLevel(previousHover: vscode.Hover | undefined): number {
69+
if (previousHover && this.lastHoverAndLevel && this.lastHoverAndLevel[0] === previousHover) {
70+
return this.lastHoverAndLevel[1];
71+
}
72+
return 0;
73+
}
74+
}
75+
76+
export function registerHoverFeature(
77+
selector: vscode.DocumentSelector,
78+
client: LanguageClient,
79+
): vscode.Disposable {
80+
return vscode.languages.registerHoverProvider(selector, new VerboseHoverProvider(client));
81+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
declare module "vscode" {
7+
/**
8+
* A hover represents additional information for a symbol or word. Hovers are
9+
* rendered in a tooltip-like widget.
10+
*/
11+
export class VerboseHover extends Hover {
12+
/**
13+
* Can increase the verbosity of the hover
14+
*/
15+
canIncreaseVerbosity?: boolean;
16+
17+
/**
18+
* Can decrease the verbosity of the hover
19+
*/
20+
canDecreaseVerbosity?: boolean;
21+
22+
/**
23+
* Creates a new hover object.
24+
*
25+
* @param contents The contents of the hover.
26+
* @param range The range to which the hover applies.
27+
*/
28+
constructor(contents: MarkdownString | MarkedString | Array<MarkdownString | MarkedString>, range?: Range, canIncreaseVerbosity?: boolean, canDecreaseVerbosity?: boolean);
29+
}
30+
31+
export interface HoverContext {
32+
/**
33+
* The delta by which to increase/decrease the hover verbosity level
34+
*/
35+
readonly verbosityDelta?: number;
36+
37+
/**
38+
* The previous hover sent for the same position
39+
*/
40+
readonly previousHover?: Hover;
41+
}
42+
43+
export enum HoverVerbosityAction {
44+
/**
45+
* Increase the hover verbosity
46+
*/
47+
Increase = 0,
48+
/**
49+
* Decrease the hover verbosity
50+
*/
51+
Decrease = 1,
52+
}
53+
54+
/**
55+
* The hover provider class
56+
*/
57+
export interface HoverProvider {
58+
/**
59+
* Provide a hover for the given position and document. Multiple hovers at the same
60+
* position will be merged by the editor. A hover can have a range which defaults
61+
* to the word range at the position when omitted.
62+
*
63+
* @param document The document in which the command was invoked.
64+
* @param position The position at which the command was invoked.
65+
* @param token A cancellation token.
66+
* @param context A hover context.
67+
* @returns A hover or a thenable that resolves to such. The lack of a result can be
68+
* signaled by returning `undefined` or `null`.
69+
*/
70+
provideHover(document: TextDocument, position: Position, token: CancellationToken, context?: HoverContext): ProviderResult<VerboseHover>;
71+
}
72+
}

_packages/api/src/node/encoder.generated.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ export function getNodeCommonData(node: Node): number {
6363
case SyntaxKind.HeritageClause:
6464
return ((node as HeritageClause).token === SyntaxKind.ImplementsKeyword ? 1 : 0) << 24;
6565
case SyntaxKind.ExportAssignment:
66-
case SyntaxKind.JSExportAssignment:
6766
return ((node as ExportAssignment).isExportEquals ? 1 : 0) << 24;
6867
case SyntaxKind.ExportSpecifier:
6968
return ((node as ExportSpecifier).isTypeOnly ? 1 : 0) << 24;

_packages/api/src/node/protocol.generated.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ export const childProperties: Readonly<Partial<Record<SyntaxKind, readonly (stri
5050
[SyntaxKind.NamespaceImport]: ["name"],
5151
[SyntaxKind.NamedImports]: ["elements"],
5252
[SyntaxKind.ExportAssignment]: ["modifiers", "type", "expression"],
53-
[SyntaxKind.JSExportAssignment]: ["modifiers", "type", "expression"],
54-
[SyntaxKind.CommonJSExport]: ["modifiers", "name", "type", "initializer"],
5553
[SyntaxKind.NamespaceExportDeclaration]: ["modifiers", "name"],
5654
[SyntaxKind.NamespaceExport]: ["name"],
5755
[SyntaxKind.NamedExports]: ["elements"],

_packages/api/test/async/api.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ import {
4343
createIdentifier,
4444
createKeywordTypeNode,
4545
createParameterDeclaration,
46+
createToken,
47+
createTypeAliasDeclaration,
4648
createTypeReferenceNode,
4749
createUnionTypeNode,
4850
} from "@typescript/ast/factory";
@@ -2354,6 +2356,28 @@ doThing();
23542356
}
23552357
});
23562358

2359+
test("Factory ModifierList auto-conversion", async () => {
2360+
const api = spawnAPI();
2361+
try {
2362+
const snapshot = await api.updateSnapshot({ openProject: "/tsconfig.json" });
2363+
const project = snapshot.getProject("/tsconfig.json")!;
2364+
const node = createTypeAliasDeclaration(
2365+
[createToken(SyntaxKind.ExportKeyword)],
2366+
createIdentifier("Test"),
2367+
undefined,
2368+
createKeywordTypeNode(SyntaxKind.AnyKeyword),
2369+
);
2370+
2371+
assert.equal(await project.emitter.printNode(node), "export type Test = any;");
2372+
2373+
const cloned = getSynthesizedDeepClone(node);
2374+
assert.equal(await project.emitter.printNode(cloned), "export type Test = any;");
2375+
}
2376+
finally {
2377+
await api.close();
2378+
}
2379+
});
2380+
23572381
test("Parse-clone-emit roundtrip", async () => {
23582382
const tsSource = fileURLToPath(new URL("../../../../_submodules/TypeScript/src", import.meta.url).toString());
23592383
const api = new API({

_packages/api/test/sync/api.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ import {
5151
createIdentifier,
5252
createKeywordTypeNode,
5353
createParameterDeclaration,
54+
createToken,
55+
createTypeAliasDeclaration,
5456
createTypeReferenceNode,
5557
createUnionTypeNode,
5658
} from "@typescript/ast/factory";
@@ -2362,6 +2364,28 @@ doThing();
23622364
}
23632365
});
23642366

2367+
test("Factory ModifierList auto-conversion", () => {
2368+
const api = spawnAPI();
2369+
try {
2370+
const snapshot = api.updateSnapshot({ openProject: "/tsconfig.json" });
2371+
const project = snapshot.getProject("/tsconfig.json")!;
2372+
const node = createTypeAliasDeclaration(
2373+
[createToken(SyntaxKind.ExportKeyword)],
2374+
createIdentifier("Test"),
2375+
undefined,
2376+
createKeywordTypeNode(SyntaxKind.AnyKeyword),
2377+
);
2378+
2379+
assert.equal(project.emitter.printNode(node), "export type Test = any;");
2380+
2381+
const cloned = getSynthesizedDeepClone(node);
2382+
assert.equal(project.emitter.printNode(cloned), "export type Test = any;");
2383+
}
2384+
finally {
2385+
api.close();
2386+
}
2387+
});
2388+
23652389
test("Parse-clone-emit roundtrip", () => {
23662390
const tsSource = fileURLToPath(new URL("../../../../_submodules/TypeScript/src", import.meta.url).toString());
23672391
const api = new API({

_packages/ast/src/ast.generated.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -700,12 +700,6 @@ export interface ExportAssignment extends DeclarationBase, StatementBase, Modifi
700700
readonly type: TypeNode;
701701
readonly expression: Expression;
702702
}
703-
export interface CommonJSExport extends StatementBase, DeclarationBase, ModifiersBase {
704-
readonly kind: SyntaxKind.CommonJSExport;
705-
readonly name: Identifier;
706-
readonly type: TypeNode;
707-
readonly initializer: Expression;
708-
}
709703
export interface NamespaceExportDeclaration extends DeclarationBase, StatementBase, ModifiersBase {
710704
readonly kind: SyntaxKind.NamespaceExportDeclaration;
711705
readonly name: Identifier;

0 commit comments

Comments
 (0)