diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1694d30fa53..16446113d01 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -907,7 +907,9 @@ module ts { ? file.syntacticErrors[file.syntacticErrors.length - 1].start : -1; if (start !== lastErrorPos) { - file.syntacticErrors.push(createFileDiagnostic(file, start, length, message, arg0, arg1, arg2)); + var diagnostic = createFileDiagnostic(file, start, length, message, arg0, arg1, arg2); + diagnostic.isParseError = true; + file.syntacticErrors.push(diagnostic); } if (lookAheadMode === LookAheadMode.NoErrorYet) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1f8e10f619b..87b95a07f93 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1067,6 +1067,7 @@ module ts { category: DiagnosticCategory; code: number; isEarly?: boolean; + isParseError?: boolean; } export enum DiagnosticCategory { diff --git a/src/services/formatting/format.ts b/src/services/formatting/format.ts index 9831921e874..a05bdee6c0f 100644 --- a/src/services/formatting/format.ts +++ b/src/services/formatting/format.ts @@ -117,16 +117,50 @@ module ts.formatting { } } + function prepareRangeContainsErrorFunction(errors: Diagnostic[], originalRange: TextRange): (r: TextRange) => boolean { + if (!errors.length) { + // no errors - always return false + return r => false; + } + else { + var sorted = errors.slice(0).filter(d => d.isParseError).sort((e1, e2) => e1.start - e2.start); + var index = 0; // TODO: set based on the range + var endIndex = sorted.length; // TODO: set based on the range + if (endIndex === 0 || index === sorted.length) { + // errors are outside the interesting span - always return false + return r => false; + } + return r => { + while (true) { + if (index >= endIndex) { + return false; + } + else { + var curr = sorted[index]; + if (r.end <= curr.start) { + return false; + } + else { + var s = Math.max(r.pos, curr.start); + var e = Math.min(r.end, curr.start + curr.length); + if (s < e) { + return true; + } + index++; + } + } + } + }; + } + } + function formatSpan(originalRange: TextRange, sourceFile: SourceFile, options: FormatCodeOptions, rulesProvider: RulesProvider, requestKind: FormattingRequestKind): TextChange[]{ - var syntacticErrors = sourceFile.syntacticErrors.length !== 0 && sourceFile.syntacticErrors.slice(0); - if (syntacticErrors) { - syntacticErrors.sort((d1, d2) => d1.start - d2.start); - } + var rangeContainsError = prepareRangeContainsErrorFunction(sourceFile.syntacticErrors, originalRange); // formatting context to be used by rules provider to get rules var formattingContext = new FormattingContext(sourceFile, requestKind); @@ -262,14 +296,6 @@ module ts.formatting { } } - function rangeContainsError(range: TextRange): boolean { - if (!syntacticErrors.length) { - return false; - } - - binarySearch - } - function consumeTokenAndAdvanceScanner(currentTokenInfo: TokenInfo, parent: Node, contextNode: Node, indentation: DynamicIndentation): void { Debug.assert(rangeContainsRange(parent, currentTokenInfo.token)); @@ -424,6 +450,7 @@ module ts.formatting { return lineAdded; } + function insertIndentation(pos: number, indentation: number, lineAdded: boolean): void { var indentationString = getIndentationString(indentation, options); if (lineAdded) { diff --git a/tests/cases/fourslash/formattingSkippedTokens.ts b/tests/cases/fourslash/formattingSkippedTokens.ts index 62cd0b67c37..a8fc8522f8d 100644 --- a/tests/cases/fourslash/formattingSkippedTokens.ts +++ b/tests/cases/fourslash/formattingSkippedTokens.ts @@ -13,10 +13,10 @@ format.document(); goTo.marker('1'); verify.currentLineContentIs('foo(): Bar { }'); goTo.marker('2'); -verify.currentLineContentIs('function Foo () # { }'); +verify.currentLineContentIs('function Foo() # { }'); goTo.marker('3'); -verify.currentLineContentIs('4+:5'); +verify.currentLineContentIs('4 +:5'); goTo.marker('4'); verify.currentLineContentIs(' : T) { }'); goTo.marker('5'); -verify.currentLineContentIs('var x ='); \ No newline at end of file +verify.currentLineContentIs('var x ='); \ No newline at end of file diff --git a/tests/cases/fourslash/semicolonFormatting.ts b/tests/cases/fourslash/semicolonFormatting.ts index da828e8e389..1522e7b32fa 100644 --- a/tests/cases/fourslash/semicolonFormatting.ts +++ b/tests/cases/fourslash/semicolonFormatting.ts @@ -4,4 +4,4 @@ goTo.eof(); edit.insert(';'); -verify.currentLineContentIs('function of1 (b:{ r:{ c: number;'); \ No newline at end of file +verify.currentLineContentIs('function of1(b: { r: { c: number;'); \ No newline at end of file