Skip to content

Commit

Permalink
fixed TokenList.getTokenAtOffset (#526)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexHaxe authored Sep 6, 2019
1 parent 076cda5 commit ba76d00
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 21 deletions.
26 changes: 5 additions & 21 deletions src/formatter/codedata/TokenList.hx
Original file line number Diff line number Diff line change
Expand Up @@ -91,38 +91,22 @@ class TokenList {
}

public function getTokenAtOffset(off:Int):Null<TokenInfo> {
var lowerBound:Int = 0;
var upperBound:Int = tokens.length - 1;
if (tokens.length <= 0) {
throw BAD_OFFSET;
}

if (off < 0) {
throw BAD_OFFSET;
}

if (off > tokens[upperBound].token.pos.max) {
if (off > tokens[tokens.length - 1].token.pos.max) {
throw BAD_OFFSET;
}

while (true) {
if (lowerBound > upperBound) {
throw BAD_OFFSET;
}

var center:Int = lowerBound + Math.floor((upperBound - lowerBound) / 2);
var matchLeft:Bool = tokens[center].token.pos.min <= off;
var matchRight:Bool = tokens[center].token.pos.max >= off;
if (matchLeft && matchRight) {
return tokens[center];
}
if (matchLeft) {
lowerBound = center + 1;
for (token in tokens) {
if (token == null) {
continue;
}
if (matchRight) {
upperBound = center - 1;
continue;
if (token.token.pos.max >= off) {
return token;
}
}
throw BAD_OFFSET;
Expand Down
2 changes: 2 additions & 0 deletions test/TestSuite.hx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import formatter.FormatStatsTest;
import formatter.codedata.TokenListTest;
import testcases.EmptyLinesTestCases;
import testcases.ExpressionLevelTestCases;
import testcases.IndentationTestCases;
Expand All @@ -17,6 +18,7 @@ class TestSuite extends massive.munit.TestSuite {
if (!singleRun.isSingleRun()) {
add(SelfTest);
add(FormatStatsTest);
add(TokenListTest);
}

add(EmptyLinesTestCases);
Expand Down
71 changes: 71 additions & 0 deletions test/formatter/codedata/TokenListTest.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package formatter.codedata;

import haxe.PosInfos;
import haxe.io.Bytes;
import massive.munit.Assert;

class TokenListTest {
@Test
public function testGetTokenAt() {
var tokenList:TokenList = makeTokenList(FormatStatsTestCode.CodeSample);
checkToken(tokenList, 0, 0, "class");
checkToken(tokenList, 5, 0, "class");
checkToken(tokenList, 7, 1, "Main");
checkToken(tokenList, 12, 2, "{");
checkToken(tokenList, 13, 2, "{");
checkToken(tokenList, 14, 3, "public");
checkToken(tokenList, 41, 9, "trace");
}

@Test
public function testInvalidGetTokenAt() {
var tokenList:TokenList = makeTokenList(FormatStatsTestCode.CodeSample);
try {
tokenList.getTokenAtOffset(-1);
Assert.fail("previous call should not succeed");
} catch (e:Any) {}
try {
tokenList.getTokenAtOffset(64);
Assert.fail("previous call should not succeed");
} catch (e:Any) {}
tokenList = makeTokenList("");
try {
tokenList.getTokenAtOffset(1);
Assert.fail("previous call should not succeed");
} catch (e:Any) {}
}

function checkToken(tokenList:TokenList, offset:Int, expectedIndex:Int, expectedText:String, ?pos:PosInfos) {
var tokenInfo:Null<TokenInfo> = tokenList.getTokenAtOffset(offset);
Assert.isNotNull(tokenInfo, pos);
Assert.isNotNull(tokenInfo.token, pos);
Assert.areEqual(expectedIndex, tokenInfo.token.index, pos);
Assert.areEqual(expectedText, tokenInfo.token.toString());
}

function makeTokenList(code:String):TokenList {
var content:Bytes = Bytes.ofString(code);
var input:FormatterInputData = {
fileName: "test.hx",
content: content,
config: null,
entryPoint: TYPE_LEVEL,
lineSeparator: null,
range: null
}
var parsedCode:ParsedCode = new ParsedCode(input);
return parsedCode.tokenList;
}
}

@:enum
abstract FormatStatsTestCode(String) to String {
var CodeSample = "
class Main {
public function new () {
trace('foo');
}
}
";
}

0 comments on commit ba76d00

Please sign in to comment.