Flattened 'ts.OutliningElementsCollector' to a single declaration.
This commit is contained in:
parent
f9eb330b19
commit
51933a231f
1 changed files with 143 additions and 145 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue