Skip to content

Commit e7df64a

Browse files
authored
fix: shallow-merging nested objects for split sections (#167)
1 parent 35da006 commit e7df64a

2 files changed

Lines changed: 80 additions & 16 deletions

File tree

lib/parser/pbxproj.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,47 @@ function peg$parse(input, options) {
178178
peg$c6 = function() { return Object.create(null) },
179179
peg$c7 = function(list) {
180180
var returnObject = list[0][0];
181-
for(var i = 1; i < list.length; i++){
181+
182+
for (var i = 1; i < list.length; i++) {
182183
var another = list[i][0];
183-
returnObject = Object.assign(returnObject, another);
184+
185+
/*
186+
* Ensure previously parsed section entries are not lost
187+
*
188+
* Example:
189+
*
190+
* If "returnObject" contains:
191+
*
192+
* {
193+
* PBXTargetDependency: {
194+
* 'A': {},
195+
* 'A_comment': 'PBXTargetDependency'
196+
* }
197+
* }
198+
*
199+
* And "another" contains:
200+
*
201+
* {
202+
* PBXTargetDependency: {
203+
* 'B': {},
204+
* 'B_comment': 'PBXTargetDependency'
205+
* }
206+
* }
207+
*
208+
* Using "Object.assign(returnObject, another)" would lose
209+
* "A" as it would replace the entire PBXTargetDependency.
210+
*
211+
* Instead, we will merge each top-level property of the
212+
* objects, if it exists and is an object else add.
213+
*/
214+
for (var key in another) {
215+
returnObject[key] = (
216+
returnObject[key] &&
217+
another[key] &&
218+
typeof returnObject[key] === 'object' &&
219+
typeof another[key] === 'object'
220+
) ? Object.assign(returnObject[key], another[key]) : another[key];
221+
}
184222
}
185223
return returnObject;
186224
},

lib/parser/pbxproj.pegjs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,6 @@
1717
under the License.
1818
*/
1919

20-
{
21-
function merge_obj(obj, secondObj) {
22-
if (!obj)
23-
return secondObj;
24-
25-
for(var i in secondObj)
26-
obj[i] = merge_obj(obj[i], secondObj[i]);
27-
28-
return obj;
29-
}
30-
}
31-
3220
/*
3321
* Project: point of entry from pbxproj file
3422
*/
@@ -60,9 +48,47 @@ AssignmentList
6048
= _ list:((a:Assignment / d:DelimitedSection) _)+
6149
{
6250
var returnObject = list[0][0];
63-
for(var i = 1; i < list.length; i++){
51+
52+
for (var i = 1; i < list.length; i++) {
6453
var another = list[i][0];
65-
returnObject = merge_obj(returnObject, another);
54+
55+
/*
56+
* Ensure previously parsed section entries are not lost
57+
*
58+
* Example:
59+
*
60+
* If "returnObject" contains:
61+
*
62+
* {
63+
* PBXTargetDependency: {
64+
* 'A': {},
65+
* 'A_comment': 'PBXTargetDependency'
66+
* }
67+
* }
68+
*
69+
* And "another" contains:
70+
*
71+
* {
72+
* PBXTargetDependency: {
73+
* 'B': {},
74+
* 'B_comment': 'PBXTargetDependency'
75+
* }
76+
* }
77+
*
78+
* Using "Object.assign(returnObject, another)" would lose
79+
* "A" as it would replace the entire PBXTargetDependency.
80+
*
81+
* Instead, we will merge each top-level property of the
82+
* objects, if it exists and is an object else add.
83+
*/
84+
for (var key in another) {
85+
returnObject[key] = (
86+
returnObject[key] &&
87+
another[key] &&
88+
typeof returnObject[key] === 'object' &&
89+
typeof another[key] === 'object'
90+
) ? Object.assign(returnObject[key], another[key]) : another[key];
91+
}
6692
}
6793
return returnObject;
6894
}

0 commit comments

Comments
 (0)