From 20f0860821c967ee892161d303a7946285bf43a1 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 22 Sep 2014 11:45:26 -0400 Subject: [PATCH 1/7] Moved to new tree for brace matching. --- src/services/braceMatcher.ts | 89 +++++++++++++++++++----------------- src/services/services.ts | 75 +++++++++++++++--------------- 2 files changed, 83 insertions(+), 81 deletions(-) diff --git a/src/services/braceMatcher.ts b/src/services/braceMatcher.ts index 3615f677024..e222125fc19 100644 --- a/src/services/braceMatcher.ts +++ b/src/services/braceMatcher.ts @@ -15,59 +15,62 @@ /// -module TypeScript.Services { - export class BraceMatcher { +module ts.BraceMatcher { - // Given a script name and position in the script, return a pair of text range if the - // position corresponds to a "brace matchin" characters (e.g. "{" or "(", etc.) - // If the position is not on any range, return an empty set. - public static getMatchSpans(syntaxTree: TypeScript.SyntaxTree, position: number): TypeScript.TextSpan[] { - var result: TypeScript.TextSpan[] = []; + // Given a script name and position in the script, return a pair of text range if the + // position corresponds to a "brace matching" characters (e.g. "{" or "(", etc.) + // If the position is not on any range, return an empty set. + export function getMatchSpans(sourceFile: SourceFile, position: number): TypeScript.TextSpan[] { + var result: TypeScript.TextSpan[] = []; - var token = findToken(syntaxTree.sourceUnit(), position); + var token = getTokenAtPosition(sourceFile, position); - if (start(token) === position) { - var matchKind = BraceMatcher.getMatchingTokenKind(token); + if (token.getStart() === position) { + var matchKind = getMatchingTokenKind(token); - if (matchKind !== null) { - var parentElement = token.parent; + // Ensure that there is a corresponding token to match ours. + if (matchKind) { + var parentElement = token.parent; - for (var i = 0, n = childCount(parentElement); i < n; i++) { - var current = childAt(parentElement, i); - - if (current !== null && fullWidth(current) > 0) { - if (current.kind() === matchKind) { - var range1 = new TypeScript.TextSpan(start(token), width(token)); - var range2 = new TypeScript.TextSpan(start(current), width(current)); - if (range1.start() < range2.start()) { - result.push(range1, range2); - } - else { - result.push(range2, range1); - } - break; + var childNodes = parentElement.getChildren(); + for (var i = 0, n = childNodes.length; i < n; i++) { + var current = childNodes[i]; + + // TODO(drosen): Check if we need the check on 'current'. + if (current && current.getFullWidth() > 0) { + if (current.kind === matchKind) { + var range1 = new TypeScript.TextSpan(token.getStart(), token.getWidth()); + var range2 = new TypeScript.TextSpan(current.getStart(), current.getWidth()); + // TODO(drosen): Does order *really* matter here? + if (range1.start() < range2.start()) { + result.push(range1, range2); } + else { + result.push(range2, range1); + } + + break; } } } } - - return result; } - private static getMatchingTokenKind(token: TypeScript.ISyntaxToken): TypeScript.SyntaxKind { - switch (token.kind()) { - case TypeScript.SyntaxKind.OpenBraceToken: return TypeScript.SyntaxKind.CloseBraceToken - case TypeScript.SyntaxKind.OpenParenToken: return TypeScript.SyntaxKind.CloseParenToken; - case TypeScript.SyntaxKind.OpenBracketToken: return TypeScript.SyntaxKind.CloseBracketToken; - case TypeScript.SyntaxKind.LessThanToken: return TypeScript.SyntaxKind.GreaterThanToken; - case TypeScript.SyntaxKind.CloseBraceToken: return TypeScript.SyntaxKind.OpenBraceToken - case TypeScript.SyntaxKind.CloseParenToken: return TypeScript.SyntaxKind.OpenParenToken; - case TypeScript.SyntaxKind.CloseBracketToken: return TypeScript.SyntaxKind.OpenBracketToken; - case TypeScript.SyntaxKind.GreaterThanToken: return TypeScript.SyntaxKind.LessThanToken; - } - - return null; - } + return result; } -} \ No newline at end of file + + function getMatchingTokenKind(token: Node): ts.SyntaxKind { + switch (token.kind) { + case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken + case ts.SyntaxKind.OpenParenToken: return ts.SyntaxKind.CloseParenToken; + case ts.SyntaxKind.OpenBracketToken: return ts.SyntaxKind.CloseBracketToken; + case ts.SyntaxKind.LessThanToken: return ts.SyntaxKind.GreaterThanToken; + case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken + case ts.SyntaxKind.CloseParenToken: return ts.SyntaxKind.OpenParenToken; + case ts.SyntaxKind.CloseBracketToken: return ts.SyntaxKind.OpenBracketToken; + case ts.SyntaxKind.GreaterThanToken: return ts.SyntaxKind.LessThanToken; + } + + return undefined; + } +} diff --git a/src/services/services.ts b/src/services/services.ts index 04e63f6dbe1..986d8d0e0ba 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2083,40 +2083,6 @@ module ts { } } - /** Get the token whose text contains the position, or the containing node. */ - function getNodeAtPosition(sourceFile: SourceFile, position: number) { - var current: Node = sourceFile; - outer: while (true) { - // find the child that has this - for (var i = 0, n = current.getChildCount(); i < n; i++) { - var child = current.getChildAt(i); - if (child.getStart() <= position && position < child.getEnd()) { - current = child; - continue outer; - } - } - return current; - } - } - - /** Get a token that contains the position. This is guaranteed to return a token, the position can be in the - * leading trivia or within the token text. - */ - function getTokenAtPosition(sourceFile: SourceFile, position: number) { - var current: Node = sourceFile; - outer: while (true) { - // find the child that has this - for (var i = 0, n = current.getChildCount(); i < n; i++) { - var child = current.getChildAt(i); - if (child.getFullStart() <= position && position < child.getEnd()) { - current = child; - continue outer; - } - } - return current; - } - } - function getContainerNode(node: Node): Node { while (true) { node = node.parent; @@ -3759,14 +3725,13 @@ module ts { } function getBraceMatchingAtPosition(filename: string, position: number) { - filename = TypeScript.switchToForwardSlashes(filename); - var syntaxTree = getSyntaxTree(filename); - return TypeScript.Services.BraceMatcher.getMatchSpans(syntaxTree, position); + var sourceFile = getCurrentSourceFile(filename); + return BraceMatcher.getMatchSpans(sourceFile, position); } function getIndentationAtPosition(filename: string, position: number, editorOptions: EditorOptions) { filename = TypeScript.switchToForwardSlashes(filename); - + var sourceFile = getCurrentSourceFile(filename); var options = new TypeScript.FormattingOptions(!editorOptions.ConvertTabsToSpaces, editorOptions.TabSize, editorOptions.IndentSize, editorOptions.NewLineCharacter) @@ -4279,6 +4244,40 @@ module ts { }; } + /** Get the token whose text contains the position, or the containing node. */ + export function getNodeAtPosition(sourceFile: SourceFile, position: number) { + var current: Node = sourceFile; + outer: while (true) { + // find the child that has this + for (var i = 0, n = current.getChildCount(); i < n; i++) { + var child = current.getChildAt(i); + if (child.getStart() <= position && position < child.getEnd()) { + current = child; + continue outer; + } + } + return current; + } + } + + /** Get a token that contains the position. This is guaranteed to return a token, the position can be in the + * leading trivia or within the token text. + */ + export function getTokenAtPosition(sourceFile: SourceFile, position: number) { + var current: Node = sourceFile; + outer: while (true) { + // find the child that has this + for (var i = 0, n = current.getChildCount(); i < n; i++) { + var child = current.getChildAt(i); + if (child.getFullStart() <= position && position < child.getEnd()) { + current = child; + continue outer; + } + } + return current; + } + } + function initializeServices() { objectAllocator = { getNodeConstructor: kind => { From 8202150b584a81269d7bdd475ac1365482fe9966 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 22 Sep 2014 11:01:35 -0700 Subject: [PATCH 2/7] Fixed fourslash bug for adjacent braces, courtesy of @mhegazy. --- src/harness/fourslash.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index ed6dc1a71f7..2e94e39e71d 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1661,9 +1661,9 @@ module FourSlash { } var actualMatchPosition = -1; - if (bracePosition >= actual[0].start() && bracePosition <= actual[0].end()) { + if (bracePosition === actual[0].start()) { actualMatchPosition = actual[1].start(); - } else if (bracePosition >= actual[1].start() && bracePosition <= actual[1].end()) { + } else if (bracePosition === actual[1].start()) { actualMatchPosition = actual[0].start(); } else { throw new Error('verifyMatchingBracePosition failed - could not find the brace position: ' + bracePosition + ' in the returned list: (' + actual[0].start() + ',' + actual[0].end() + ') and (' + actual[1].start() + ',' + actual[1].end() + ')'); From 384d77197e116cfd8e9eab638ff275fba16ffdee Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 22 Sep 2014 11:07:56 -0700 Subject: [PATCH 3/7] Moved old fourslash test for brace matching over from fourslash_old. --- .../cases/{fourslash_old => fourslash}/getMatchingBraces.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tests/cases/{fourslash_old => fourslash}/getMatchingBraces.ts (79%) diff --git a/tests/cases/fourslash_old/getMatchingBraces.ts b/tests/cases/fourslash/getMatchingBraces.ts similarity index 79% rename from tests/cases/fourslash_old/getMatchingBraces.ts rename to tests/cases/fourslash/getMatchingBraces.ts index 13d5effa15f..fc8a71197db 100644 --- a/tests/cases/fourslash_old/getMatchingBraces.ts +++ b/tests/cases/fourslash/getMatchingBraces.ts @@ -38,6 +38,6 @@ ////} test.ranges().forEach((range) => { - verify.matchingBracePositionInCurrentFile(range.start, range.end - 1); - verify.matchingBracePositionInCurrentFile(range.end - 1, range.start); - }); \ No newline at end of file + verify.matchingBracePositionInCurrentFile(range.start, range.end - 1); + verify.matchingBracePositionInCurrentFile(range.end - 1, range.start); +}); \ No newline at end of file From 1be4fe1b619f966759f9100665dd835f2dcfe57a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 22 Sep 2014 12:00:45 -0700 Subject: [PATCH 4/7] Addressed code review feedback. --- src/services/braceMatcher.ts | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/services/braceMatcher.ts b/src/services/braceMatcher.ts index e222125fc19..c26be522694 100644 --- a/src/services/braceMatcher.ts +++ b/src/services/braceMatcher.ts @@ -25,32 +25,30 @@ module ts.BraceMatcher { var token = getTokenAtPosition(sourceFile, position); - if (token.getStart() === position) { + if (token.getStart(sourceFile) === position) { var matchKind = getMatchingTokenKind(token); // Ensure that there is a corresponding token to match ours. if (matchKind) { var parentElement = token.parent; - var childNodes = parentElement.getChildren(); + var childNodes = parentElement.getChildren(sourceFile); for (var i = 0, n = childNodes.length; i < n; i++) { var current = childNodes[i]; - // TODO(drosen): Check if we need the check on 'current'. - if (current && current.getFullWidth() > 0) { - if (current.kind === matchKind) { - var range1 = new TypeScript.TextSpan(token.getStart(), token.getWidth()); - var range2 = new TypeScript.TextSpan(current.getStart(), current.getWidth()); - // TODO(drosen): Does order *really* matter here? - if (range1.start() < range2.start()) { - result.push(range1, range2); - } - else { - result.push(range2, range1); - } - - break; + if (current.kind === matchKind) { + var range1 = new TypeScript.TextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); + var range2 = new TypeScript.TextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); + + // We want to order the braces when we return the result. + if (range1.start() < range2.start()) { + result.push(range1, range2); } + else { + result.push(range2, range1); + } + + break; } } } From 3ffed28a1d7feac2cba1bce8df2c2b6ccbf77770 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 22 Sep 2014 13:33:29 -0700 Subject: [PATCH 5/7] Moved brace matching code into services.ts --- src/services/braceMatcher.ts | 74 --------------------- src/services/services.ts | 123 +++++++++++++++++++++++++---------- 2 files changed, 87 insertions(+), 110 deletions(-) delete mode 100644 src/services/braceMatcher.ts diff --git a/src/services/braceMatcher.ts b/src/services/braceMatcher.ts deleted file mode 100644 index c26be522694..00000000000 --- a/src/services/braceMatcher.ts +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -/// - -module ts.BraceMatcher { - - // Given a script name and position in the script, return a pair of text range if the - // position corresponds to a "brace matching" characters (e.g. "{" or "(", etc.) - // If the position is not on any range, return an empty set. - export function getMatchSpans(sourceFile: SourceFile, position: number): TypeScript.TextSpan[] { - var result: TypeScript.TextSpan[] = []; - - var token = getTokenAtPosition(sourceFile, position); - - if (token.getStart(sourceFile) === position) { - var matchKind = getMatchingTokenKind(token); - - // Ensure that there is a corresponding token to match ours. - if (matchKind) { - var parentElement = token.parent; - - var childNodes = parentElement.getChildren(sourceFile); - for (var i = 0, n = childNodes.length; i < n; i++) { - var current = childNodes[i]; - - if (current.kind === matchKind) { - var range1 = new TypeScript.TextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); - var range2 = new TypeScript.TextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); - - // We want to order the braces when we return the result. - if (range1.start() < range2.start()) { - result.push(range1, range2); - } - else { - result.push(range2, range1); - } - - break; - } - } - } - } - - return result; - } - - function getMatchingTokenKind(token: Node): ts.SyntaxKind { - switch (token.kind) { - case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken - case ts.SyntaxKind.OpenParenToken: return ts.SyntaxKind.CloseParenToken; - case ts.SyntaxKind.OpenBracketToken: return ts.SyntaxKind.CloseBracketToken; - case ts.SyntaxKind.LessThanToken: return ts.SyntaxKind.GreaterThanToken; - case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken - case ts.SyntaxKind.CloseParenToken: return ts.SyntaxKind.OpenParenToken; - case ts.SyntaxKind.CloseBracketToken: return ts.SyntaxKind.OpenBracketToken; - case ts.SyntaxKind.GreaterThanToken: return ts.SyntaxKind.LessThanToken; - } - - return undefined; - } -} diff --git a/src/services/services.ts b/src/services/services.ts index 986d8d0e0ba..31fdfd8e5fb 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -7,7 +7,6 @@ /// /// /// -/// /// /// /// @@ -2083,6 +2082,40 @@ module ts { } } + /** Get the token whose text contains the position, or the containing node. */ + function getNodeAtPosition(sourceFile: SourceFile, position: number) { + var current: Node = sourceFile; + outer: while (true) { + // find the child that has this + for (var i = 0, n = current.getChildCount(); i < n; i++) { + var child = current.getChildAt(i); + if (child.getStart() <= position && position < child.getEnd()) { + current = child; + continue outer; + } + } + return current; + } + } + + /** Get a token that contains the position. This is guaranteed to return a token, the position can be in the + * leading trivia or within the token text. + */ + function getTokenAtPosition(sourceFile: SourceFile, position: number) { + var current: Node = sourceFile; + outer: while (true) { + // find the child that has this + for (var i = 0, n = current.getChildCount(); i < n; i++) { + var child = current.getChildAt(i); + if (child.getFullStart() <= position && position < child.getEnd()) { + current = child; + continue outer; + } + } + return current; + } + } + function getContainerNode(node: Node): Node { while (true) { node = node.parent; @@ -3726,7 +3759,59 @@ module ts { function getBraceMatchingAtPosition(filename: string, position: number) { var sourceFile = getCurrentSourceFile(filename); - return BraceMatcher.getMatchSpans(sourceFile, position); + return getMatchSpans(sourceFile, position); + + function getMatchSpans(sourceFile: SourceFile, position: number): TypeScript.TextSpan[] { + var result: TypeScript.TextSpan[] = []; + + var token = getTokenAtPosition(sourceFile, position); + + if (token.getStart(sourceFile) === position) { + var matchKind = getMatchingTokenKind(token); + + // Ensure that there is a corresponding token to match ours. + if (matchKind) { + var parentElement = token.parent; + + var childNodes = parentElement.getChildren(sourceFile); + for (var i = 0, n = childNodes.length; i < n; i++) { + var current = childNodes[i]; + + if (current.kind === matchKind) { + var range1 = new TypeScript.TextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); + var range2 = new TypeScript.TextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); + + // We want to order the braces when we return the result. + if (range1.start() < range2.start()) { + result.push(range1, range2); + } + else { + result.push(range2, range1); + } + + break; + } + } + } + } + + return result; + } + + function getMatchingTokenKind(token: Node): ts.SyntaxKind { + switch (token.kind) { + case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken + case ts.SyntaxKind.OpenParenToken: return ts.SyntaxKind.CloseParenToken; + case ts.SyntaxKind.OpenBracketToken: return ts.SyntaxKind.CloseBracketToken; + case ts.SyntaxKind.LessThanToken: return ts.SyntaxKind.GreaterThanToken; + case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken + case ts.SyntaxKind.CloseParenToken: return ts.SyntaxKind.OpenParenToken; + case ts.SyntaxKind.CloseBracketToken: return ts.SyntaxKind.OpenBracketToken; + case ts.SyntaxKind.GreaterThanToken: return ts.SyntaxKind.LessThanToken; + } + + return undefined; + } } function getIndentationAtPosition(filename: string, position: number, editorOptions: EditorOptions) { @@ -4244,40 +4329,6 @@ module ts { }; } - /** Get the token whose text contains the position, or the containing node. */ - export function getNodeAtPosition(sourceFile: SourceFile, position: number) { - var current: Node = sourceFile; - outer: while (true) { - // find the child that has this - for (var i = 0, n = current.getChildCount(); i < n; i++) { - var child = current.getChildAt(i); - if (child.getStart() <= position && position < child.getEnd()) { - current = child; - continue outer; - } - } - return current; - } - } - - /** Get a token that contains the position. This is guaranteed to return a token, the position can be in the - * leading trivia or within the token text. - */ - export function getTokenAtPosition(sourceFile: SourceFile, position: number) { - var current: Node = sourceFile; - outer: while (true) { - // find the child that has this - for (var i = 0, n = current.getChildCount(); i < n; i++) { - var child = current.getChildAt(i); - if (child.getFullStart() <= position && position < child.getEnd()) { - current = child; - continue outer; - } - } - return current; - } - } - function initializeServices() { objectAllocator = { getNodeConstructor: kind => { From 36308fd4933af5748baeec203fd7e112cfa4a5b6 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 22 Sep 2014 19:03:13 -0700 Subject: [PATCH 6/7] Inlined 'getMatchSpans'. --- src/services/services.ts | 50 ++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 31fdfd8e5fb..819dcc8d825 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3759,45 +3759,41 @@ module ts { function getBraceMatchingAtPosition(filename: string, position: number) { var sourceFile = getCurrentSourceFile(filename); - return getMatchSpans(sourceFile, position); + var result: TypeScript.TextSpan[] = []; - function getMatchSpans(sourceFile: SourceFile, position: number): TypeScript.TextSpan[] { - var result: TypeScript.TextSpan[] = []; + var token = getTokenAtPosition(sourceFile, position); - var token = getTokenAtPosition(sourceFile, position); + if (token.getStart(sourceFile) === position) { + var matchKind = getMatchingTokenKind(token); - if (token.getStart(sourceFile) === position) { - var matchKind = getMatchingTokenKind(token); + // Ensure that there is a corresponding token to match ours. + if (matchKind) { + var parentElement = token.parent; - // Ensure that there is a corresponding token to match ours. - if (matchKind) { - var parentElement = token.parent; + var childNodes = parentElement.getChildren(sourceFile); + for (var i = 0, n = childNodes.length; i < n; i++) { + var current = childNodes[i]; - var childNodes = parentElement.getChildren(sourceFile); - for (var i = 0, n = childNodes.length; i < n; i++) { - var current = childNodes[i]; + if (current.kind === matchKind) { + var range1 = new TypeScript.TextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); + var range2 = new TypeScript.TextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); - if (current.kind === matchKind) { - var range1 = new TypeScript.TextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); - var range2 = new TypeScript.TextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); - - // We want to order the braces when we return the result. - if (range1.start() < range2.start()) { - result.push(range1, range2); - } - else { - result.push(range2, range1); - } - - break; + // We want to order the braces when we return the result. + if (range1.start() < range2.start()) { + result.push(range1, range2); } + else { + result.push(range2, range1); + } + + break; } } } - - return result; } + return result; + function getMatchingTokenKind(token: Node): ts.SyntaxKind { switch (token.kind) { case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken From 1842dd0568e2424ef01be8930d0cb21cffac9da7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 23 Sep 2014 08:23:59 -0700 Subject: [PATCH 7/7] Added test case for adjacent braces. --- tests/cases/fourslash/getMatchingBracesAdjacentBraces.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/cases/fourslash/getMatchingBracesAdjacentBraces.ts diff --git a/tests/cases/fourslash/getMatchingBracesAdjacentBraces.ts b/tests/cases/fourslash/getMatchingBracesAdjacentBraces.ts new file mode 100644 index 00000000000..8dd997ebe73 --- /dev/null +++ b/tests/cases/fourslash/getMatchingBracesAdjacentBraces.ts @@ -0,0 +1,9 @@ +////function f[||][|(x: T)|][|{ +//// return x; +////}|] + +// If there is an adjacent opening and closing brace, +// then only the opening brace should get highlighted. +test.ranges().forEach(range => { + verify.matchingBracePositionInCurrentFile(range.start, range.end - 1); +}); \ No newline at end of file