Remove all circular references in TypeSpec Compiler (#3308)
They cause vitest to not be happy randomly. This is only a problem with non type import so adding `type` helps finding which ones are a real problem Use madge with this command to find them ``` npx madge --circular --extensions ts ./src/ ``` with this config ``` { "detectiveOptions": { "ts": { "skipTypeImports": true, "skipAsyncImports": true } } } ```
This commit is contained in:
Родитель
bdb3f24bff
Коммит
8c44c3a89d
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
|
||||
changeKind: internal
|
||||
packages:
|
||||
- "@typespec/compiler"
|
||||
- "@typespec/http"
|
||||
- "@typespec/playground"
|
||||
---
|
|
@ -1,5 +1,5 @@
|
|||
import { Diagnostic, RuleRef } from "../core/index.js";
|
||||
import { YamlScript } from "../yaml/types.js";
|
||||
import type { Diagnostic, RuleRef } from "../core/index.js";
|
||||
import type { YamlScript } from "../yaml/types.js";
|
||||
|
||||
/**
|
||||
* Represent the normalized user configuration.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { mutate } from "../utils/misc.js";
|
||||
import { compilerAssert } from "./diagnostics.js";
|
||||
import { getLocationContext } from "./helpers/index.js";
|
||||
import { getLocationContext } from "./helpers/location-context.js";
|
||||
import { visitChildren } from "./parser.js";
|
||||
import { Program } from "./program.js";
|
||||
import type { Program } from "./program.js";
|
||||
import {
|
||||
AliasStatementNode,
|
||||
ConstStatementNode,
|
||||
|
|
|
@ -12,14 +12,14 @@ import {
|
|||
reportDeprecated,
|
||||
} from "./diagnostics.js";
|
||||
import { validateInheritanceDiscriminatedUnions } from "./helpers/discriminator-utils.js";
|
||||
import { getLocationContext } from "./helpers/location-context.js";
|
||||
import { explainStringTemplateNotSerializable } from "./helpers/string-template-utils.js";
|
||||
import {
|
||||
TypeNameOptions,
|
||||
getEntityName,
|
||||
getLocationContext,
|
||||
getNamespaceFullName,
|
||||
getTypeName,
|
||||
} from "./helpers/index.js";
|
||||
import { explainStringTemplateNotSerializable } from "./helpers/string-template-utils.js";
|
||||
type TypeNameOptions,
|
||||
} from "./helpers/type-name-utils.js";
|
||||
import {
|
||||
getMaxItems,
|
||||
getMaxLength,
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { getPropertyType } from "../lib/decorators.js";
|
||||
import { compilerAssert, ignoreDiagnostics } from "./diagnostics.js";
|
||||
import { getTypeName } from "./helpers/type-name-utils.js";
|
||||
import { createDiagnostic, reportDiagnostic } from "./messages.js";
|
||||
import { Program } from "./program.js";
|
||||
import type { Program } from "./program.js";
|
||||
import {
|
||||
DecoratorContext,
|
||||
DecoratorFunction,
|
||||
|
@ -516,3 +515,14 @@ export function validateDecoratorNotOnType(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the property or the model itself.
|
||||
*/
|
||||
export function getPropertyType(target: Scalar | ModelProperty): Type {
|
||||
if (target.kind === "ModelProperty") {
|
||||
return target.type;
|
||||
} else {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Program } from "./program.js";
|
||||
import type { Program } from "./program.js";
|
||||
import { BaseNode, Node, SyntaxKind, Type } from "./types.js";
|
||||
|
||||
function createStateSymbol(name: string) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { formatLog } from "./logger/index.js";
|
||||
import { formatLog } from "./logger/console-sink.js";
|
||||
import type { Program } from "./program.js";
|
||||
import { createSourceFile } from "./source-file.js";
|
||||
import {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { getDirectoryPath } from "./path-utils.js";
|
||||
import { Program } from "./program.js";
|
||||
import type { Program } from "./program.js";
|
||||
|
||||
export type NewLine = "lf" | "crlf";
|
||||
export interface EmitFileOptions {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Discriminator, getDiscriminatedTypes } from "../../lib/decorators.js";
|
||||
import { DuplicateTracker } from "../../utils/duplicate-tracker.js";
|
||||
import { isDefined } from "../../utils/misc.js";
|
||||
import { Discriminator, getDiscriminatedTypes } from "../intrinsic-type-state.js";
|
||||
import { createDiagnostic } from "../messages.js";
|
||||
import { Program } from "../program.js";
|
||||
import type { Program } from "../program.js";
|
||||
import { isTemplateDeclarationOrInstance } from "../type-utils.js";
|
||||
import { Diagnostic, Model, Type, Union } from "../types.js";
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { getSourceLocation } from "../diagnostics.js";
|
||||
import { Program } from "../program.js";
|
||||
import { DiagnosticTarget, LocationContext } from "../types.js";
|
||||
import type { Program } from "../program.js";
|
||||
import type { DiagnosticTarget, LocationContext } from "../types.js";
|
||||
|
||||
export function getLocationContext(program: Program, type: DiagnosticTarget): LocationContext {
|
||||
const sourceLocation = getSourceLocation(type);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Program, ProjectedProgram, projectProgram } from "../program.js";
|
||||
import { Projector, Type } from "../types.js";
|
||||
import type { Program, ProjectedProgram } from "../program.js";
|
||||
import { projectProgram } from "../program.js";
|
||||
import type { Projector, Type } from "../types.js";
|
||||
|
||||
export interface ProjectedNameView {
|
||||
program: ProjectedProgram;
|
||||
|
|
|
@ -7,6 +7,8 @@ export * from "./emitter-utils.js";
|
|||
export * from "./formatter.js";
|
||||
export * from "./helpers/index.js";
|
||||
export {
|
||||
getDiscriminatedTypes,
|
||||
getDiscriminator,
|
||||
getDocData,
|
||||
getMaxItems,
|
||||
getMaxItemsAsNumeric,
|
||||
|
@ -45,6 +47,7 @@ export { getPositionBeforeTrivia } from "./parser-utils.js";
|
|||
export * from "./parser.js";
|
||||
export * from "./path-utils.js";
|
||||
export * from "./program.js";
|
||||
export { isProjectedProgram } from "./projected-program.js";
|
||||
export * from "./scanner.js";
|
||||
export * from "./semantic-walker.js";
|
||||
export { createSourceFile, getSourceFileKindFromExt } from "./source-file.js";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Contains all intrinsic data setter or getter
|
||||
// Anything that the TypeSpec check might should be here.
|
||||
|
||||
import type { Type } from "./index.js";
|
||||
import type { Model, Type, Union } from "./index.js";
|
||||
import type { Numeric } from "./numeric.js";
|
||||
import type { Program } from "./program.js";
|
||||
|
||||
|
@ -22,6 +22,8 @@ const stateKeys = {
|
|||
docs: createStateSymbol("docs"),
|
||||
returnDocs: createStateSymbol("returnsDocs"),
|
||||
errorsDocs: createStateSymbol("errorDocs"),
|
||||
|
||||
discriminator: createStateSymbol("discriminator"),
|
||||
};
|
||||
|
||||
// #region @minValue
|
||||
|
@ -208,3 +210,23 @@ export function getDocData(program: Program, target: Type): DocData | undefined
|
|||
return getDocDataInternal(program, target, "self");
|
||||
}
|
||||
// #endregion doc
|
||||
|
||||
// #region discriminator
|
||||
|
||||
export interface Discriminator {
|
||||
readonly propertyName: string;
|
||||
}
|
||||
|
||||
export function setDiscriminator(program: Program, entity: Type, discriminator: Discriminator) {
|
||||
program.stateMap(stateKeys.discriminator).set(entity, discriminator);
|
||||
}
|
||||
|
||||
export function getDiscriminator(program: Program, entity: Type): Discriminator | undefined {
|
||||
return program.stateMap(stateKeys.discriminator).get(entity);
|
||||
}
|
||||
|
||||
export function getDiscriminatedTypes(program: Program): [Model | Union, Discriminator][] {
|
||||
return [...program.stateMap(stateKeys.discriminator).entries()] as any;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Checker } from "./checker.js";
|
||||
import type { Checker } from "./checker.js";
|
||||
import { compilerAssert } from "./diagnostics.js";
|
||||
import { numericRanges } from "./numeric-ranges.js";
|
||||
import { Numeric } from "./numeric.js";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { createDiagnosticCreator } from "./diagnostic-creator.js";
|
||||
import { compilerAssert } from "./diagnostics.js";
|
||||
import { Program } from "./program.js";
|
||||
import type { Program } from "./program.js";
|
||||
import { createJSONSchemaValidator } from "./schema-validator.js";
|
||||
import {
|
||||
DiagnosticMessages,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { DiagnosticCollector, compilerAssert, createDiagnosticCollector } from "./diagnostics.js";
|
||||
import { getLocationContext } from "./helpers/index.js";
|
||||
import { getLocationContext } from "./helpers/location-context.js";
|
||||
import { createDiagnostic } from "./messages.js";
|
||||
import { Program } from "./program.js";
|
||||
import type { Program } from "./program.js";
|
||||
import { EventEmitter, mapEventEmitterToNodeListener, navigateProgram } from "./semantic-walker.js";
|
||||
import {
|
||||
Diagnostic,
|
||||
|
|
|
@ -37,6 +37,7 @@ import { isImportStatement, parse, parseStandaloneTypeReference } from "./parser
|
|||
import { getDirectoryPath, joinPaths, resolvePath } from "./path-utils.js";
|
||||
import { createProjector } from "./projector.js";
|
||||
import { createSourceFile } from "./source-file.js";
|
||||
import { StateMap, StateSet, createStateAccessors } from "./state-accessors.js";
|
||||
import {
|
||||
CompilerHost,
|
||||
Diagnostic,
|
||||
|
@ -73,10 +74,12 @@ export interface ProjectedProgram extends Program {
|
|||
projector: Projector;
|
||||
}
|
||||
|
||||
export function isProjectedProgram(
|
||||
program: Program | ProjectedProgram
|
||||
): program is ProjectedProgram {
|
||||
return "projector" in program;
|
||||
export function projectProgram(
|
||||
program: Program,
|
||||
projections: ProjectionApplication[],
|
||||
startNode?: Type
|
||||
): ProjectedProgram {
|
||||
return createProjector(program, projections, startNode);
|
||||
}
|
||||
|
||||
export interface Program {
|
||||
|
@ -132,146 +135,11 @@ interface Validator {
|
|||
callback: (program: Program) => void | Promise<void>;
|
||||
}
|
||||
|
||||
class StateMap extends Map<undefined | Projector, Map<Type, unknown>> {}
|
||||
class StateSet extends Map<undefined | Projector, Set<Type>> {}
|
||||
|
||||
class StateMapView<V> implements Map<Type, V> {
|
||||
public constructor(
|
||||
private state: StateMap,
|
||||
private projector?: Projector
|
||||
) {}
|
||||
|
||||
has(t: Type) {
|
||||
return this.dispatch(t)?.has(t) ?? false;
|
||||
}
|
||||
|
||||
set(t: Type, v: any) {
|
||||
this.dispatch(t).set(t, v);
|
||||
return this;
|
||||
}
|
||||
|
||||
get(t: Type) {
|
||||
return this.dispatch(t).get(t);
|
||||
}
|
||||
|
||||
delete(t: Type) {
|
||||
return this.dispatch(t).delete(t);
|
||||
}
|
||||
|
||||
forEach(cb: (value: V, key: Type, map: Map<Type, V>) => void, thisArg?: any) {
|
||||
this.dispatch().forEach(cb, thisArg);
|
||||
return this;
|
||||
}
|
||||
|
||||
get size() {
|
||||
return this.dispatch().size;
|
||||
}
|
||||
|
||||
clear() {
|
||||
return this.dispatch().clear();
|
||||
}
|
||||
|
||||
entries() {
|
||||
return this.dispatch().entries();
|
||||
}
|
||||
|
||||
values() {
|
||||
return this.dispatch().values();
|
||||
}
|
||||
|
||||
keys() {
|
||||
return this.dispatch().keys();
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.entries();
|
||||
}
|
||||
|
||||
[Symbol.toStringTag] = "StateMap";
|
||||
|
||||
dispatch(keyType?: Type): Map<Type, V> {
|
||||
const key = keyType ? keyType.projector : this.projector;
|
||||
if (!this.state.has(key)) {
|
||||
this.state.set(key, new Map());
|
||||
}
|
||||
|
||||
return this.state.get(key)! as any;
|
||||
}
|
||||
}
|
||||
|
||||
class StateSetView implements Set<Type> {
|
||||
public constructor(
|
||||
private state: StateSet,
|
||||
private projector?: Projector
|
||||
) {}
|
||||
|
||||
has(t: Type) {
|
||||
return this.dispatch(t)?.has(t) ?? false;
|
||||
}
|
||||
|
||||
add(t: Type) {
|
||||
this.dispatch(t).add(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
delete(t: Type) {
|
||||
return this.dispatch(t).delete(t);
|
||||
}
|
||||
|
||||
forEach(cb: (value: Type, value2: Type, set: Set<Type>) => void, thisArg?: any) {
|
||||
this.dispatch().forEach(cb, thisArg);
|
||||
return this;
|
||||
}
|
||||
|
||||
get size() {
|
||||
return this.dispatch().size;
|
||||
}
|
||||
|
||||
clear() {
|
||||
return this.dispatch().clear();
|
||||
}
|
||||
|
||||
values() {
|
||||
return this.dispatch().values();
|
||||
}
|
||||
|
||||
keys() {
|
||||
return this.dispatch().keys();
|
||||
}
|
||||
|
||||
entries() {
|
||||
return this.dispatch().entries();
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.values();
|
||||
}
|
||||
|
||||
[Symbol.toStringTag] = "StateSet";
|
||||
|
||||
dispatch(keyType?: Type): Set<Type> {
|
||||
const key = keyType ? keyType.projector : this.projector;
|
||||
if (!this.state.has(key)) {
|
||||
this.state.set(key, new Set());
|
||||
}
|
||||
|
||||
return this.state.get(key)!;
|
||||
}
|
||||
}
|
||||
|
||||
interface TypeSpecLibraryReference {
|
||||
path: string;
|
||||
manifest: NodePackage;
|
||||
}
|
||||
|
||||
export function projectProgram(
|
||||
program: Program,
|
||||
projections: ProjectionApplication[],
|
||||
startNode?: Type
|
||||
): ProjectedProgram {
|
||||
return createProjector(program, projections, startNode);
|
||||
}
|
||||
|
||||
export async function compile(
|
||||
host: CompilerHost,
|
||||
mainFile: string,
|
||||
|
@ -1228,36 +1096,6 @@ export async function compile(
|
|||
}
|
||||
}
|
||||
|
||||
export function createStateAccessors(
|
||||
stateMaps: Map<symbol, StateMap>,
|
||||
stateSets: Map<symbol, StateSet>,
|
||||
projector?: Projector
|
||||
) {
|
||||
function stateMap<T>(key: symbol): StateMapView<T> {
|
||||
let m = stateMaps.get(key);
|
||||
|
||||
if (!m) {
|
||||
m = new StateMap();
|
||||
stateMaps.set(key, m);
|
||||
}
|
||||
|
||||
return new StateMapView(m, projector);
|
||||
}
|
||||
|
||||
function stateSet(key: symbol): StateSetView {
|
||||
let s = stateSets.get(key);
|
||||
|
||||
if (!s) {
|
||||
s = new StateSet();
|
||||
stateSets.set(key, s);
|
||||
}
|
||||
|
||||
return new StateSetView(s, projector);
|
||||
}
|
||||
|
||||
return { stateMap, stateSet };
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve compiler options from input options.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import type { Program, ProjectedProgram } from "./index.js";
|
||||
|
||||
export function isProjectedProgram(
|
||||
program: Program | ProjectedProgram
|
||||
): program is ProjectedProgram {
|
||||
return "projector" in program;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { camelCase, kebabCase, pascalCase, snakeCase } from "change-case";
|
||||
import { Checker } from "./checker.js";
|
||||
import type { Checker } from "./checker.js";
|
||||
import { ProjectionError, assertType } from "./diagnostics.js";
|
||||
import { ObjectType, Type, UnionVariant } from "./types.js";
|
||||
import type { ObjectType, Type, UnionVariant } from "./types.js";
|
||||
|
||||
export function createProjectionMembers(checker: Checker): {
|
||||
[TKind in Type["kind"]]?: Record<string, (base: Type & { kind: TKind }) => Type>;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { createRekeyableMap, mutate } from "../utils/misc.js";
|
||||
import { finishTypeForProgram } from "./checker.js";
|
||||
import { compilerAssert } from "./diagnostics.js";
|
||||
import { Program, ProjectedProgram, createStateAccessors, isProjectedProgram } from "./program.js";
|
||||
import type { Program, ProjectedProgram } from "./program.js";
|
||||
import { isProjectedProgram } from "./projected-program.js";
|
||||
import { createStateAccessors } from "./state-accessors.js";
|
||||
import { getParentTemplateNode, isNeverType, isTemplateInstance, isValue } from "./type-utils.js";
|
||||
import {
|
||||
import type {
|
||||
DecoratorApplication,
|
||||
DecoratorArgument,
|
||||
Enum,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Program } from "./program.js";
|
||||
import type { Program } from "./program.js";
|
||||
import { isTemplateDeclaration } from "./type-utils.js";
|
||||
import {
|
||||
Decorator,
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
import type { Projector, Type } from "./types.js";
|
||||
|
||||
export class StateMap extends Map<undefined | Projector, Map<Type, unknown>> {}
|
||||
export class StateSet extends Map<undefined | Projector, Set<Type>> {}
|
||||
|
||||
class StateMapView<V> implements Map<Type, V> {
|
||||
public constructor(
|
||||
private state: StateMap,
|
||||
private projector?: Projector
|
||||
) {}
|
||||
|
||||
has(t: Type) {
|
||||
return this.dispatch(t)?.has(t) ?? false;
|
||||
}
|
||||
|
||||
set(t: Type, v: any) {
|
||||
this.dispatch(t).set(t, v);
|
||||
return this;
|
||||
}
|
||||
|
||||
get(t: Type) {
|
||||
return this.dispatch(t).get(t);
|
||||
}
|
||||
|
||||
delete(t: Type) {
|
||||
return this.dispatch(t).delete(t);
|
||||
}
|
||||
|
||||
forEach(cb: (value: V, key: Type, map: Map<Type, V>) => void, thisArg?: any) {
|
||||
this.dispatch().forEach(cb, thisArg);
|
||||
return this;
|
||||
}
|
||||
|
||||
get size() {
|
||||
return this.dispatch().size;
|
||||
}
|
||||
|
||||
clear() {
|
||||
return this.dispatch().clear();
|
||||
}
|
||||
|
||||
entries() {
|
||||
return this.dispatch().entries();
|
||||
}
|
||||
|
||||
values() {
|
||||
return this.dispatch().values();
|
||||
}
|
||||
|
||||
keys() {
|
||||
return this.dispatch().keys();
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.entries();
|
||||
}
|
||||
|
||||
[Symbol.toStringTag] = "StateMap";
|
||||
|
||||
dispatch(keyType?: Type): Map<Type, V> {
|
||||
const key = keyType ? keyType.projector : this.projector;
|
||||
if (!this.state.has(key)) {
|
||||
this.state.set(key, new Map());
|
||||
}
|
||||
|
||||
return this.state.get(key)! as any;
|
||||
}
|
||||
}
|
||||
|
||||
class StateSetView implements Set<Type> {
|
||||
public constructor(
|
||||
private state: StateSet,
|
||||
private projector?: Projector
|
||||
) {}
|
||||
|
||||
has(t: Type) {
|
||||
return this.dispatch(t)?.has(t) ?? false;
|
||||
}
|
||||
|
||||
add(t: Type) {
|
||||
this.dispatch(t).add(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
delete(t: Type) {
|
||||
return this.dispatch(t).delete(t);
|
||||
}
|
||||
|
||||
forEach(cb: (value: Type, value2: Type, set: Set<Type>) => void, thisArg?: any) {
|
||||
this.dispatch().forEach(cb, thisArg);
|
||||
return this;
|
||||
}
|
||||
|
||||
get size() {
|
||||
return this.dispatch().size;
|
||||
}
|
||||
|
||||
clear() {
|
||||
return this.dispatch().clear();
|
||||
}
|
||||
|
||||
values() {
|
||||
return this.dispatch().values();
|
||||
}
|
||||
|
||||
keys() {
|
||||
return this.dispatch().keys();
|
||||
}
|
||||
|
||||
entries() {
|
||||
return this.dispatch().entries();
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.values();
|
||||
}
|
||||
|
||||
[Symbol.toStringTag] = "StateSet";
|
||||
|
||||
dispatch(keyType?: Type): Set<Type> {
|
||||
const key = keyType ? keyType.projector : this.projector;
|
||||
if (!this.state.has(key)) {
|
||||
this.state.set(key, new Set());
|
||||
}
|
||||
|
||||
return this.state.get(key)!;
|
||||
}
|
||||
}
|
||||
|
||||
export function createStateAccessors(
|
||||
stateMaps: Map<symbol, StateMap>,
|
||||
stateSets: Map<symbol, StateSet>,
|
||||
projector?: Projector
|
||||
) {
|
||||
function stateMap<T>(key: symbol): StateMapView<T> {
|
||||
let m = stateMaps.get(key);
|
||||
|
||||
if (!m) {
|
||||
m = new StateMap();
|
||||
stateMaps.set(key, m);
|
||||
}
|
||||
|
||||
return new StateMapView(m, projector);
|
||||
}
|
||||
|
||||
function stateSet(key: symbol): StateSetView {
|
||||
let s = stateSets.get(key);
|
||||
|
||||
if (!s) {
|
||||
s = new StateSet();
|
||||
stateSets.set(key, s);
|
||||
}
|
||||
|
||||
return new StateSetView(s, projector);
|
||||
}
|
||||
|
||||
return { stateMap, stateSet };
|
||||
}
|
|
@ -1,14 +1,8 @@
|
|||
import {
|
||||
compilerAssert,
|
||||
EmitContext,
|
||||
getTypeName,
|
||||
isTemplateDeclaration,
|
||||
joinPaths,
|
||||
Model,
|
||||
Namespace,
|
||||
Program,
|
||||
Type,
|
||||
} from "../core/index.js";
|
||||
import { compilerAssert } from "../core/diagnostics.js";
|
||||
import { getTypeName } from "../core/helpers/type-name-utils.js";
|
||||
import type { EmitContext, Model, Namespace, Program, Type } from "../core/index.js";
|
||||
import { joinPaths } from "../core/path-utils.js";
|
||||
import { isTemplateDeclaration } from "../core/type-utils.js";
|
||||
import { CustomKeyMap } from "./custom-key-map.js";
|
||||
import { Placeholder } from "./placeholder.js";
|
||||
import { resolveDeclarationReferenceScope } from "./ref-scope.js";
|
||||
|
@ -20,9 +14,9 @@ import {
|
|||
ContextState,
|
||||
Declaration,
|
||||
EmitEntity,
|
||||
EmitTypeReferenceOptions,
|
||||
EmitterResult,
|
||||
EmitterState,
|
||||
EmitTypeReferenceOptions,
|
||||
LexicalTypeStackEntry,
|
||||
NamespaceScope,
|
||||
NoEmit,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Declaration, Scope } from "./types.js";
|
||||
import type { Declaration, Scope } from "./types.js";
|
||||
|
||||
export function scopeChain<T>(scope: Scope<T> | null) {
|
||||
const chain = [];
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Type, getTypeName } from "../core/index.js";
|
||||
import { EmitEntity } from "./types.js";
|
||||
import { getTypeName } from "../core/helpers/type-name-utils.js";
|
||||
import type { Type } from "../core/index.js";
|
||||
import type { EmitEntity } from "./types.js";
|
||||
|
||||
export interface ReferenceCycleEntry {
|
||||
type: Type;
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import {
|
||||
import { compilerAssert } from "../core/diagnostics.js";
|
||||
import { emitFile } from "../core/emitter-utils.js";
|
||||
import type { Program } from "../core/program.js";
|
||||
import { isTemplateDeclaration } from "../core/type-utils.js";
|
||||
import type {
|
||||
BooleanLiteral,
|
||||
compilerAssert,
|
||||
emitFile,
|
||||
Enum,
|
||||
EnumMember,
|
||||
Interface,
|
||||
IntrinsicType,
|
||||
isTemplateDeclaration,
|
||||
Model,
|
||||
ModelProperty,
|
||||
Namespace,
|
||||
NumericLiteral,
|
||||
Operation,
|
||||
Program,
|
||||
Scalar,
|
||||
StringLiteral,
|
||||
StringTemplate,
|
||||
|
@ -20,8 +20,8 @@ import {
|
|||
Type,
|
||||
Union,
|
||||
UnionVariant,
|
||||
} from "../core/index.js";
|
||||
import { code, StringBuilder } from "./builders/string-builder.js";
|
||||
} from "../core/types.js";
|
||||
import { StringBuilder, code } from "./builders/string-builder.js";
|
||||
import { Placeholder } from "./placeholder.js";
|
||||
import { resolveDeclarationReferenceScope } from "./ref-scope.js";
|
||||
import { ReferenceCycle } from "./reference-cycle.js";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {
|
||||
import type {
|
||||
Enum,
|
||||
Interface,
|
||||
IntrinsicType,
|
||||
|
@ -12,7 +12,7 @@ import {
|
|||
Union,
|
||||
} from "../core/index.js";
|
||||
import { Placeholder } from "./placeholder.js";
|
||||
import { TypeEmitter } from "./type-emitter.js";
|
||||
import type { TypeEmitter } from "./type-emitter.js";
|
||||
|
||||
type AssetEmitterOptions<TOptions extends object> = {
|
||||
noEmit: boolean;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { camelCase, kebabCase, pascalCase } from "change-case";
|
||||
import Mustache from "mustache";
|
||||
import { InitTemplate } from "./init-template.js";
|
||||
import { ScaffoldingConfig } from "./scaffold.js";
|
||||
import type { InitTemplate } from "./init-template.js";
|
||||
import type { ScaffoldingConfig } from "./scaffold.js";
|
||||
|
||||
export type FileTemplatingContext = Omit<InitTemplate, "libraries"> &
|
||||
ScaffoldingConfig & {
|
||||
|
|
|
@ -37,6 +37,7 @@ import type {
|
|||
WithoutOmittedPropertiesDecorator,
|
||||
} from "../../generated-defs/TypeSpec.js";
|
||||
import {
|
||||
getPropertyType,
|
||||
isIntrinsicType,
|
||||
validateDecoratorNotOnType,
|
||||
validateDecoratorTarget,
|
||||
|
@ -53,6 +54,7 @@ import {
|
|||
validateDecoratorUniqueOnNode,
|
||||
} from "../core/index.js";
|
||||
import {
|
||||
Discriminator,
|
||||
DocData,
|
||||
getDocDataInternal,
|
||||
getMaxItemsAsNumeric,
|
||||
|
@ -63,6 +65,7 @@ import {
|
|||
getMinLengthAsNumeric,
|
||||
getMinValueAsNumeric,
|
||||
getMinValueExclusiveAsNumeric,
|
||||
setDiscriminator,
|
||||
setDocData,
|
||||
setMaxItems,
|
||||
setMaxLength,
|
||||
|
@ -310,17 +313,6 @@ function validateTargetingAString(
|
|||
return valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the property or the model itself.
|
||||
*/
|
||||
export function getPropertyType(target: Scalar | ModelProperty): Type {
|
||||
if (target.kind === "ModelProperty") {
|
||||
return target.type;
|
||||
} else {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
// -- @error decorator ----------------------
|
||||
|
||||
const errorKey = createStateSymbol("error");
|
||||
|
@ -1343,12 +1335,6 @@ function validateRange(
|
|||
return true;
|
||||
}
|
||||
|
||||
export interface Discriminator {
|
||||
propertyName: string;
|
||||
}
|
||||
|
||||
const discriminatorKey = createStateSymbol("discriminator");
|
||||
|
||||
export const $discriminator: DiscriminatorDecorator = (
|
||||
context: DecoratorContext,
|
||||
entity: Model | Union,
|
||||
|
@ -1364,17 +1350,9 @@ export const $discriminator: DiscriminatorDecorator = (
|
|||
return;
|
||||
}
|
||||
}
|
||||
context.program.stateMap(discriminatorKey).set(entity, discriminator);
|
||||
setDiscriminator(context.program, entity, discriminator);
|
||||
};
|
||||
|
||||
export function getDiscriminator(program: Program, entity: Type): Discriminator | undefined {
|
||||
return program.stateMap(discriminatorKey).get(entity);
|
||||
}
|
||||
|
||||
export function getDiscriminatedTypes(program: Program): [Model | Union, Discriminator][] {
|
||||
return [...program.stateMap(discriminatorKey).entries()] as any;
|
||||
}
|
||||
|
||||
const parameterVisibilityKey = createStateSymbol("parameterVisibility");
|
||||
|
||||
export const $parameterVisibility: ParameterVisibilityDecorator = (
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { reportDiagnostic } from "../core/messages.js";
|
||||
import { parseMimeType } from "../core/mime-type.js";
|
||||
import { Program } from "../core/program.js";
|
||||
import { DecoratorContext, Enum, Model, Type, Union } from "../core/types.js";
|
||||
import type { Program } from "../core/program.js";
|
||||
import type { DecoratorContext, Enum, Model, Type, Union } from "../core/types.js";
|
||||
import { DuplicateTracker } from "../utils/index.js";
|
||||
|
||||
function createStateSymbol(name: string) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { ServiceDecorator } from "../../generated-defs/TypeSpec.js";
|
|||
import { validateDecoratorUniqueOnNode } from "../core/decorator-utils.js";
|
||||
import { Type, getTypeName, reportDeprecated } from "../core/index.js";
|
||||
import { reportDiagnostic } from "../core/messages.js";
|
||||
import { Program } from "../core/program.js";
|
||||
import type { Program } from "../core/program.js";
|
||||
import { DecoratorContext, Namespace } from "../core/types.js";
|
||||
|
||||
export interface ServiceDetails {
|
||||
|
|
|
@ -54,7 +54,7 @@ import { ResolveModuleHost, resolveModule } from "../core/index.js";
|
|||
import { getPositionBeforeTrivia } from "../core/parser-utils.js";
|
||||
import { getNodeAtPosition, visitChildren } from "../core/parser.js";
|
||||
import { ensureTrailingDirectorySeparator, getDirectoryPath } from "../core/path-utils.js";
|
||||
import { Program } from "../core/program.js";
|
||||
import type { Program } from "../core/program.js";
|
||||
import { skipTrivia, skipWhiteSpace } from "../core/scanner.js";
|
||||
import { createSourceFile, getSourceFileKindFromExt } from "../core/source-file.js";
|
||||
import {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { compilerAssert } from "../core/diagnostics.js";
|
||||
import { getEntityName, getTypeName, isStdNamespace } from "../core/helpers/type-name-utils.js";
|
||||
import { Program } from "../core/program.js";
|
||||
import type { Program } from "../core/program.js";
|
||||
import { getFullyQualifiedSymbolName } from "../core/type-utils.js";
|
||||
import {
|
||||
AliasStatementNode,
|
||||
|
|
|
@ -37,7 +37,7 @@ import {
|
|||
WorkspaceFoldersChangeEvent,
|
||||
} from "vscode-languageserver";
|
||||
import { TextDocument, TextEdit } from "vscode-languageserver-textdocument";
|
||||
import { CompilerHost, Program, SourceFile, TypeSpecScriptNode } from "../index.js";
|
||||
import type { CompilerHost, Program, SourceFile, TypeSpecScriptNode } from "../core/index.js";
|
||||
|
||||
export interface ServerHost {
|
||||
readonly compilerHost: CompilerHost;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { fail, match, strictEqual } from "assert";
|
||||
import { Diagnostic, NoTarget, Type, formatDiagnostic, getSourceLocation } from "../core/index.js";
|
||||
import { isArray } from "../utils/misc.js";
|
||||
import { resolveVirtualPath } from "./test-host.js";
|
||||
import { resolveVirtualPath } from "./test-utils.js";
|
||||
|
||||
/**
|
||||
* Assert there is no diagnostics.
|
||||
|
|
|
@ -10,8 +10,7 @@ import {
|
|||
} from "../core/index.js";
|
||||
import { createLinterRuleContext } from "../core/linter.js";
|
||||
import { DiagnosticMatch, expectDiagnosticEmpty, expectDiagnostics } from "./expect.js";
|
||||
import { resolveVirtualPath } from "./test-host.js";
|
||||
import { trimBlankLines } from "./test-utils.js";
|
||||
import { resolveVirtualPath, trimBlankLines } from "./test-utils.js";
|
||||
import { BasicTestRunner } from "./types.js";
|
||||
|
||||
export interface LinterRuleTester {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import assert from "assert";
|
||||
import { RmOptions } from "fs";
|
||||
import type { RmOptions } from "fs";
|
||||
import { readFile } from "fs/promises";
|
||||
import { globby } from "globby";
|
||||
import { fileURLToPath, pathToFileURL } from "url";
|
||||
|
@ -9,11 +9,11 @@ import { NodeHost } from "../core/node-host.js";
|
|||
import { CompilerOptions } from "../core/options.js";
|
||||
import { getAnyExtensionFromPath, resolvePath } from "../core/path-utils.js";
|
||||
import { Program, compile as compileProgram } from "../core/program.js";
|
||||
import { CompilerHost, Diagnostic, StringLiteral, Type } from "../core/types.js";
|
||||
import type { CompilerHost, Diagnostic, StringLiteral, Type } from "../core/types.js";
|
||||
import { createSourceFile, getSourceFileKindFromExt } from "../index.js";
|
||||
import { createStringMap } from "../utils/misc.js";
|
||||
import { expectDiagnosticEmpty } from "./expect.js";
|
||||
import { createTestWrapper, findTestPackageRoot } from "./test-utils.js";
|
||||
import { createTestWrapper, findTestPackageRoot, resolveVirtualPath } from "./test-utils.js";
|
||||
import {
|
||||
BasicTestRunner,
|
||||
TestFileSystem,
|
||||
|
@ -29,14 +29,6 @@ export interface TestHostOptions {
|
|||
compilerHostOverrides?: Partial<CompilerHost>;
|
||||
}
|
||||
|
||||
export function resolveVirtualPath(path: string, ...paths: string[]) {
|
||||
// NB: We should always resolve an absolute path, and there is no absolute
|
||||
// path that works across OSes. This ensures that we can still rely on API
|
||||
// like pathToFileURL in tests.
|
||||
const rootDir = process.platform === "win32" ? "Z:/test" : "/test";
|
||||
return resolvePath(rootDir, path, ...paths);
|
||||
}
|
||||
|
||||
function createTestCompilerHost(
|
||||
virtualFs: Map<string, string>,
|
||||
jsImports: Map<string, Record<string, any>>,
|
||||
|
|
|
@ -6,12 +6,8 @@ import { parse, visitChildren } from "../core/parser.js";
|
|||
import { IdentifierNode, SyntaxKind } from "../core/types.js";
|
||||
import { Server, ServerHost, createServer } from "../server/index.js";
|
||||
import { createStringMap } from "../utils/misc.js";
|
||||
import {
|
||||
StandardTestLibrary,
|
||||
TestHostOptions,
|
||||
createTestFileSystem,
|
||||
resolveVirtualPath,
|
||||
} from "./test-host.js";
|
||||
import { StandardTestLibrary, TestHostOptions, createTestFileSystem } from "./test-host.js";
|
||||
import { resolveVirtualPath } from "./test-utils.js";
|
||||
import { TestFileSystem } from "./types.js";
|
||||
|
||||
export interface TestServerHost extends ServerHost, TestFileSystem {
|
||||
|
|
|
@ -9,6 +9,14 @@ import {
|
|||
TypeSpecTestLibraryInit,
|
||||
} from "./types.js";
|
||||
|
||||
export function resolveVirtualPath(path: string, ...paths: string[]) {
|
||||
// NB: We should always resolve an absolute path, and there is no absolute
|
||||
// path that works across OSes. This ensures that we can still rely on API
|
||||
// like pathToFileURL in tests.
|
||||
const rootDir = process.platform === "win32" ? "Z:/test" : "/test";
|
||||
return resolvePath(rootDir, path, ...paths);
|
||||
}
|
||||
|
||||
/** Find the package root from the provided file */
|
||||
export function findTestPackageRoot(fileUrl: string): Promise<string> {
|
||||
return findProjectRoot(NodeHost.stat, fileURLToPath(fileUrl)) as Promise<string>;
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Binder, createBinder } from "../src/core/binder.js";
|
|||
import { createLogger } from "../src/core/logger/logger.js";
|
||||
import { createTracer } from "../src/core/logger/tracer.js";
|
||||
import { parse } from "../src/core/parser.js";
|
||||
import { Program } from "../src/core/program.js";
|
||||
import type { Program } from "../src/core/program.js";
|
||||
import { createSourceFile } from "../src/core/source-file.js";
|
||||
import {
|
||||
AliasStatementNode,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { deepStrictEqual, ok, strictEqual } from "assert";
|
||||
import { beforeEach, describe, it } from "vitest";
|
||||
import { Program } from "../../src/core/program.js";
|
||||
import type { Program } from "../../src/core/program.js";
|
||||
import { DecoratorContext, Type } from "../../src/core/types.js";
|
||||
import { TestHost, createTestHost } from "../../src/testing/index.js";
|
||||
import { createRekeyableMap } from "../../src/utils/misc.js";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { ok, strictEqual } from "assert";
|
||||
import { beforeEach, describe, it } from "vitest";
|
||||
import { getTypeName } from "../../src/core/index.js";
|
||||
import { Program } from "../../src/core/program.js";
|
||||
import type { Program } from "../../src/core/program.js";
|
||||
import { Model, Namespace, Type } from "../../src/core/types.js";
|
||||
import {
|
||||
TestHost,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { deepStrictEqual, fail, ok, strictEqual } from "assert";
|
||||
import { beforeEach, describe, it } from "vitest";
|
||||
import { Program, projectProgram } from "../../src/core/program.js";
|
||||
import type { Program } from "../../src/core/program.js";
|
||||
import { createProjector } from "../../src/core/projector.js";
|
||||
import {
|
||||
import type {
|
||||
DecoratorArgumentValue,
|
||||
DecoratorContext,
|
||||
Enum,
|
||||
|
@ -17,6 +17,7 @@ import {
|
|||
Type,
|
||||
Union,
|
||||
} from "../../src/core/types.js";
|
||||
import { projectProgram } from "../../src/index.js";
|
||||
import { getDoc } from "../../src/lib/decorators.js";
|
||||
import { TestHost, createTestHost } from "../../src/testing/index.js";
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Program } from "@typespec/compiler";
|
||||
import type { Program } from "@typespec/compiler";
|
||||
import { reportDiagnostic } from "./lib.js";
|
||||
import { getAllHttpServices } from "./operations.js";
|
||||
import { isSharedRoute } from "./route.js";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { tokens } from "@fluentui/react-components";
|
||||
import { Program } from "@typespec/compiler";
|
||||
import type { Program } from "@typespec/compiler";
|
||||
import { ColorPalette, ColorProvider, TypeSpecProgramViewer } from "@typespec/html-program-viewer";
|
||||
import { FunctionComponent, useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { FileOutput } from "../file-output/file-output.js";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Program } from "@typespec/compiler";
|
||||
import type { Program } from "@typespec/compiler";
|
||||
import { ReactElement } from "react";
|
||||
|
||||
export type CompilationCrashed = {
|
||||
|
|
Загрузка…
Ссылка в новой задаче