@@ -41,6 +41,9 @@ const COLON = ':'
4141const UNDEFINED = undefined
4242
4343const symbol = ( prefix , key ) => Symbol . for ( prefix + COLON + key )
44+ const symbol_checked = ( prefix , key ) => key
45+ ? symbol ( prefix , key )
46+ : prefix
4447
4548const define = ( target , key , value ) => Object . defineProperty ( target , key , {
4649 value,
@@ -164,6 +167,7 @@ module.exports = {
164167
165168 is_raw_json,
166169
170+ // TODO: js doc and usage examples
167171 assign ( target , source , keys ) {
168172 if ( ! isObject ( target ) ) {
169173 throw new TypeError ( 'Cannot convert undefined or null to object' )
@@ -174,17 +178,68 @@ module.exports = {
174178 }
175179
176180 if ( keys === UNDEFINED ) {
181+ // Copy all comments from source to target, including:
182+ // - non-property comments
183+ // - property comments
184+
177185 keys = Object . keys ( source )
178186 // We assign non-property comments
179187 // if argument `keys` is not specified
180188 assign_non_prop_comments ( target , source )
181189 } else if ( ! isArray ( keys ) ) {
182190 throw new TypeError ( 'keys must be array or undefined' )
183191 } else if ( keys . length === 0 ) {
192+ // Copy all non-property comments from source to target
193+
184194 // Or argument `keys` is an empty array
185195 assign_non_prop_comments ( target , source )
186196 }
187197
198+ // Copy specified property comments from source to target
188199 return assign ( target , source , keys )
200+ } ,
201+
202+ // TODO: js doc and usage examples
203+ moveComments ( source , target , {
204+ kind : from_kind ,
205+ key : from_key
206+ } , {
207+ kind : to_kind ,
208+ key : to_key
209+ } , override = false ) {
210+ if ( ! isObject ( source ) ) {
211+ throw new TypeError ( 'source must be an object' )
212+ }
213+
214+ if ( ! target ) {
215+ target = source
216+ }
217+
218+ if ( ! isObject ( target ) ) {
219+ // No target to move to
220+ return
221+ }
222+
223+ const from_prop = symbol_checked ( from_kind , from_key )
224+ const to_prop = symbol_checked ( to_kind , to_key )
225+
226+ if ( ! Object . hasOwn ( source , from_prop ) ) {
227+ return
228+ }
229+
230+ const source_comments = source [ from_prop ]
231+ delete source [ from_prop ]
232+
233+ if ( override || ! Object . hasOwn ( target , to_prop ) ) {
234+ // Override
235+ // or the target has no existing comments
236+ define ( target , to_prop , source_comments )
237+ return
238+ }
239+
240+ const target_comments = target [ to_prop ]
241+ if ( target_comments ) {
242+ target_comments . push ( ...source_comments )
243+ }
189244 }
190245}
0 commit comments