-
Notifications
You must be signed in to change notification settings - Fork 512
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Referencer, Name conflicts, Mapped unions, etc. #1498
Changes from all commits
106aca2
4a00474
7874601
096fa70
9ff1e36
ded85e4
f869ed0
9a5ceb8
bb53e2e
160ed28
9b6bb40
c1eea73
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,19 @@ | ||
import { Config, Tsoa } from '@tsoa/runtime'; | ||
import { minimatch } from 'minimatch'; | ||
import { createProgram, forEachChild, isClassDeclaration, type ClassDeclaration, type CompilerOptions, type Program, type TypeChecker } from 'typescript'; | ||
import { getDecorators } from '../utils/decoratorUtils'; | ||
import { importClassesFromDirectories } from '../utils/importClassesFromDirectories'; | ||
import { ControllerGenerator } from './controllerGenerator'; | ||
import { GenerateMetadataError } from './exceptions'; | ||
import { Config, Tsoa } from '@tsoa/runtime'; | ||
import { TypeResolver } from './typeResolver'; | ||
import { getDecorators } from '../utils/decoratorUtils'; | ||
import { type TypeChecker, type Program, type ClassDeclaration, type CompilerOptions, createProgram, forEachChild, isClassDeclaration } from 'typescript'; | ||
|
||
export class MetadataGenerator { | ||
public readonly controllerNodes = new Array<ClassDeclaration>(); | ||
public readonly typeChecker: TypeChecker; | ||
private readonly program: Program; | ||
private referenceTypeMap: Tsoa.ReferenceTypeMap = {}; | ||
private circularDependencyResolvers = new Array<(referenceTypes: Tsoa.ReferenceTypeMap) => void>(); | ||
private modelDefinitionPosMap: { [name: string]: Array<{ fileName: string; pos: number }> } = {}; | ||
private expressionOrigNameMap: Record<string, string> = {}; | ||
|
||
constructor( | ||
entryFile: string, | ||
|
@@ -35,7 +36,6 @@ export class MetadataGenerator { | |
|
||
this.checkForMethodSignatureDuplicates(controllers); | ||
this.checkForPathParamSignatureDuplicates(controllers); | ||
this.circularDependencyResolvers.forEach(c => c(this.referenceTypeMap)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handled in another place |
||
|
||
return { | ||
controllers, | ||
|
@@ -214,17 +214,34 @@ export class MetadataGenerator { | |
|
||
public AddReferenceType(referenceType: Tsoa.ReferenceType) { | ||
if (!referenceType.refName) { | ||
return; | ||
throw new Error('no reference type name found'); | ||
} | ||
this.referenceTypeMap[decodeURIComponent(referenceType.refName)] = referenceType; | ||
this.referenceTypeMap[referenceType.refName] = referenceType; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. decodeURIComponent() not interesting here, because typeResolver guarantees, that only OpenApi-accepted names can be generated. |
||
} | ||
|
||
public GetReferenceType(refName: string) { | ||
return this.referenceTypeMap[refName]; | ||
} | ||
|
||
public OnFinish(callback: (referenceTypes: Tsoa.ReferenceTypeMap) => void) { | ||
this.circularDependencyResolvers.push(callback); | ||
public CheckModelUnicity(refName: string, positions: Array<{ fileName: string; pos: number }>) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Type unicity check:
|
||
if (!this.modelDefinitionPosMap[refName]) { | ||
this.modelDefinitionPosMap[refName] = positions; | ||
} else { | ||
const origPositions = this.modelDefinitionPosMap[refName]; | ||
if (!(origPositions.length === positions.length && positions.every(pos => origPositions.find(origPos => pos.pos === origPos.pos && pos.fileName === origPos.fileName)))) { | ||
throw new Error(`Found 2 different model definitions for model ${refName}: orig: ${JSON.stringify(origPositions)}, act: ${JSON.stringify(positions)}`); | ||
} | ||
} | ||
} | ||
|
||
public CheckExpressionUnicity(formattedRefName: string, refName: string) { | ||
if (!this.expressionOrigNameMap[formattedRefName]) { | ||
this.expressionOrigNameMap[formattedRefName] = refName; | ||
} else { | ||
if (this.expressionOrigNameMap[formattedRefName] !== refName) { | ||
throw new Error(`Found 2 different type expressions for formatted name "${formattedRefName}": orig: "${this.expressionOrigNameMap[formattedRefName]}", act: "${refName}"`); | ||
} | ||
} | ||
} | ||
|
||
private buildControllers() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small thing, do not crash while trying to make exceptions to throw (or when make warning messages).