Skip to content
Draft
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
10 changes: 7 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,13 @@
// Set the telemetry key environment variable to use if you dont want to set it in package.json
//"TYPESPEC_VSCODE_TELEMETRY_KEY": "{The instrumentation key of your Application Insights}",

//"ENABLE_SERVER_COMPILE_LOGGING": "true",
//"ENABLE_UPDATE_MANAGER_LOGGING": "true",
//"ENABLE_LM_LOGGING": "true",
// Enable debug logging for specific areas using DEBUG environment variable
// Examples:
// "DEBUG": "typespec:server_compile" - Enable server compilation debug logs
// "DEBUG": "typespec:lm" - Enable Language Model debug logs
// "DEBUG": "typespec:*" - Enable all typespec debug logs
// "DEBUG": "typespec:server_compile,typespec:compile_config" - Enable multiple areas
//"DEBUG": "typespec:server_compile,typespec:update_manager,typespec:compile_config,typespec:lm",

"TYPESPEC_SERVER_NODE_OPTIONS": "--nolazy --inspect-brk=4242",
"TYPESPEC_DEVELOPMENT_MODE": "true"
Expand Down
2 changes: 2 additions & 0 deletions packages/compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
"@inquirer/prompts": "^8.0.1",
"ajv": "~8.17.1",
"change-case": "~5.4.4",
"debug": "~4.4.0",
"env-paths": "^3.0.0",
"globby": "~16.0.0",
"is-unicode-supported": "^2.1.0",
Expand All @@ -125,6 +126,7 @@
},
"devDependencies": {
"@types/babel__code-frame": "~7.0.6",
"@types/debug": "~4.1.12",
"@types/mustache": "~4.2.5",
"@types/node": "~25.0.2",
"@types/semver": "^7.5.8",
Expand Down
19 changes: 12 additions & 7 deletions packages/compiler/src/server/compile-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { deepClone, distinctArray } from "../utils/misc.js";
import { getLocationInYamlScript } from "../yaml/diagnostics.js";
import { parseYaml } from "../yaml/parser.js";
import { ClientConfigProvider } from "./client-config-provider.js";
import { serverOptions } from "./constants.js";
import { debugLoggers, serverOptions } from "./constants.js";
import { resolveEntrypointFile } from "./entrypoint-resolver.js";
import { FileService } from "./file-service.js";
import { FileSystemCache } from "./file-system-cache.js";
Expand Down Expand Up @@ -90,6 +90,8 @@ export function createCompileService({
const eventListeners = new Map<string, (...args: unknown[]) => void | Promise<void>>();
const compileManager = new ServerCompileManager(updateManager, compilerHost, log);
let configFilePath: string | undefined;
const debug = debugLoggers.compileConfig;
const logDebug = debug.enabled ? log : () => {};

return { compile, getScript, on, notifyChange, getMainFileForDocument };

Expand Down Expand Up @@ -129,15 +131,15 @@ export function createCompileService({
}
const mainFile = await getMainFileForDocument(path);
if (mainFile === undefined) {
log({ level: "debug", message: `failed to resolve main file for ${path}` });
logDebug({ level: "debug", message: `failed to resolve main file for ${path}` });
return undefined;
}
if (!mainFile.endsWith(".tsp")) {
return undefined;
}
const config = await getConfig(mainFile);
configFilePath = config.filename;
log({ level: "debug", message: `config resolved`, detail: config });
logDebug({ level: "debug", message: `config resolved`, detail: config });
const [optionsFromConfig, _] = resolveOptionsFromConfig(config, {
cwd: getDirectoryPath(path),
});
Expand Down Expand Up @@ -217,7 +219,7 @@ export function createCompileService({
) {
// If the file that changed wasn't imported by anything from the main
// file, retry using the file itself as the main file.
log({
logDebug({
level: "debug",
message: `target file was not included in compiling, try to compile ${path} as main file directly`,
});
Expand Down Expand Up @@ -246,7 +248,7 @@ export function createCompileService({
const [yamlScript] = parseYaml(await serverHost.compilerHost.readFile(configFilePath));
const target = getLocationInYamlScript(yamlScript, ["emit", emitterName], "key");
if (target.pos === 0) {
log({
logDebug({
level: "debug",
message: `Unexpected situation, can't find emitter '${emitterName}' in config file '${configFilePath}'`,
});
Expand Down Expand Up @@ -286,7 +288,7 @@ export function createCompileService({
const lookupDir = entrypointStat.isDirectory() ? mainFile : getDirectoryPath(mainFile);
const configPath = await findTypeSpecConfigPath(compilerHost, lookupDir, true);
if (!configPath) {
log({
logDebug({
level: "debug",
message: `can't find path with config file, try to use default config`,
});
Expand Down Expand Up @@ -337,7 +339,10 @@ export function createCompileService({
*/
async function getMainFileForDocument(path: string) {
if (path.startsWith("untitled:")) {
log({ level: "debug", message: `untitled document treated as its own main file: ${path}` });
logDebug({
level: "debug",
message: `untitled document treated as its own main file: ${path}`,
});
return path;
}

Expand Down
16 changes: 13 additions & 3 deletions packages/compiler/src/server/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import createDebug from "debug";
import { CompilerOptions } from "../core/options.js";

export const serverOptions: CompilerOptions = {
Expand All @@ -14,7 +15,16 @@ export const Commands = {
};

/**
* Environment variables to enable some logging when needed
* Debug loggers for different areas. Can be enabled via DEBUG environment variable.
* Usage: DEBUG=typespec:server_compile,typespec:compile_config
*
* Examples:
* DEBUG=typespec:server_compile - Enable server compilation debug logs
* DEBUG=typespec:* - Enable all typespec debug logs
* DEBUG=typespec:server_compile,typespec:compile_config - Enable multiple areas
*/
export const ENABLE_SERVER_COMPILE_LOGGING = "ENABLE_SERVER_COMPILE_LOGGING";
export const ENABLE_UPDATE_MANAGER_LOGGING = "ENABLE_UPDATE_MANAGER_LOGGING";
export const debugLoggers = {
serverCompile: createDebug("typespec:server_compile"),
updateManager: createDebug("typespec:update_manager"),
compileConfig: createDebug("typespec:compile_config"),
} as const;
11 changes: 7 additions & 4 deletions packages/compiler/src/server/entrypoint-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getDirectoryPath, joinPaths } from "../core/path-utils.js";
import { SystemHost, Diagnostic as TypeSpecDiagnostic } from "../core/types.js";
import { doIO, loadFile } from "../utils/io.js";
import { resolveTspMain } from "../utils/misc.js";
import { debugLoggers } from "./constants.js";
import { FileSystemCache } from "./file-system-cache.js";
import { ServerLog } from "./types.js";

Expand All @@ -14,6 +15,8 @@ export async function resolveEntrypointFile(
log: (log: ServerLog) => void,
): Promise<string | undefined> {
const options = { allowFileNotFound: true };
const debug = debugLoggers.compileConfig;
const logDebug = debug.enabled ? log : () => {};

const pathStat = await doIO(() => host.stat(path), path, logMainFileSearchDiagnostic, options);
const isFilePath = pathStat?.isFile() ?? false;
Expand All @@ -36,22 +39,22 @@ export async function resolveEntrypointFile(

const tspMain = resolveTspMain(pkg);
if (typeof tspMain === "string") {
log({
logDebug({
level: "debug",
message: `tspMain resolved from package.json (${pkgPath}) as ${tspMain}`,
});

const packageJsonEntrypoint = await existingFile(dir, tspMain);
if (packageJsonEntrypoint) {
log({ level: "debug", message: `entrypoint file found as ${packageJsonEntrypoint}` });
logDebug({ level: "debug", message: `entrypoint file found as ${packageJsonEntrypoint}` });
return packageJsonEntrypoint;
}
}

for (const entrypoint of entrypoints) {
const candidate = await existingFile(dir, entrypoint);
if (candidate) {
log({
logDebug({
level: "debug",
message: `main file found using client provided entrypoint: ${candidate}`,
});
Expand All @@ -67,7 +70,7 @@ export async function resolveEntrypointFile(
dir = parentDir;
}

log({ level: "debug", message: `reached directory root, using '${path}' as main file` });
logDebug({ level: "debug", message: `reached directory root, using '${path}' as main file` });
return isFilePath ? path : undefined;

function logMainFileSearchDiagnostic(diagnostic: TypeSpecDiagnostic) {
Expand Down
9 changes: 3 additions & 6 deletions packages/compiler/src/server/server-compile-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import {
Program,
ServerLog,
} from "../index.js";
import { getEnvironmentVariable } from "../utils/misc.js";
import { ENABLE_SERVER_COMPILE_LOGGING } from "./constants.js";
import { debugLoggers } from "./constants.js";
import { trackActionFunc } from "./server-track-action-task.js";
import { UpdateManager } from "./update-manager.js";

Expand Down Expand Up @@ -45,10 +44,8 @@ export class ServerCompileManager {
private compilerHost: CompilerHost,
private log: (log: ServerLog) => void,
) {
this.logDebug =
getEnvironmentVariable(ENABLE_SERVER_COMPILE_LOGGING)?.toLowerCase() === "true"
? (msg) => this.log({ level: "debug", message: msg })
: () => {};
const debug = debugLoggers.serverCompile;
this.logDebug = debug.enabled ? (msg) => this.log({ level: "debug", message: msg }) : () => {};
}

async compile(
Expand Down
15 changes: 7 additions & 8 deletions packages/compiler/src/server/update-manager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { TextDocumentIdentifier } from "vscode-languageserver";
import { TextDocument } from "vscode-languageserver-textdocument";
import { getEnvironmentVariable } from "../utils/misc.js";
import { ENABLE_UPDATE_MANAGER_LOGGING } from "./constants.js";
import { debugLoggers } from "./constants.js";
import { ServerLog } from "./types.js";

interface PendingUpdate {
Expand Down Expand Up @@ -43,12 +42,12 @@ export class UpdateManager<T = void> {
log: (sl: ServerLog) => void,
getDebounceDelay?: () => number,
) {
this._log =
getEnvironmentVariable(ENABLE_UPDATE_MANAGER_LOGGING)?.toLowerCase() === "true"
? (sl: ServerLog) => {
log({ ...sl, message: `#FromUpdateManager(${this.name}): ${sl.message}` });
}
: () => {};
const debug = debugLoggers.updateManager;
this._log = debug.enabled
? (sl: ServerLog) => {
log({ ...sl, message: `#FromUpdateManager(${this.name}): ${sl.message}` });
}
: () => {};

// Set the debounce delay function once during construction
this.getDebounceDelay = getDebounceDelay ?? this.getAdaptiveDebounceDelay;
Expand Down
125 changes: 108 additions & 17 deletions packages/typespec-vscode/ThirdPartyNotices.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,27 @@ granted herein, whether by implication, estoppel or otherwise.
5. brace-expansion version 2.0.2 (https://github.com/juliangruber/brace-expansion)
6. change-case version 5.4.4 (https://github.com/blakeembrey/change-case)
7. cross-spawn version 7.0.6 (git@github.com:moxystudio/node-cross-spawn)
8. fast-deep-equal version 3.1.3 (https://github.com/epoberezkin/fast-deep-equal)
9. fast-uri version 3.1.0 (https://github.com/fastify/fast-uri)
10. is-unicode-supported version 2.1.0 (sindresorhus/is-unicode-supported)
11. isexe version 2.0.0 (https://github.com/isaacs/isexe)
12. isexe version 3.1.1 (https://github.com/isaacs/isexe)
13. js-tokens version 4.0.0 (lydell/js-tokens)
14. json-schema-traverse version 1.0.0 (https://github.com/epoberezkin/json-schema-traverse)
15. minimatch version 5.1.6 (https://github.com/isaacs/minimatch)
16. mustache version 4.2.0 (https://github.com/janl/mustache.js)
17. path-key version 3.1.1 (sindresorhus/path-key)
18. picocolors version 1.1.1 (alexeyraspopov/picocolors)
19. semver version 7.7.3 (https://github.com/npm/node-semver)
20. shebang-command version 2.0.0 (kevva/shebang-command)
21. shebang-regex version 3.0.0 (sindresorhus/shebang-regex)
22. which version 2.0.2 (https://github.com/isaacs/node-which)
23. which version 6.0.0 (https://github.com/npm/node-which)
24. yaml version 2.8.2 (github:eemeli/yaml)
8. debug version 4.4.3 (https://github.com/debug-js/debug)
9. fast-deep-equal version 3.1.3 (https://github.com/epoberezkin/fast-deep-equal)
10. fast-uri version 3.1.0 (https://github.com/fastify/fast-uri)
11. has-flag version 4.0.0 (sindresorhus/has-flag)
12. is-unicode-supported version 2.1.0 (sindresorhus/is-unicode-supported)
13. isexe version 2.0.0 (https://github.com/isaacs/isexe)
14. isexe version 3.1.1 (https://github.com/isaacs/isexe)
15. js-tokens version 4.0.0 (lydell/js-tokens)
16. json-schema-traverse version 1.0.0 (https://github.com/epoberezkin/json-schema-traverse)
17. minimatch version 5.1.6 (https://github.com/isaacs/minimatch)
18. ms version 2.1.3 (vercel/ms)
19. mustache version 4.2.0 (https://github.com/janl/mustache.js)
20. path-key version 3.1.1 (sindresorhus/path-key)
21. picocolors version 1.1.1 (alexeyraspopov/picocolors)
22. semver version 7.7.3 (https://github.com/npm/node-semver)
23. shebang-command version 2.0.0 (kevva/shebang-command)
24. shebang-regex version 3.0.0 (sindresorhus/shebang-regex)
25. supports-color version 8.1.1 (chalk/supports-color)
26. which version 2.0.2 (https://github.com/isaacs/node-which)
27. which version 6.0.0 (https://github.com/npm/node-which)
28. yaml version 2.8.2 (github:eemeli/yaml)


%% @babel/code-frame NOTICES AND INFORMATION BEGIN HERE
Expand Down Expand Up @@ -233,6 +237,33 @@ THE SOFTWARE.
END OF cross-spawn NOTICES AND INFORMATION


%% debug NOTICES AND INFORMATION BEGIN HERE
=====================================================
(The MIT License)

Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2018-2021 Josh Junon

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the 'Software'), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


=====================================================");
END OF debug NOTICES AND INFORMATION


%% fast-deep-equal NOTICES AND INFORMATION BEGIN HERE
=====================================================
MIT License
Expand Down Expand Up @@ -299,6 +330,22 @@ The complete list of contributors can be found at:
END OF fast-uri NOTICES AND INFORMATION


%% has-flag NOTICES AND INFORMATION BEGIN HERE
=====================================================
MIT License

Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

=====================================================");
END OF has-flag NOTICES AND INFORMATION


%% is-unicode-supported NOTICES AND INFORMATION BEGIN HERE
=====================================================
MIT License
Expand Down Expand Up @@ -437,6 +484,34 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
END OF minimatch NOTICES AND INFORMATION


%% ms NOTICES AND INFORMATION BEGIN HERE
=====================================================
The MIT License (MIT)

Copyright (c) 2020 Vercel, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

=====================================================");
END OF ms NOTICES AND INFORMATION


%% mustache NOTICES AND INFORMATION BEGIN HERE
=====================================================
The MIT License
Expand Down Expand Up @@ -547,6 +622,22 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
END OF shebang-regex NOTICES AND INFORMATION


%% supports-color NOTICES AND INFORMATION BEGIN HERE
=====================================================
MIT License

Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

=====================================================");
END OF supports-color NOTICES AND INFORMATION


%% which NOTICES AND INFORMATION BEGIN HERE
=====================================================
The ISC License
Expand Down
Loading