Skip to content
This repository has been archived by the owner on Feb 20, 2024. It is now read-only.

Commit

Permalink
fix non-deterministic typo suggestion ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Feb 18, 2016
1 parent f84e7bd commit 16af13c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
18 changes: 17 additions & 1 deletion skewc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9650,14 +9650,30 @@
this._bestMatch = null;
};

Skew.FuzzySymbolMatcher.prototype._isBetterScore = function(score, match) {
if (score < this._bestScore) {
return true;
}

// Do tie-breaking using a consistent ordering so that language targets
// with unordered maps (C++ for example) can iterate over symbols in an
// unspecified order for speed and still deterministically arrive at the
// same result.
if (score == this._bestScore && (this._bestMatch == null || match.id < this._bestMatch.id)) {
return true;
}

return false;
};

Skew.FuzzySymbolMatcher.prototype.include = function(match) {
if (this._kind == Skew.FuzzySymbolKind.INSTANCE_ONLY && !Skew.in_SymbolKind.isOnInstances(match.kind) || this._kind == Skew.FuzzySymbolKind.GLOBAL_ONLY && Skew.in_SymbolKind.isOnInstances(match.kind) || this._kind == Skew.FuzzySymbolKind.TYPE_ONLY && !Skew.in_SymbolKind.isType(match.kind) || match.state == Skew.SymbolState.INITIALIZING) {
return;
}

var score = Skew.caseAwareLevenshteinEditDistance(this._name, match.name);

if (score <= this._bestScore && score <= match.name.length * 0.5) {
if (score <= match.name.length * 0.5 && this._isBetterScore(score, match)) {
this._bestScore = score;
this._bestMatch = match;
}
Expand Down
18 changes: 17 additions & 1 deletion src/core/symbol.sk
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,22 @@ namespace Skew {
_bestMatch = null
}

def _isBetterScore(score double, match Symbol) bool {
if score < _bestScore {
return true
}

# Do tie-breaking using a consistent ordering so that language targets
# with unordered maps (C++ for example) can iterate over symbols in an
# unspecified order for speed and still deterministically arrive at the
# same result.
if score == _bestScore && (_bestMatch == null || match.id < _bestMatch.id) {
return true
}

return false
}

def include(match Symbol) {
if _kind == .INSTANCE_ONLY && !match.kind.isOnInstances ||
_kind == .GLOBAL_ONLY && match.kind.isOnInstances ||
Expand All @@ -462,7 +478,7 @@ namespace Skew {
}

var score = caseAwareLevenshteinEditDistance(_name, match.name)
if score <= _bestScore && score <= match.name.count * 0.5 {
if score <= match.name.count * 0.5 && _isBetterScore(score, match) {
_bestScore = score
_bestMatch = match
}
Expand Down
8 changes: 4 additions & 4 deletions tests/ide.sk
Original file line number Diff line number Diff line change
Expand Up @@ -731,12 +731,12 @@ namespace Foo {

var bat = 0
", 7, 8, "
<stdin>:8:7: error: \"ba\" is not declared, did you mean \"bat\"?
<stdin>:8:7: error: \"ba\" is not declared, did you mean \"bar\"?
ba
~~
<stdin>:21:5: note: \"bat\" is defined here
var bat = 0
~~~
<stdin>:2:7: note: \"bar\" is defined here
var bar = 0
~~~
<stdin>:8:7: completions:
ba
~~
Expand Down

0 comments on commit 16af13c

Please sign in to comment.