microsoft/typespec

Public

mirrored from https://github.com/microsoft/typespecAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/fix-1919

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

packages/asset-emitter/src/types.ts

199lines · modecode

1import type {
2 Enum,
3 Interface,
4 IntrinsicType,
5 Model,
6 ModelProperty,
7 Operation,
8 Program,
9 Scalar,
10 Tuple,
11 Type,
12 Union,
13} from "@typespec/compiler";
14import { Placeholder } from "./placeholder.js";
15import type { TypeEmitter } from "./type-emitter.js";
16
17type AssetEmitterOptions<TOptions extends object> = {
18 noEmit: boolean;
19 emitterOutputDir: string;
20} & TOptions;
21
22export interface EmitTypeReferenceOptions {
23 readonly referenceContext?: Record<string, any>;
24}
25
26export interface AssetEmitter<T, TOptions extends object = Record<string, unknown>> {
27 /**
28 * Get the current emitter context as set by the TypeEmitter's various
29 * context methods.
30 *
31 * @returns The current emitter context
32 */
33 getContext(): Context;
34 getOptions(): AssetEmitterOptions<TOptions>;
35 getProgram(): Program;
36 emitTypeReference(type: Type, context?: EmitTypeReferenceOptions): EmitEntity<T>;
37 emitDeclarationName(type: TypeSpecDeclaration): string | undefined;
38 emitType(type: Type, context?: Partial<ContextState>): EmitEntity<T>;
39 emitProgram(options?: { emitGlobalNamespace?: boolean; emitTypeSpecNamespace?: boolean }): void;
40 emitModelProperties(model: Model): EmitEntity<T>;
41 emitModelProperty(prop: ModelProperty): EmitEntity<T>;
42 emitOperationParameters(operation: Operation): EmitEntity<T>;
43 emitOperationReturnType(operation: Operation): EmitEntity<T>;
44 emitInterfaceOperations(iface: Interface): EmitEntity<T>;
45 emitInterfaceOperation(operation: Operation): EmitEntity<T>;
46 emitEnumMembers(en: Enum): EmitEntity<T>;
47 emitUnionVariants(union: Union): EmitEntity<T>;
48 emitTupleLiteralValues(tuple: Tuple): EmitEntity<T>;
49 emitSourceFile(sourceFile: SourceFile<T>): Promise<EmittedSourceFile>;
50 /**
51 * Create a source file.
52 *
53 * @param name the path of the file, resolved relative to the emitter's output directory.
54 */
55 createSourceFile(name: string): SourceFile<T>;
56 createScope(sourceFile: SourceFile<T>, name: string): SourceFileScope<T>;
57 createScope(namespace: any, name: string, parentScope: Scope<T>): NamespaceScope<T>;
58 createScope(block: any, name: string, parentScope?: Scope<T> | null): Scope<T>;
59 result: {
60 declaration(name: string, value: T | Placeholder<T>): Declaration<T>;
61 rawCode(value: T | Placeholder<T>): RawCode<T>;
62 none(): NoEmit;
63 };
64 writeOutput(): Promise<void>;
65
66 /** Get source files that have been scoped. */
67 getSourceFiles(): SourceFile<T>[];
68}
69
70export interface ScopeBase<T> {
71 kind: string;
72 name: string;
73 parentScope: Scope<T> | null;
74 childScopes: Scope<T>[];
75 declarations: Declaration<T>[];
76}
77
78export interface SourceFileScope<T> extends ScopeBase<T> {
79 kind: "sourceFile";
80 sourceFile: SourceFile<T>;
81}
82
83export interface NamespaceScope<T> extends ScopeBase<T> {
84 kind: "namespace";
85 parentScope: Scope<T>;
86 namespace: any;
87}
88
89export type Scope<T> = SourceFileScope<T> | NamespaceScope<T>;
90
91export interface TypeReference {
92 expression: string;
93}
94
95export interface SourceFile<T> {
96 path: string;
97 globalScope: Scope<T>;
98 imports: Map<string, string[]>;
99 meta: Record<string, any>;
100}
101
102export interface EmittedSourceFile {
103 contents: string;
104 path: string;
105}
106
107export type EmitEntity<T> = Declaration<T> | RawCode<T> | NoEmit | CircularEmit;
108
109export class EmitterResult {}
110export class Declaration<T> extends EmitterResult {
111 public kind = "declaration" as const;
112 public meta: Record<string, any> = {};
113
114 constructor(
115 public name: string,
116 public scope: Scope<T>,
117 public value: T | Placeholder<T>,
118 ) {
119 if (value instanceof Placeholder) {
120 value.onValue((v) => (this.value = v));
121 }
122
123 super();
124 }
125}
126
127export class RawCode<T> extends EmitterResult {
128 public kind = "code" as const;
129
130 constructor(public value: T | Placeholder<T>) {
131 if (value instanceof Placeholder) {
132 value.onValue((v) => (this.value = v));
133 }
134
135 super();
136 }
137}
138
139export class NoEmit extends EmitterResult {
140 public kind = "none" as const;
141}
142
143export class CircularEmit extends EmitterResult {
144 public kind = "circular" as const;
145 constructor(public emitEntityKey: [string, Type, ContextState]) {
146 super();
147 }
148}
149
150export interface AssetTag {
151 language: AssetTagFactory;
152 create(key: string): AssetTagFactory;
153}
154
155export interface AssetTagInstance {}
156
157export type AssetTagFactory = {
158 (value: string): AssetTagInstance;
159};
160
161export type TypeSpecDeclaration =
162 | Model
163 | Interface
164 | Union
165 | Operation
166 | Enum
167 | Scalar
168 | IntrinsicType;
169
170export interface ContextState {
171 lexicalContext: Record<string, any>;
172 referenceContext: Record<string, any>;
173}
174
175export type Context = Record<string, any>;
176export type ESRecord = Record<string, any> & { _record: true };
177
178type EndingWith<Names, Name extends string> = Names extends `${infer _X}${Name}` ? Names : never;
179
180export type TypeEmitterMethod = keyof Omit<
181 TypeEmitter<any, any>,
182 | "sourceFile"
183 | "declarationName"
184 | "reference"
185 | "circularReference"
186 | "emitValue"
187 | "writeOutput"
188 | EndingWith<keyof TypeEmitter<any, any>, "Context">
189>;
190
191export interface LexicalTypeStackEntry {
192 method: TypeEmitterMethod;
193 args: any[];
194}
195
196export interface EmitterState {
197 lexicalTypeStack: LexicalTypeStackEntry[];
198 context: ContextState;
199}
200