Skip to content

Commit

Permalink
fix: deduplicate Input objects in JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
mischnic committed Dec 8, 2020
1 parent 7454de3 commit c50d685
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 15 deletions.
23 changes: 12 additions & 11 deletions lib/fromJSON.js
Expand Up @@ -8,16 +8,17 @@ let Input = require('./input')
let Root = require('./root')
let Rule = require('./rule')

function fromJSON (json) {
let defaults = { ...json }
if (json.nodes) {
defaults.nodes = json.nodes.map(i => fromJSON(i))
function fromJSON (json, inputs) {
let { _inputs, ...defaults } = json
inputs = _inputs || inputs
if (defaults.nodes) {
defaults.nodes = json.nodes.map(n => fromJSON(n, inputs))
}
if (defaults.source) {
defaults.source = { ...defaults.source }
if (defaults.source.input) {
if (defaults.source.input != null) {
defaults.source.input = {
...defaults.source.input,
...inputs[defaults.source.input],
__proto__: Input.prototype
}
if (defaults.source.input.map) {
Expand All @@ -28,15 +29,15 @@ function fromJSON (json) {
}
}
}
if (json.type === 'root') {
if (defaults.type === 'root') {
return new Root(defaults)
} else if (json.type === 'decl') {
} else if (defaults.type === 'decl') {
return new Declaration(defaults)
} else if (json.type === 'rule') {
} else if (defaults.type === 'rule') {
return new Rule(defaults)
} else if (json.type === 'comment') {
} else if (defaults.type === 'comment') {
return new Comment(defaults)
} else if (json.type === 'atrule') {
} else if (defaults.type === 'atrule') {
return new AtRule(defaults)
} else {
throw new Error('Unknown node type: ' + json.type)
Expand Down
21 changes: 17 additions & 4 deletions lib/node.js
Expand Up @@ -166,8 +166,11 @@ class Node {
if (!keepBetween) delete this.raws.between
}

toJSON () {
toJSON (inputs) {
let fixed = {}
let emitInputs = inputs == null
inputs = inputs || new Map()
let inputsNextIndex = 0

for (let name in this) {
if (!Object.prototype.hasOwnProperty.call(this, name)) {
Expand All @@ -180,23 +183,33 @@ class Node {
if (Array.isArray(value)) {
fixed[name] = value.map(i => {
if (typeof i === 'object' && i.toJSON) {
return i.toJSON()
return i.toJSON(inputs)
} else {
return i
}
})
} else if (typeof value === 'object' && value.toJSON) {
fixed[name] = value.toJSON()
fixed[name] = value.toJSON(inputs)
} else if (name === 'source') {
let input = inputs.get(value.input)
if (input == null) {
input = inputsNextIndex
inputs.set(value.input, inputsNextIndex)
inputsNextIndex++
}
fixed[name] = {
input: value.input.toJSON(),
input,
start: value.start
}
} else {
fixed[name] = value
}
}

if (emitInputs) {
fixed._inputs = [...inputs.keys()].map(input => input.toJSON())
}

return fixed
}

Expand Down

0 comments on commit c50d685

Please sign in to comment.