Skip to content

Commit

Permalink
fix: recursive search of direct type references (#591)
Browse files Browse the repository at this point in the history
* fix: recursive search issue

Co-authored-by: John Kaster <kaster@google.com>
  • Loading branch information
josephaxisa and jkaster authored Apr 14, 2021
1 parent 53a32eb commit 9af2e37
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 90 deletions.
17 changes: 8 additions & 9 deletions packages/sdk-codegen/src/sdkModels.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,15 +291,14 @@ describe('sdkModels', () => {
}
})

// TODO create a mock spec that has a recursive type, since this no longer does
// it ('detects recursive types', () => {
// const type = apiTestModel.types['LookmlModelExploreField']
// const actual = type.isRecursive()
// expect(actual).toEqual(true)
// type = apiTestModel.types['CredentialsApi3']
// actual = type.isRecursive()
// expect(actual).toEqual(false)
// })
it('detects recursive types', () => {
let type = apiTestModel.types.LookmlModelExploreField
let actual = type.isRecursive()
expect(actual).toEqual(true)
type = apiTestModel.types.CredentialsApi3
actual = type.isRecursive()
expect(actual).toEqual(false)
})
})

describe('response modes', () => {
Expand Down
37 changes: 29 additions & 8 deletions packages/sdk-codegen/src/sdkModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1608,10 +1608,13 @@ export class Type implements IType {
return false
let result = rx.test(this.searchString(criteria))
if (!result && Type.isPropSearch(criteria)) {
for (const [, p] of Object.entries(this.properties)) {
if (p.search(rx, criteria)) {
result = true
break
for (const [, prop] of Object.entries(this.properties)) {
if (this.name !== prop.type.name) {
/** Avoiding recursion */
if (prop.search(rx, criteria)) {
result = true
break
}
}
}
}
Expand All @@ -1630,7 +1633,10 @@ export class Type implements IType {
}
if (criteria.has(SearchCriterion.property)) {
Object.entries(this.properties).forEach(([, prop]) => {
result += prop.searchString(criteria)
if (this.name !== prop.type.name) {
/** Avoiding recursion */
result += prop.searchString(criteria)
}
})
}
return result
Expand Down Expand Up @@ -1915,7 +1921,7 @@ export class ApiModel implements ISymbolTable, IApiModel {
return new ApiModel(spec)
}

private static isModelSearch(criteria: SearchCriteria): boolean {
private static isMethodSearch(criteria: SearchCriteria): boolean {
return (
criteria.has(SearchCriterion.method) ||
criteria.has(SearchCriterion.argument) ||
Expand Down Expand Up @@ -1979,7 +1985,7 @@ export class ApiModel implements ISymbolTable, IApiModel {
return result
}

if (ApiModel.isModelSearch(criteria)) {
if (ApiModel.isMethodSearch(criteria)) {
Object.entries(this.methods).forEach(([, method]) => {
if (method.search(rx, criteria)) {
methodCount++
Expand Down Expand Up @@ -2029,6 +2035,21 @@ export class ApiModel implements ISymbolTable, IApiModel {
typeName?: string,
methodName?: string
): IType {
const getRef = (schema: OAS.SchemaObject | OAS.ReferenceObject) => {
const ref = schema.$ref
let result = this.refs[ref]

if (!result) {
/** This must be recursive */
const parts: string[] = ref.split('/')
const name = parts[parts.length - 1]
const t = new Type(schema, name)
this.refs[ref] = t
result = t
}
return result
}

if (typeof schema === 'string') {
if (schema.indexOf('/requestBodies/') < 0)
return this.types[schema.substr(schema.lastIndexOf('/') + 1)]
Expand All @@ -2042,7 +2063,7 @@ export class ApiModel implements ISymbolTable, IApiModel {
if (ref) return this.resolveType(ref, style, typeName, methodName)
}
} else if (OAS.isReferenceObject(schema)) {
return this.refs[schema.$ref]
return getRef(schema)
} else if (schema.type) {
if (schema.type === 'integer' && schema.format === 'int64') {
return this.types.int64
Expand Down
Loading

0 comments on commit 9af2e37

Please sign in to comment.