More unit tests. Clearer comments. Better variable names.

This commit is contained in:
dgeorge 2011-11-01 17:09:43 -07:00
commit ae26fe31a0
2 changed files with 46 additions and 22 deletions

View file

@ -77,43 +77,46 @@ function BracketMatch() {
var token = iterator.getCurrentToken(); var token = iterator.getCurrentToken();
if (!token) return null; if (!token) return null;
// Create a pattern that matches any token with the same type as token.type. // token.type contains a period-delimited list of token identifiers
// Exception: if token.type includes "rparen", then also match "lparen". // (e.g.: "constant.numeric" or "paren.lparen"). Create a pattern that
// matches any token containing the same identifiers or a subset. In
// addition, if token.type includes "rparen", then also match "lparen".
// So if type.token is "paren.rparen", then typeRe will match "lparen.paren".
var typeRe = new RegExp("(\\.?[" + var typeRe = new RegExp("(\\.?[" +
token.type.replace(".", "|").replace("rparen", "lparen|rparen") + "])+"); token.type.replace(".", "|").replace("rparen", "lparen|rparen") + "])+");
// Start searching in token, just before the character at position.column // Start searching in token, just before the character at position.column
var vIndex = position.column - iterator.getCurrentTokenColumn() - 2; var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;
var value = token.value; var value = token.value;
while (true) { while (true) {
while (vIndex >= 0) { while (valueIndex >= 0) {
var char = value.charAt(vIndex); var char = value.charAt(valueIndex);
if (char == openBracket) { if (char == openBracket) {
depth -= 1; depth -= 1;
if (depth == 0) { if (depth == 0) {
return {row: iterator.getCurrentTokenRow(), return {row: iterator.getCurrentTokenRow(),
column: vIndex + iterator.getCurrentTokenColumn()}; column: valueIndex + iterator.getCurrentTokenColumn()};
} }
} }
else if (char == bracket) { else if (char == bracket) {
depth += 1; depth += 1;
} }
vIndex -= 1; valueIndex -= 1;
} }
// Scan backward through the document, looking for the next token // Scan backward through the document, looking for the next token
// whose type matches typeRe // whose type matches typeRe
do { do {
token = iterator.stepBackward(); token = iterator.stepBackward();
} while (token && !typeRe.test(token.type)) } while (token && !typeRe.test(token.type));
if (token == null) if (token == null)
break; break;
value = token.value; value = token.value;
vIndex = token.value.length - 1; valueIndex = value.length - 1;
} }
return null; return null;
@ -127,43 +130,46 @@ function BracketMatch() {
var token = iterator.getCurrentToken(); var token = iterator.getCurrentToken();
if (!token) return null; if (!token) return null;
// Create a pattern that matches any token with the same type as token.type. // token.type contains a period-delimited list of token identifiers
// Exception: if token.type includes "lparen", then also match "rparen". // (e.g.: "constant.numeric" or "paren.lparen"). Create a pattern that
// matches any token containing the same identifiers or a subset. In
// addition, if token.type includes "lparen", then also match "rparen".
// So if type.token is "lparen.paren", then typeRe will match "paren.rparen".
var typeRe = new RegExp("(\\.?[" + var typeRe = new RegExp("(\\.?[" +
token.type.replace(".", "|").replace("lparen", "lparen|rparen") + "])+"); token.type.replace(".", "|").replace("lparen", "lparen|rparen") + "])+");
// Start searching in token, after after the character at position.column // Start searching in token, after the character at position.column
var vIndex = position.column - iterator.getCurrentTokenColumn(); var valueIndex = position.column - iterator.getCurrentTokenColumn();
while (true) { while (true) {
var value = token.value; var value = token.value;
var valueLength = value.length; var valueLength = value.length;
while (vIndex < valueLength) { while (valueIndex < valueLength) {
var char = value.charAt(vIndex); var char = value.charAt(valueIndex);
if (char == closingBracket) { if (char == closingBracket) {
depth -= 1; depth -= 1;
if (depth == 0) { if (depth == 0) {
return {row: iterator.getCurrentTokenRow(), return {row: iterator.getCurrentTokenRow(),
column: vIndex + iterator.getCurrentTokenColumn()}; column: valueIndex + iterator.getCurrentTokenColumn()};
} }
} }
else if (char == bracket) { else if (char == bracket) {
depth += 1; depth += 1;
} }
vIndex += 1; valueIndex += 1;
} }
// Scan forward through the document, looking for the next token // Scan forward through the document, looking for the next token
// whose type matches typeRe // whose type matches typeRe
do { do {
token = iterator.stepForward(); token = iterator.stepForward();
} while (token && !typeRe.test(token.type)) } while (token && !typeRe.test(token.type));
if (token == null) if (token == null)
break; break;
vIndex = 0; valueIndex = 0;
} }
return null; return null;

View file

@ -91,7 +91,7 @@ module.exports = {
assert.equal(session.findMatchingBracket({row: 0, column: 0}), null); assert.equal(session.findMatchingBracket({row: 0, column: 0}), null);
}, },
"test: find matching opening bracket in JavaScript mode" : function() { "test: find matching opening bracket in JavaScript mode" : function() {
var lines = [ var lines = [
"function foo() {", "function foo() {",
" var str = \"{ foo()\";", " var str = \"{ foo()\";",
@ -113,7 +113,7 @@ module.exports = {
assert.equal(session.findMatchingBracket({row: 0, column: 1}), null); assert.equal(session.findMatchingBracket({row: 0, column: 1}), null);
}, },
"test: find matching closing bracket in JavaScript mode" : function() { "test: find matching closing bracket in JavaScript mode" : function() {
var lines = [ var lines = [
"function foo() {", "function foo() {",
" var str = \"{ foo()\";", " var str = \"{ foo()\";",
@ -134,6 +134,24 @@ module.exports = {
assert.position(session.findMatchingBracket({row: 4, column: 20}), 4, 23); assert.position(session.findMatchingBracket({row: 4, column: 20}), 4, 23);
}, },
"test: handle unbalanced brackets in JavaScript mode" : function() {
var lines = [
"function foo() {",
" var str = \"{ foo()\";",
" if (debug) {",
" // write str a string) to the console",
" console.log(str);",
" ",
" str += \" bar() \";",
"}"
];
var session = new EditSession(lines.join("\n"), new JavaScriptMode());
assert.equal(session.findMatchingBracket({row: 0, column: 16}), null);
assert.equal(session.findMatchingBracket({row: 3, column: 30}), null);
assert.equal(session.findMatchingBracket({row: 1, column: 16}), null);
},
"test: match different bracket types" : function() { "test: match different bracket types" : function() {
var session = new EditSession(["({[", ")]}"]); var session = new EditSession(["({[", ")]}"]);