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
3 changes: 2 additions & 1 deletion packages/rlc-common/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
}
],
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error"
"@typescript-eslint/no-misused-promises": "error",
"no-console": "error"
}
}
3 changes: 2 additions & 1 deletion packages/typespec-ts/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
],
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/no-deprecated": "warn"
"@typescript-eslint/no-deprecated": "warn",
"no-console": "error"
}
}
16 changes: 14 additions & 2 deletions packages/typespec-ts/src/framework/load-static-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { refkey } from "./refkey.js";
import { resolveProjectRoot } from "../utils/resolve-project-root.js";
import { isAzurePackage } from "@azure-tools/rlc-common";
import { ModularEmitterOptions } from "../modular/interfaces.js";
import { NoTarget, Program } from "@typespec/compiler";
import { reportDiagnostic } from "../lib.js";
export const SourceFileSymbol = Symbol("SourceFile");
export interface StaticHelperMetadata {
name: string;
Expand Down Expand Up @@ -41,6 +43,7 @@ export interface LoadStaticHelpersOptions
extends Partial<ModularEmitterOptions> {
helpersAssetDirectory?: string;
sourcesDir?: string;
program?: Program;
}

export async function loadStaticHelpers(
Expand All @@ -55,7 +58,8 @@ export async function loadStaticHelpers(
DEFAULT_STATIC_HELPERS_PATH
);
const files = await traverseDirectory(
options.helpersAssetDirectory ?? defaultStaticHelpersPath
options.helpersAssetDirectory ?? defaultStaticHelpersPath,
options.program
);

for (const file of files) {
Expand Down Expand Up @@ -161,6 +165,7 @@ function getDeclarationByMetadata(
const _targetStaticHelpersBaseDir = "static-helpers";
async function traverseDirectory(
directory: string,
program?: Program,
result: { source: string; target: string }[] = [],
relativePath: string = ""
): Promise<{ source: string; target: string }[]> {
Expand All @@ -175,6 +180,7 @@ async function traverseDirectory(
if (fileStat.isDirectory()) {
await traverseDirectory(
filePath,
program,
result,
path.join(relativePath, file)
);
Expand All @@ -195,7 +201,13 @@ async function traverseDirectory(

return result;
} catch (error) {
console.error(`Error traversing directory ${directory}:`, error);
if (program) {
reportDiagnostic(program, {
code: "directory-traversal-error",
format: { directory, error: String(error) },
target: NoTarget
});
}
throw error;
}
}
6 changes: 0 additions & 6 deletions packages/typespec-ts/src/framework/sample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,6 @@ sourceFile2.addStatements(`let obj: ${modelReference} = { id: 1 };`);
// Apply imports to ensure correct references
binder.resolveAllReferences("/modularPackageFolder/src");

// Output the generated files
console.log("// test.ts");
console.log(sourceFile.getFullText());
console.log("// test2.ts");
console.log(sourceFile2.getFullText());

// Output
// test.ts
// interface MyInterface {
Expand Down
26 changes: 2 additions & 24 deletions packages/typespec-ts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,14 @@ import { generateCrossLanguageDefinitionFile } from "./utils/crossLanguageDef.js
export * from "./lib.js";

export async function $onEmit(context: EmitContext) {
console.time("onEmit");
if (context.program.compilerOptions.noEmit || context.program.hasError()) {
return;
}
/** Shared status */
const outputProject = new Project();
const program: Program = context.program;
const emitterOptions: EmitterOptions = context.options;
console.time("onEmit: create context");
const dpgContext = await createContextWithDefaultOptions(context);
console.timeEnd("onEmit: create context");
// Enrich the dpg context with path detail and common options
await enrichDpgContext();
const rlcOptions = dpgContext.rlcOptions ?? {};
Expand All @@ -126,7 +123,6 @@ export async function $onEmit(context: EmitContext) {
compilerContext: context,
tcgcContext: dpgContext
});
console.time("onEmit: load static helpers");
const staticHelpers = await loadStaticHelpers(
outputProject,
{
Expand All @@ -139,36 +135,32 @@ export async function $onEmit(context: EmitContext) {
},
{
sourcesDir: dpgContext.generationPathDetail?.modularSourcesDir,
options: rlcOptions
options: rlcOptions,
program
}
);
console.timeEnd("onEmit: load static helpers");
const extraDependencies = isAzurePackage({ options: rlcOptions })
? {
...AzurePollingDependencies,
...AzureCoreDependencies,
...AzureIdentityDependencies
}
: { ...DefaultCoreDependencies };
console.time("onEmit: provide binder");
const binder = provideBinder(outputProject, {
staticHelpers,
dependencies: {
...extraDependencies
}
});
provideSdkTypes(dpgContext);
console.timeEnd("onEmit: provide binder");

const rlcCodeModels: RLCModel[] = [];
let modularEmitterOptions: ModularEmitterOptions;
// 1. Clear sources folder
await clearSrcFolder();
// 2. Generate RLC code model
// TODO: skip this step in modular once modular generator is sufficiently decoupled
console.time("onEmit: build RLC code models");
await buildRLCCodeModels();
console.timeEnd("onEmit: build RLC code models");

// 4. Generate sources
if (emitterOptions["is-modular-library"]) {
Expand Down Expand Up @@ -275,7 +267,6 @@ export async function $onEmit(context: EmitContext) {
}

async function generateModularSources() {
console.time("onEmit: generate modular sources");
const modularSourcesRoot =
dpgContext.generationPathDetail?.modularSourcesDir ?? "src";
const project = useContext("outputProject");
Expand All @@ -298,13 +289,10 @@ export async function $onEmit(context: EmitContext) {
);

const isMultiClients = dpgContext.sdkPackage.clients.length > 1;
console.time("onEmit: emit models");
emitTypes(dpgContext, { sourceRoot: modularSourcesRoot });
console.timeEnd("onEmit: emit models");
buildSubpathIndexFile(modularEmitterOptions, "models", undefined, {
recursive: true
});
console.time("onEmit: emit source files");
const clientMap = getClientHierarchyMap(dpgContext);
if (clientMap.length === 0) {
// If no clients, we still need to build the root index file
Expand Down Expand Up @@ -344,27 +332,20 @@ export async function $onEmit(context: EmitContext) {
subClient
);
}
console.timeEnd("onEmit: emit source files");
// Enable modular sample generation when explicitly set to true or MPG
if (emitterOptions["generate-sample"] === true) {
console.time("onEmit: emit samples");
const samples = emitSamples(dpgContext);
console.timeEnd("onEmit: emit samples");
// Refine the rlc sample generation logic
// TODO: remember to remove this out when RLC is splitted from Modular
if (samples.length > 0) {
dpgContext.rlcOptions!.generateSample = true;
}
}

console.time("onEmit: resolve references");
binder.resolveAllReferences(modularSourcesRoot);
if (program.compilerOptions.noEmit || program.hasError()) {
return;
}
console.timeEnd("onEmit: resolve references");

console.time("onEmit: generate files");

for (const file of project.getSourceFiles()) {
await emitContentByBuilder(
Expand All @@ -373,8 +354,6 @@ export async function $onEmit(context: EmitContext) {
modularEmitterOptions as any
);
}
console.timeEnd("onEmit: generate files");
console.timeEnd("onEmit: generate modular sources");
}

interface Metadata {
Expand Down Expand Up @@ -558,7 +537,6 @@ export async function $onEmit(context: EmitContext) {
.map((subClient) => getClientContextPath(subClient, options))
.map((path) => path.substring(path.indexOf("src")));
}
console.timeEnd("onEmit");
}

export async function createContextWithDefaultOptions(
Expand Down
6 changes: 6 additions & 0 deletions packages/typespec-ts/src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,12 @@ const libDef = {
messages: {
default: paramMessage`Failed to format file: ${"filePath"}. Error: ${"error"}.`
}
},
"directory-traversal-error": {
severity: "error",
messages: {
default: paramMessage`Error traversing directory ${"directory"}: ${"error"}`
}
}
},
emitter: {
Expand Down
4 changes: 1 addition & 3 deletions packages/typespec-ts/src/modular/buildClientContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,7 @@ export function buildClientContext(
}`;
} else {
apiVersionPolicyStatement += `
if (options.apiVersion) {
console.warn("This client does not support client api-version, please change it at the operation level");
}`;
// This client does not support client api-version, please change it at the operation level`;
}
factoryFunction.addStatements(apiVersionPolicyStatement);

Expand Down
1 change: 0 additions & 1 deletion packages/typespec-ts/src/utils/emitUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ async function emitFile(
target: NoTarget
});
// Continue with unformatted content rather than crashing
console.error(`Failed to format file: ${filePath}`, e);
}
}
await host.mkdirp(dirname(filePath));
Expand Down
Loading