Skip to content

Commit

Permalink
[typespec-vscode] Improvements for the intellisense of tspconfig.yaml (
Browse files Browse the repository at this point in the history
…#5186)

Add a intellisense for the extends path in tspconfig.yaml


Fixes:#4855

---------

Co-authored-by: Rodge Fu <fwj_ac@msn.com>
  • Loading branch information
mzhongl524 and RodgeFu authored Jan 24, 2025
1 parent dd65f86 commit 801dc0d
Show file tree
Hide file tree
Showing 21 changed files with 828 additions and 68 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/compiler"
---

Support the auto completion for extends, imports, rule, rule sets and variables in tspconfig.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: fix
packages:
- "@typespec/compiler"
---

Fix bug in tspconfig.yaml
- Fix the issue that extra " will be added when auto completing emitter options inside ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/compiler"
---

Show required/optional information in the details of emitter's options completion item in tspconfig.yaml
Original file line number Diff line number Diff line change
@@ -1,54 +1,57 @@
import { joinPaths } from "../core/path-utils.js";
import { NpmPackage, NpmPackageProvider } from "./npm-package-provider.js";

export class EmitterProvider {
private isEmitterPackageCache = new Map<string, boolean>();
constructor(private npmPackageProvider: NpmPackageProvider) {}
export class LibraryProvider {
private libPackageFilterResultCache = new Map<string, boolean>();
constructor(
private npmPackageProvider: NpmPackageProvider,
private filter: (libExports: Record<string, any>) => boolean,
) {}

/**
*
* @param startFolder folder starts to search for package.json with emitters defined as dependencies
* @param startFolder folder starts to search for package.json with library defined as dependencies
* @returns
*/
async listEmitters(startFolder: string): Promise<Record<string, NpmPackage>> {
async listLibraries(startFolder: string): Promise<Record<string, NpmPackage>> {
const packageJsonFolder = await this.npmPackageProvider.getPackageJsonFolder(startFolder);
if (!packageJsonFolder) return {};

const pkg = await this.npmPackageProvider.get(packageJsonFolder);
const data = await pkg?.getPackageJsonData();
if (!data) return {};

const emitters: Record<string, NpmPackage> = {};
const libs: Record<string, NpmPackage> = {};
const allDep = {
...(data.dependencies ?? {}),
...(data.devDependencies ?? {}),
};
for (const dep of Object.keys(allDep)) {
const depPkg = await this.getEmitterFromDep(packageJsonFolder, dep);
const depPkg = await this.getLibraryFromDep(packageJsonFolder, dep);
if (depPkg) {
emitters[dep] = depPkg;
libs[dep] = depPkg;
}
}
return emitters;
return libs;
}

/**
*
* @param startFolder folder starts to search for package.json with emitters defined as dependencies
* @param emitterName
* @param startFolder folder starts to search for package.json with library defined as dependencies
* @param libName
* @returns
*/
async getEmitter(startFolder: string, emitterName: string): Promise<NpmPackage | undefined> {
async getLibrary(startFolder: string, libName: string): Promise<NpmPackage | undefined> {
const packageJsonFolder = await this.npmPackageProvider.getPackageJsonFolder(startFolder);
if (!packageJsonFolder) {
return undefined;
}
return this.getEmitterFromDep(packageJsonFolder, emitterName);
return this.getLibraryFromDep(packageJsonFolder, libName);
}

private async isEmitter(depName: string, pkg: NpmPackage) {
if (this.isEmitterPackageCache.has(depName)) {
return this.isEmitterPackageCache.get(depName);
private async getLibFilterResult(depName: string, pkg: NpmPackage) {
if (this.libPackageFilterResultCache.has(depName)) {
return this.libPackageFilterResultCache.get(depName);
}

const data = await pkg.getPackageJsonData();
Expand All @@ -61,19 +64,20 @@ export class EmitterProvider {
const exports = await pkg.getModuleExports();
// don't add to cache when failing to load exports which is unexpected
if (!exports) return false;
const isEmitter = exports.$onEmit !== undefined;
this.isEmitterPackageCache.set(depName, isEmitter);
return isEmitter;

const filterResult = this.filter(exports);
this.libPackageFilterResultCache.set(depName, filterResult);
return filterResult;
} else {
this.isEmitterPackageCache.set(depName, false);
this.libPackageFilterResultCache.set(depName, false);
return false;
}
}

private async getEmitterFromDep(packageJsonFolder: string, depName: string) {
private async getLibraryFromDep(packageJsonFolder: string, depName: string) {
const depFolder = joinPaths(packageJsonFolder, "node_modules", depName);
const depPkg = await this.npmPackageProvider.get(depFolder);
if (depPkg && (await this.isEmitter(depName, depPkg))) {
if (depPkg && (await this.getLibFilterResult(depName, depPkg))) {
return depPkg;
}
return undefined;
Expand Down
13 changes: 11 additions & 2 deletions packages/compiler/src/server/serverlib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ import { createCompileService } from "./compile-service.js";
import { resolveCompletion } from "./completion.js";
import { Commands } from "./constants.js";
import { convertDiagnosticToLsp } from "./diagnostics.js";
import { EmitterProvider } from "./emitter-provider.js";
import { createFileService } from "./file-service.js";
import { createFileSystemCache } from "./file-system-cache.js";
import { LibraryProvider } from "./lib-provider.js";
import { NpmPackageProvider } from "./npm-package-provider.js";
import { getSymbolStructure } from "./symbol-structure.js";
import { provideTspconfigCompletionItems } from "./tspconfig/completion.js";
Expand Down Expand Up @@ -134,7 +134,14 @@ export function createServer(host: ServerHost): Server {
});
const compilerHost = createCompilerHost();
const npmPackageProvider = new NpmPackageProvider(compilerHost);
const emitterProvider = new EmitterProvider(npmPackageProvider);
const emitterProvider = new LibraryProvider(
npmPackageProvider,
(exports) => exports.$onEmit !== undefined,
);
const linterProvider = new LibraryProvider(
npmPackageProvider,
(exports) => exports.$linter !== undefined,
);

const compileService = createCompileService({
fileService,
Expand Down Expand Up @@ -789,7 +796,9 @@ export function createServer(host: ServerHost): Server {
if (doc) {
const items = await provideTspconfigCompletionItems(doc, params.position, {
fileService,
compilerHost,
emitterProvider,
linterProvider,
log,
});
return CompletionList.create(items);
Expand Down
Loading

0 comments on commit 801dc0d

Please sign in to comment.