UNPKG

@typespec/http-server-js

Version:

TypeSpec HTTP server code generator for JavaScript

111 lines 4.51 kB
import { NoTarget } from "@typespec/compiler"; import { reportDiagnostic } from "../lib.js"; import { UnreachableError } from "./error.js"; const DEFAULT_DECLARATION_OPTIONS = { source: NoTarget, resolutionStrategy: "shadow", }; const NO_PARENT = { declare() { throw new UnreachableError("Cannot declare in the no-parent scope"); }, isDeclared() { return false; }, }; /** * Create a new scope. * * @param ctx - the JS emitter context. * @param parent - an optional parent scope for this scope. It will consider declarations in the parent scope for some conflicts. */ export function createScope(ctx, parent = NO_PARENT) { const ownDeclarations = new Set(); const self = { declare(primaryName, options = {}) { const { source: target, resolutionStrategy } = { ...DEFAULT_DECLARATION_OPTIONS, ...options }; if (!self.isDeclared(primaryName)) { ownDeclarations.add(primaryName); return primaryName; } // Apply resolution strategy const resolutionStrategyName = typeof resolutionStrategy === "string" ? resolutionStrategy : resolutionStrategy.kind; switch (resolutionStrategyName) { case "none": // Report diagnostic and return the name as is. reportDiagnostic(ctx.program, { code: "name-conflict", format: { name: primaryName, }, target, }); return primaryName; case "shadow": // Check to make sure this name isn't an own-declaration, and if not allow it, otherwise raise a diagnostic. if (!ownDeclarations.has(primaryName)) { ownDeclarations.add(primaryName); return primaryName; } else { reportDiagnostic(ctx.program, { code: "name-conflict", format: { name: primaryName, }, target, }); return primaryName; } case "prefix": { const { prefix = "_", repeated = false, shadow = true, } = resolutionStrategy; let name = primaryName; const isDeclared = shadow ? (name) => ownDeclarations.has(name) : self.isDeclared; while (isDeclared(name)) { name = prefix + name; if (!repeated) break; } if (isDeclared(name)) { // We were not able to resolve the conflict with this strategy, so raise a diagnostic. reportDiagnostic(ctx.program, { code: "name-conflict", format: { name: name, }, target, }); return name; } ownDeclarations.add(name); return name; } case "alt-name": { const { altName } = resolutionStrategy; if (!self.isDeclared(altName)) { ownDeclarations.add(altName); return altName; } // We were not able to resolve the conflict with this strategy, so raise a diagnostic. reportDiagnostic(ctx.program, { code: "name-conflict", format: { name: altName, }, target, }); return altName; } default: throw new UnreachableError(`Unknown resolution strategy: ${resolutionStrategy}`, { resolutionStrategyName, }); } }, isDeclared(name) { return ownDeclarations.has(name) || parent.isDeclared(name); }, }; return self; } //# sourceMappingURL=scope.js.map