multiline comments support

This commit is contained in:
Vladimir Matveev 2014-10-17 13:22:39 -07:00
parent c211f97169
commit 4e84377187
3 changed files with 80 additions and 52 deletions

View File

@ -362,21 +362,19 @@ module ts.formatting {
}
if (lastTriviaWasNewLine && indentToken) {
var indentNextTokenOrTrivia = true;
if (currentTokenInfo.leadingTrivia) {
for (var i = 0, len = currentTokenInfo.leadingTrivia.length; i < len; ++i) {
var triviaItem = currentTokenInfo.leadingTrivia[i];
if (rangeContainsRange(originalRange, triviaItem)) {
switch (triviaItem.kind) {
case SyntaxKind.MultiLineCommentTrivia:
// TODO
indentMultilineComment(triviaItem, indentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia);
indentNextTokenOrTrivia = false;
break;
case SyntaxKind.SingleLineCommentTrivia:
if (indentNextTokenOrTrivia) {
insertIndentation(triviaItem.pos, indentation, sourceFile);
insertIndentation(triviaItem.pos, indentation);
indentNextTokenOrTrivia = false;
}
break;
@ -391,7 +389,7 @@ module ts.formatting {
}
}
insertIndentation(currentTokenInfo.token.pos, indentation, sourceFile);
insertIndentation(currentTokenInfo.token.pos, indentation);
//// TODO: remove
//var tokenRange = getNonAdjustedLineAndCharacterFromPosition(currentTokenInfo.token.pos, sourceFile);
@ -408,7 +406,7 @@ module ts.formatting {
return fetchNextTokenInfo();
}
function insertIndentation(pos: number, indentation: number, sourceFile: SourceFile): void {
function insertIndentation(pos: number, indentation: number): void {
var tokenRange = getNonAdjustedLineAndCharacterFromPosition(pos, sourceFile);
if (indentation !== tokenRange.character) {
var indentationString = getIndentationString(indentation, options);
@ -417,6 +415,65 @@ module ts.formatting {
}
}
function indentMultilineComment(commentRange: TextRange, indentation: number, firstLineIsIndented: boolean) {
// split comment in lines
var startLine = getNonAdjustedLineAndCharacterFromPosition(commentRange.pos, sourceFile).line;
var endLine = getNonAdjustedLineAndCharacterFromPosition(commentRange.end, sourceFile).line;
if (startLine === endLine) {
if (!firstLineIsIndented) {
// treat as single line comment
insertIndentation(commentRange.pos, indentation);
}
return;
}
else {
var parts: TextRange[] = [];
var startPos = commentRange.pos;
for (var line = startLine; line < endLine; ++line) {
var endOfLine = getEndLinePosition(line, sourceFile);
parts.push( {pos: startPos, end: endOfLine} );
startPos = getStartPositionOfLine(line + 1, sourceFile);
}
parts.push( {pos: startPos, end: commentRange.end} );
}
var startLinePos = getStartPositionOfLine(startLine, sourceFile);
var nonWhitespaceColumnInFirstPart =
SmartIndenter.findFirstNonWhitespaceColumn(startLinePos, parts[0].pos, sourceFile, options);
if (indentation === nonWhitespaceColumnInFirstPart) {
return;
}
var startIndex = 0;
if (firstLineIsIndented) {
startIndex = 1;
startLine++;
}
// shift all parts on the delta size
var delta = indentation - nonWhitespaceColumnInFirstPart;
for (var i = startIndex, len = parts.length; i < len; ++i, ++startLine) {
var startLinePos = getStartPositionOfLine(startLine, sourceFile);
var nonWhitespaceColumn =
i === 0
? nonWhitespaceColumnInFirstPart
: SmartIndenter.findFirstNonWhitespaceColumn(parts[i].pos, parts[i].end, sourceFile, options);
var newIndentation = nonWhitespaceColumn + delta;
if (newIndentation > 0) {
var indentationString = getIndentationString(newIndentation, options);
recordReplace(startLinePos, nonWhitespaceColumn, indentationString);
}
else {
recordDelete(startLinePos, nonWhitespaceColumn);
}
}
}
function processTrivia(trivia: TextRangeWithKind[], parent: Node, contextNode: Node, currentIndentation: number): void {
for (var i = 0, len = trivia.length; i < len; ++i) {
var triviaItem = trivia[i];

View File

@ -65,41 +65,7 @@ module ts.formatting {
return 0;
}
var parent: Node = current.parent;
var parentStart: LineAndCharacter;
// walk upwards and collect indentations for pairs of parent-child nodes
// indentation is not added if parent and child nodes start on the same line or if parent is IfStatement and child starts on the same line with 'else clause'
while (parent) {
// check if current node is a list item - if yes, take indentation from it
var actualIndentation = getActualIndentationForListItem(current, sourceFile, options);
if (actualIndentation !== -1) {
return actualIndentation + indentationDelta;
}
parentStart = sourceFile.getLineAndCharacterFromPosition(parent.getStart(sourceFile));
var parentAndChildShareLine =
parentStart.line === currentStart.line ||
childStartsOnTheSameLineWithElseInIfStatement(parent, current, currentStart.line, sourceFile);
// try to fetch actual indentation for current node from source text
var actualIndentation = getActualIndentationForNode(current, parent, currentStart, parentAndChildShareLine, sourceFile, options);
if (actualIndentation !== -1) {
return actualIndentation + indentationDelta;
}
// increase indentation if parent node wants its content to be indented and parent and child nodes don't start on the same line
if (nodeContentIsIndented(parent, current) && !parentAndChildShareLine) {
indentationDelta += options.IndentSize;
}
current = parent;
currentStart = parentStart;
parent = current.parent;
}
return indentationDelta;
return getIndentationForNode(current, currentStart, indentationDelta, sourceFile, options);
}
export function getIndentationForNode(current: Node, currentStart: LineAndCharacter, indentationDelta: number, sourceFile: SourceFile, options: EditorOptions): number {
@ -287,21 +253,24 @@ module ts.formatting {
function findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter: LineAndCharacter, sourceFile: SourceFile, options: EditorOptions): number {
var lineStart = sourceFile.getPositionFromLineAndCharacter(lineAndCharacter.line, 1);
return findFirstNonWhitespaceColumn(lineStart, lineStart + lineAndCharacter.character, sourceFile, options);
}
export function findFirstNonWhitespaceColumn(startPos: number, endPos: number, sourceFile: SourceFile, options: EditorOptions): number {
var column = 0;
for (var i = 0; i < lineAndCharacter.character; ++i) {
var charCode = sourceFile.text.charCodeAt(lineStart + i);
if (!isWhiteSpace(charCode)) {
for (var pos = startPos; pos < endPos; ++pos) {
var ch = sourceFile.text.charCodeAt(pos);
if (!isWhiteSpace(ch)) {
return column;
}
if (charCode === CharacterCodes.tab) {
column += options.TabSize;
if (ch === CharacterCodes.tab) {
column += options.TabSize + (column % options.TabSize);
}
else {
column++;
}
}
return column;
}

View File

@ -24,19 +24,21 @@ module ts.formatting {
}
else {
var spacesString: string;
var index = indentation / options.IndentSize;
var quotient = Math.floor(indentation / options.IndentSize);
var remainder = indentation % options.IndentSize;
if (!internedSpacesIndentation) {
internedSpacesIndentation = [];
}
if (internedSpacesIndentation[index] === undefined) {
internedSpacesIndentation[index] = spacesString = repeat(" ", indentation);;
if (internedSpacesIndentation[quotient] === undefined) {
spacesString = repeat(" ", options.IndentSize * quotient);
internedSpacesIndentation[quotient] = spacesString;
}
else {
spacesString = internedSpacesIndentation[index];
spacesString = internedSpacesIndentation[quotient];
}
var remainder = indentation % options.IndentSize;
return remainder ? spacesString + repeat(" ", remainder) : spacesString;
}