@@ -178,9 +178,24 @@ export class ComponentConstructor {
178178 * @param context A parsed JSON-LD context.
179179 * @param classReference The class reference.
180180 * @param fieldName The name of the field.
181+ * @param scope The current field scope.
181182 */
182- public fieldNameToId ( context : JsonLdContextNormalized , classReference : ClassReference , fieldName : string ) : string {
183- return context . compactIri ( `${ this . packageMetadata . moduleIri } /${ this . getPathRelative ( classReference . fileName ) } #${ classReference . localName } _${ fieldName } ` ) ;
183+ public fieldNameToId (
184+ context : JsonLdContextNormalized ,
185+ classReference : ClassReference ,
186+ fieldName : string ,
187+ scope : FieldScope ,
188+ ) : string {
189+ if ( scope . parentFieldNames . length > 0 ) {
190+ fieldName = `${ scope . parentFieldNames . join ( '_' ) } _${ fieldName } ` ;
191+ }
192+ let id = context . compactIri ( `${ this . packageMetadata . moduleIri } /${ this . getPathRelative ( classReference . fileName ) } #${ classReference . localName } _${ fieldName } ` ) ;
193+ if ( id in scope . fieldIdsHash ) {
194+ id += `_${ scope . fieldIdsHash [ id ] ++ } ` ;
195+ } else {
196+ scope . fieldIdsHash [ id ] = 1 ;
197+ }
198+ return id ;
184199 }
185200
186201 /**
@@ -198,12 +213,17 @@ export class ComponentConstructor {
198213 constructorData : ConstructorData < ParameterRangeResolved > ,
199214 parameters : ParameterDefinition [ ] ,
200215 ) : ConstructorArgumentDefinition [ ] {
216+ const scope : FieldScope = {
217+ parentFieldNames : [ ] ,
218+ fieldIdsHash : { } ,
219+ } ;
201220 return constructorData . parameters . map ( parameter => this . parameterDataToConstructorArgument (
202221 context ,
203222 classReference ,
204223 parameter ,
205224 parameters ,
206- this . fieldNameToId ( context , classReference , parameter . name ) ,
225+ this . fieldNameToId ( context , classReference , parameter . name , scope ) ,
226+ scope ,
207227 ) ) ;
208228 }
209229
@@ -218,13 +238,15 @@ export class ComponentConstructor {
218238 * @param parameterData Parameter data.
219239 * @param parameters The array of parameters of the owning class, which will be appended to.
220240 * @param fieldId The @id of the field.
241+ * @param scope The current field scope.
221242 */
222243 public parameterDataToConstructorArgument (
223244 context : JsonLdContextNormalized ,
224245 classReference : ClassLoaded ,
225246 parameterData : ParameterData < ParameterRangeResolved > ,
226247 parameters : ParameterDefinition [ ] ,
227248 fieldId : string ,
249+ scope : FieldScope ,
228250 ) : ConstructorArgumentDefinition {
229251 if ( parameterData . range . type === 'nested' ) {
230252 // Create a hash object with `fields` entries.
@@ -235,6 +257,7 @@ export class ComponentConstructor {
235257 < ParameterData < ParameterRangeResolved > & { range : { type : 'nested' } } > parameterData ,
236258 parameters ,
237259 subParamData ,
260+ scope ,
238261 ) ) ;
239262 return { fields } ;
240263 }
@@ -257,23 +280,30 @@ export class ComponentConstructor {
257280 * @param parameterData Parameter data with nested range.
258281 * @param parameters The array of parameters of the owning class, which will be appended to.
259282 * @param subParamData The sub-parameter of the parameter with nested range.
283+ * @param scope The current field scope.
260284 */
261285 public constructFieldDefinitionNested (
262286 context : JsonLdContextNormalized ,
263287 classReference : ClassLoaded ,
264288 parameterData : ParameterData < ParameterRangeResolved > & { range : { type : 'nested' } } ,
265289 parameters : ParameterDefinition [ ] ,
266290 subParamData : ParameterData < ParameterRangeResolved > ,
291+ scope : FieldScope ,
267292 ) : ConstructorFieldDefinition {
268293 if ( subParamData . type === 'field' ) {
294+ const subScope : FieldScope = {
295+ parentFieldNames : [ ...scope . parentFieldNames , subParamData . name ] ,
296+ fieldIdsHash : scope . fieldIdsHash ,
297+ } ;
269298 return {
270299 keyRaw : subParamData . name ,
271300 value : this . parameterDataToConstructorArgument (
272301 context ,
273302 classReference ,
274303 subParamData ,
275304 parameters ,
276- this . fieldNameToId ( context , classReference , subParamData . name ) ,
305+ this . fieldNameToId ( context , classReference , subParamData . name , scope ) ,
306+ subScope ,
277307 ) ,
278308 } ;
279309 }
@@ -287,9 +317,9 @@ export class ComponentConstructor {
287317 }
288318
289319 // Determine parameter id's
290- const idCollectEntries = this . fieldNameToId ( context , classReference , parameterData . name ) ;
291- const idKey = this . fieldNameToId ( context , classReference , `${ parameterData . name } _key` ) ;
292- const idValue = this . fieldNameToId ( context , classReference , `${ parameterData . name } _value` ) ;
320+ const idCollectEntries = this . fieldNameToId ( context , classReference , parameterData . name , scope ) ;
321+ const idKey = this . fieldNameToId ( context , classReference , `${ parameterData . name } _key` , scope ) ;
322+ const idValue = this . fieldNameToId ( context , classReference , `${ parameterData . name } _value` , scope ) ;
293323
294324 // Create sub parameters for key and value
295325 const subParameters : ParameterDefinition [ ] = [ ] ;
@@ -304,6 +334,7 @@ export class ComponentConstructor {
304334 subParamData ,
305335 subParameters ,
306336 idValue ,
337+ scope ,
307338 ) ;
308339 subParameters [ subParameters . length - 1 ] . required = true ;
309340 subParameters [ subParameters . length - 1 ] . unique = true ;
@@ -312,7 +343,7 @@ export class ComponentConstructor {
312343 const parameter : ParameterDefinition = {
313344 '@id' : idCollectEntries ,
314345 range : {
315- '@type' : this . fieldNameToId ( context , classReference , `${ parameterData . name } _range` ) ,
346+ '@type' : this . fieldNameToId ( context , classReference , `${ parameterData . name } _range` , scope ) ,
316347 parameters : subParameters ,
317348 } ,
318349 } ;
@@ -416,3 +447,14 @@ export interface PathDestinationDefinition {
416447 originalPath : string ;
417448 replacementPath : string ;
418449}
450+
451+ export interface FieldScope {
452+ /**
453+ * All parent field names for the current scope.
454+ */
455+ parentFieldNames : string [ ] ;
456+ /**
457+ * A hash containing all previously created field names, to ensure uniqueness.
458+ */
459+ fieldIdsHash : { [ fieldName : string ] : number } ;
460+ }
0 commit comments