Flattened 'ts.OutliningElementsCollector' to a single declaration.

This commit is contained in:
Daniel Rosenwasser 2015-12-28 17:00:36 -05:00
parent f9eb330b19
commit 51933a231f

View file

@ -1,181 +1,179 @@
/* @internal */ /* @internal */
namespace ts { namespace ts.OutliningElementsCollector {
export namespace OutliningElementsCollector { export function collectElements(sourceFile: SourceFile): OutliningSpan[] {
export function collectElements(sourceFile: SourceFile): OutliningSpan[] { const elements: OutliningSpan[] = [];
const elements: OutliningSpan[] = []; const collapseText = "...";
const collapseText = "...";
function addOutliningSpan(hintSpanNode: Node, startElement: Node, endElement: Node, autoCollapse: boolean) { function addOutliningSpan(hintSpanNode: Node, startElement: Node, endElement: Node, autoCollapse: boolean) {
if (hintSpanNode && startElement && endElement) { if (hintSpanNode && startElement && endElement) {
const span: OutliningSpan = { const span: OutliningSpan = {
textSpan: createTextSpanFromBounds(startElement.pos, endElement.end), textSpan: createTextSpanFromBounds(startElement.pos, endElement.end),
hintSpan: createTextSpanFromBounds(hintSpanNode.getStart(), hintSpanNode.end), hintSpan: createTextSpanFromBounds(hintSpanNode.getStart(), hintSpanNode.end),
bannerText: collapseText, bannerText: collapseText,
autoCollapse: autoCollapse autoCollapse: autoCollapse
}; };
elements.push(span); elements.push(span);
}
} }
}
function addOutliningSpanComments(commentSpan: CommentRange, autoCollapse: boolean) { function addOutliningSpanComments(commentSpan: CommentRange, autoCollapse: boolean) {
if (commentSpan) { if (commentSpan) {
const span: OutliningSpan = { const span: OutliningSpan = {
textSpan: createTextSpanFromBounds(commentSpan.pos, commentSpan.end), textSpan: createTextSpanFromBounds(commentSpan.pos, commentSpan.end),
hintSpan: createTextSpanFromBounds(commentSpan.pos, commentSpan.end), hintSpan: createTextSpanFromBounds(commentSpan.pos, commentSpan.end),
bannerText: collapseText, bannerText: collapseText,
autoCollapse: autoCollapse autoCollapse: autoCollapse
}; };
elements.push(span); elements.push(span);
}
} }
}
function addOutliningForLeadingCommentsForNode(n: Node) { function addOutliningForLeadingCommentsForNode(n: Node) {
const comments = ts.getLeadingCommentRangesOfNode(n, sourceFile); const comments = ts.getLeadingCommentRangesOfNode(n, sourceFile);
if (comments) { if (comments) {
let firstSingleLineCommentStart = -1; let firstSingleLineCommentStart = -1;
let lastSingleLineCommentEnd = -1; let lastSingleLineCommentEnd = -1;
let isFirstSingleLineComment = true; let isFirstSingleLineComment = true;
let singleLineCommentCount = 0; let singleLineCommentCount = 0;
for (const currentComment of comments) { for (const currentComment of comments) {
// For single line comments, combine consecutive ones (2 or more) into // For single line comments, combine consecutive ones (2 or more) into
// a single span from the start of the first till the end of the last // a single span from the start of the first till the end of the last
if (currentComment.kind === SyntaxKind.SingleLineCommentTrivia) { if (currentComment.kind === SyntaxKind.SingleLineCommentTrivia) {
if (isFirstSingleLineComment) { if (isFirstSingleLineComment) {
firstSingleLineCommentStart = currentComment.pos; firstSingleLineCommentStart = currentComment.pos;
}
isFirstSingleLineComment = false;
lastSingleLineCommentEnd = currentComment.end;
singleLineCommentCount++;
}
else if (currentComment.kind === SyntaxKind.MultiLineCommentTrivia) {
combineAndAddMultipleSingleLineComments(singleLineCommentCount, firstSingleLineCommentStart, lastSingleLineCommentEnd);
addOutliningSpanComments(currentComment, /*autoCollapse*/ false);
singleLineCommentCount = 0;
lastSingleLineCommentEnd = -1;
isFirstSingleLineComment = true;
} }
isFirstSingleLineComment = false;
lastSingleLineCommentEnd = currentComment.end;
singleLineCommentCount++;
} }
else if (currentComment.kind === SyntaxKind.MultiLineCommentTrivia) {
combineAndAddMultipleSingleLineComments(singleLineCommentCount, firstSingleLineCommentStart, lastSingleLineCommentEnd);
addOutliningSpanComments(currentComment, /*autoCollapse*/ false);
combineAndAddMultipleSingleLineComments(singleLineCommentCount, firstSingleLineCommentStart, lastSingleLineCommentEnd); singleLineCommentCount = 0;
lastSingleLineCommentEnd = -1;
isFirstSingleLineComment = true;
}
} }
combineAndAddMultipleSingleLineComments(singleLineCommentCount, firstSingleLineCommentStart, lastSingleLineCommentEnd);
}
}
function combineAndAddMultipleSingleLineComments(count: number, start: number, end: number) {
// Only outline spans of two or more consecutive single line comments
if (count > 1) {
const multipleSingleLineComments = {
pos: start,
end: end,
kind: SyntaxKind.SingleLineCommentTrivia
};
addOutliningSpanComments(multipleSingleLineComments, /*autoCollapse*/ false);
}
}
function autoCollapse(node: Node) {
return isFunctionBlock(node) && node.parent.kind !== SyntaxKind.ArrowFunction;
}
let depth = 0;
const maxDepth = 20;
function walk(n: Node): void {
if (depth > maxDepth) {
return;
} }
function combineAndAddMultipleSingleLineComments(count: number, start: number, end: number) { if (isDeclaration(n)) {
addOutliningForLeadingCommentsForNode(n);
// Only outline spans of two or more consecutive single line comments
if (count > 1) {
const multipleSingleLineComments = {
pos: start,
end: end,
kind: SyntaxKind.SingleLineCommentTrivia
};
addOutliningSpanComments(multipleSingleLineComments, /*autoCollapse*/ false);
}
} }
function autoCollapse(node: Node) { switch (n.kind) {
return isFunctionBlock(node) && node.parent.kind !== SyntaxKind.ArrowFunction; case SyntaxKind.Block:
} if (!isFunctionBlock(n)) {
const parent = n.parent;
const openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile);
const closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile);
let depth = 0; // Check if the block is standalone, or 'attached' to some parent statement.
const maxDepth = 20; // If the latter, we want to collaps the block, but consider its hint span
function walk(n: Node): void { // to be the entire span of the parent.
if (depth > maxDepth) { if (parent.kind === SyntaxKind.DoStatement ||
return; parent.kind === SyntaxKind.ForInStatement ||
} parent.kind === SyntaxKind.ForOfStatement ||
parent.kind === SyntaxKind.ForStatement ||
parent.kind === SyntaxKind.IfStatement ||
parent.kind === SyntaxKind.WhileStatement ||
parent.kind === SyntaxKind.WithStatement ||
parent.kind === SyntaxKind.CatchClause) {
if (isDeclaration(n)) { addOutliningSpan(parent, openBrace, closeBrace, autoCollapse(n));
addOutliningForLeadingCommentsForNode(n); break;
} }
switch (n.kind) {
case SyntaxKind.Block:
if (!isFunctionBlock(n)) {
const parent = n.parent;
const openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile);
const closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile);
// Check if the block is standalone, or 'attached' to some parent statement.
// If the latter, we want to collaps the block, but consider its hint span
// to be the entire span of the parent.
if (parent.kind === SyntaxKind.DoStatement ||
parent.kind === SyntaxKind.ForInStatement ||
parent.kind === SyntaxKind.ForOfStatement ||
parent.kind === SyntaxKind.ForStatement ||
parent.kind === SyntaxKind.IfStatement ||
parent.kind === SyntaxKind.WhileStatement ||
parent.kind === SyntaxKind.WithStatement ||
parent.kind === SyntaxKind.CatchClause) {
if (parent.kind === SyntaxKind.TryStatement) {
// Could be the try-block, or the finally-block.
const tryStatement = <TryStatement>parent;
if (tryStatement.tryBlock === n) {
addOutliningSpan(parent, openBrace, closeBrace, autoCollapse(n)); addOutliningSpan(parent, openBrace, closeBrace, autoCollapse(n));
break; break;
} }
else if (tryStatement.finallyBlock === n) {
if (parent.kind === SyntaxKind.TryStatement) { const finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile);
// Could be the try-block, or the finally-block. if (finallyKeyword) {
const tryStatement = <TryStatement>parent; addOutliningSpan(finallyKeyword, openBrace, closeBrace, autoCollapse(n));
if (tryStatement.tryBlock === n) {
addOutliningSpan(parent, openBrace, closeBrace, autoCollapse(n));
break; break;
} }
else if (tryStatement.finallyBlock === n) {
const finallyKeyword = findChildOfKind(tryStatement, SyntaxKind.FinallyKeyword, sourceFile);
if (finallyKeyword) {
addOutliningSpan(finallyKeyword, openBrace, closeBrace, autoCollapse(n));
break;
}
}
// fall through.
} }
// Block was a standalone block. In this case we want to only collapse // fall through.
// the span of the block, independent of any parent span.
const span = createTextSpanFromBounds(n.getStart(), n.end);
elements.push({
textSpan: span,
hintSpan: span,
bannerText: collapseText,
autoCollapse: autoCollapse(n)
});
break;
} }
// Fallthrough.
case SyntaxKind.ModuleBlock: { // Block was a standalone block. In this case we want to only collapse
const openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); // the span of the block, independent of any parent span.
const closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); const span = createTextSpanFromBounds(n.getStart(), n.end);
addOutliningSpan(n.parent, openBrace, closeBrace, autoCollapse(n)); elements.push({
textSpan: span,
hintSpan: span,
bannerText: collapseText,
autoCollapse: autoCollapse(n)
});
break; break;
} }
case SyntaxKind.ClassDeclaration: // Fallthrough.
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.EnumDeclaration: case SyntaxKind.ModuleBlock: {
case SyntaxKind.ObjectLiteralExpression: const openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile);
case SyntaxKind.CaseBlock: { const closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile);
const openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); addOutliningSpan(n.parent, openBrace, closeBrace, autoCollapse(n));
const closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); break;
addOutliningSpan(n, openBrace, closeBrace, autoCollapse(n));
break;
}
case SyntaxKind.ArrayLiteralExpression:
const openBracket = findChildOfKind(n, SyntaxKind.OpenBracketToken, sourceFile);
const closeBracket = findChildOfKind(n, SyntaxKind.CloseBracketToken, sourceFile);
addOutliningSpan(n, openBracket, closeBracket, autoCollapse(n));
break;
} }
depth++; case SyntaxKind.ClassDeclaration:
forEachChild(n, walk); case SyntaxKind.InterfaceDeclaration:
depth--; case SyntaxKind.EnumDeclaration:
case SyntaxKind.ObjectLiteralExpression:
case SyntaxKind.CaseBlock: {
const openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile);
const closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile);
addOutliningSpan(n, openBrace, closeBrace, autoCollapse(n));
break;
}
case SyntaxKind.ArrayLiteralExpression:
const openBracket = findChildOfKind(n, SyntaxKind.OpenBracketToken, sourceFile);
const closeBracket = findChildOfKind(n, SyntaxKind.CloseBracketToken, sourceFile);
addOutliningSpan(n, openBracket, closeBracket, autoCollapse(n));
break;
} }
depth++;
walk(sourceFile); forEachChild(n, walk);
return elements; depth--;
} }
walk(sourceFile);
return elements;
} }
} }