Skip to content

Commit c828957

Browse files
fix: generated function names collision
1 parent 798ec60 commit c828957

File tree

2 files changed

+53
-29
lines changed

2 files changed

+53
-29
lines changed

index.js

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,11 @@ function build (schema, options) {
297297
switch (schema.type) {
298298
case 'object':
299299
main = '$main'
300-
code = buildObject(location, code, main)
300+
code = buildObject(location, code, main, main)
301301
break
302302
case 'array':
303303
main = '$main'
304-
code = buildArray(location, code, main)
304+
code = buildArray(location, code, main, main)
305305
schema = location.schema
306306
break
307307
case 'string':
@@ -449,13 +449,13 @@ function addPatternProperties (location) {
449449
const ifPpKeyExists = `if (/${regex.replace(/\\*\//g, '\\/')}/.test(keys[i])) {`
450450

451451
if (type === 'object') {
452-
code += `${buildObject(ppLocation, '', 'buildObjectPP' + index)}
452+
code += `${buildObject(ppLocation, '', 'buildObjectPP' + index, 'buildObjectPP' + index)}
453453
${ifPpKeyExists}
454454
${addComma}
455455
json += serializer.asString(keys[i]) + ':' + buildObjectPP${index}(obj[keys[i]])
456456
`
457457
} else if (type === 'array') {
458-
code += `${buildArray(ppLocation, '', 'buildArrayPP' + index)}
458+
code += `${buildArray(ppLocation, '', 'buildArrayPP' + index, 'buildArrayPP' + index)}
459459
${ifPpKeyExists}
460460
${addComma}
461461
json += serializer.asString(keys[i]) + ':' + buildArrayPP${index}(obj[keys[i]])
@@ -539,12 +539,12 @@ function additionalProperty (location) {
539539
const format = ap.format
540540
const stringSerializer = getStringSerializer(format)
541541
if (type === 'object') {
542-
code += `${buildObject(apLocation, '', 'buildObjectAP')}
542+
code += `${buildObject(apLocation, '', 'buildObjectAP', 'buildObjectAP')}
543543
${addComma}
544544
json += serializer.asString(keys[i]) + ':' + buildObjectAP(obj[keys[i]])
545545
`
546546
} else if (type === 'array') {
547-
code += `${buildArray(apLocation, '', 'buildArrayAP')}
547+
code += `${buildArray(apLocation, '', 'buildArrayAP', 'buildArrayAP')}
548548
${addComma}
549549
json += serializer.asString(keys[i]) + ':' + buildArrayAP(obj[keys[i]])
550550
`
@@ -893,13 +893,14 @@ function toJSON (variableName) {
893893
`
894894
}
895895

896-
function buildObject (location, code, name) {
896+
function buildObject (location, code, functionName, name) {
897897
const schema = location.schema
898898
if (schema.$id !== undefined) {
899899
schemaReferenceMap.set(schema.$id, schema)
900900
}
901901
code += `
902-
function ${name} (input) {
902+
function ${functionName} (input) {
903+
// ${name}
903904
`
904905
if (schema.nullable) {
905906
code += `
@@ -909,14 +910,14 @@ function buildObject (location, code, name) {
909910
`
910911
}
911912

912-
if (objectReferenceSerializersMap.has(schema) && objectReferenceSerializersMap.get(schema) !== name) {
913+
if (objectReferenceSerializersMap.has(schema) && objectReferenceSerializersMap.get(schema) !== functionName) {
913914
code += `
914915
return ${objectReferenceSerializersMap.get(schema)}(input)
915916
}
916917
`
917918
return code
918919
}
919-
objectReferenceSerializersMap.set(schema, name)
920+
objectReferenceSerializersMap.set(schema, functionName)
920921

921922
code += `
922923
var obj = ${toJSON('input')}
@@ -945,13 +946,14 @@ function buildObject (location, code, name) {
945946
return code
946947
}
947948

948-
function buildArray (location, code, name, key = null) {
949+
function buildArray (location, code, functionName, name, key = null) {
949950
let schema = location.schema
950951
if (schema.$id !== undefined) {
951952
schemaReferenceMap.set(schema.$id, schema)
952953
}
953954
code += `
954-
function ${name} (obj) {
955+
function ${functionName} (obj) {
956+
// ${name}
955957
`
956958
if (schema.nullable) {
957959
code += `
@@ -984,7 +986,7 @@ function buildArray (location, code, name, key = null) {
984986
`
985987
return code
986988
}
987-
arrayItemsReferenceSerializersMap.set(schema.items, name)
989+
arrayItemsReferenceSerializersMap.set(schema.items, functionName)
988990
}
989991

990992
let result = { code: '', laterCode: '' }
@@ -1120,18 +1122,9 @@ function dereferenceOfRefs (location, type) {
11201122
return locations
11211123
}
11221124

1123-
let strNameCounter = 0
1124-
function asFuncName (str) {
1125-
// only allow chars that can work
1126-
let rep = str.replace(/[^a-zA-Z0-9$_]/g, '')
1127-
1128-
if (rep.length === 0) {
1129-
return 'anan' + strNameCounter++
1130-
} else if (rep !== str) {
1131-
rep += strNameCounter++
1132-
}
1133-
1134-
return rep
1125+
let genFuncNameCounter = 0
1126+
function generateFuncName () {
1127+
return 'anonymous' + genFuncNameCounter++
11351128
}
11361129

11371130
function nested (laterCode, name, key, location, subKey, isArray) {
@@ -1182,13 +1175,13 @@ function nested (laterCode, name, key, location, subKey, isArray) {
11821175
code += `json += ${funcName}(obj${accessor})`
11831176
break
11841177
case 'object':
1185-
funcName = asFuncName(name + key + subKey)
1186-
laterCode = buildObject(location, laterCode, funcName)
1178+
funcName = generateFuncName()
1179+
laterCode = buildObject(location, laterCode, funcName, name + key + subKey)
11871180
code += `json += ${funcName}(obj${accessor})`
11881181
break
11891182
case 'array':
1190-
funcName = asFuncName('$arr' + name + key + subKey) // eslint-disable-line
1191-
laterCode = buildArray(location, laterCode, funcName, key)
1183+
funcName = generateFuncName()
1184+
laterCode = buildArray(location, laterCode, funcName, name + key + subKey, key)
11921185
code += `json += ${funcName}(obj${accessor})`
11931186
break
11941187
case undefined:

test/nestedObjects.test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,34 @@ test('nested objects with same properties', (t) => {
3030
})
3131
t.equal(value, '{"stringProperty":"string1","objectProperty":{"stringProperty":"string2","numberProperty":42}}')
3232
})
33+
34+
test('names collision', (t) => {
35+
t.plan(1)
36+
37+
const schema = {
38+
title: 'nested objects with same properties',
39+
type: 'object',
40+
properties: {
41+
test: {
42+
type: 'object',
43+
properties: {
44+
a: { type: 'string' }
45+
}
46+
},
47+
tes: {
48+
type: 'object',
49+
properties: {
50+
b: { type: 'string' },
51+
t: { type: 'object' }
52+
}
53+
}
54+
}
55+
}
56+
const stringify = build(schema)
57+
const data = {
58+
test: { a: 'a' },
59+
tes: { b: 'b', t: {} }
60+
}
61+
62+
t.equal(stringify(data), JSON.stringify(data))
63+
})

0 commit comments

Comments
 (0)