-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Before this commit, Concordance attempted to determine whether a complex value was reused in the same location on either side of a comparison. It did this by detecting value reuse and emitting a Pointer descriptor instead. This required lookups to be maintained, to map pointers back to previously seen descriptors. It turned out that maintaining these lookups is hard, and there were various code paths where Concordance should have added descriptors to the lookup tables but didn't. Furthermore, pointer indexes are simple integer increments, which means that the same value in either side of the comparison may actually have a different index. This breaks the comparison logic. avajs/ava#1431 shows some of the issues that arose from this approach. This commit simplifies the implementation. When describing, if the same value is encountered then the first descriptor is emitted. The serialization logic tracks complex descriptors by their pointer index and serializes a pointer descriptor if reuse is detected. Deserialization ensures that the first descriptor is emitted, rather than the pointer. Circular references are now tracked for each side of the comparison. A stack is maintained, and if at any stage in the comparison a circular reference is detected, then the result of that comparison is only equal if both sides have the same circular reference. Which is a long way of saying that some circular references are considered equal, and others are not. This shouldn't matter much for real-life uses of Concordance, though it is a breaking change.
- Loading branch information
1 parent
611e720
commit ae51d22
Showing
14 changed files
with
176 additions
and
189 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,35 @@ | ||
'use strict' | ||
|
||
class Circular extends Set { | ||
class Circular { | ||
constructor () { | ||
this.stack = new Map() | ||
} | ||
|
||
add (descriptor) { | ||
if (this.stack.has(descriptor)) throw new Error('Already in stack') | ||
|
||
if (descriptor.isItem !== true && descriptor.isMapEntry !== true && descriptor.isProperty !== true) { | ||
super.add(descriptor) | ||
this.stack.set(descriptor, this.stack.size + 1) | ||
} | ||
return this | ||
} | ||
|
||
delete (descriptor) { | ||
if (this.stack.has(descriptor)) { | ||
if (this.stack.get(descriptor) !== this.stack.size) throw new Error('Not on top of stack') | ||
this.stack.delete(descriptor) | ||
} | ||
return this | ||
} | ||
|
||
has (descriptor) { | ||
return this.stack.has(descriptor) | ||
} | ||
|
||
get (descriptor) { | ||
return this.stack.has(descriptor) | ||
? this.stack.get(descriptor) | ||
: 0 | ||
} | ||
} | ||
module.exports = Circular |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.