Extract findListItem from smart indenter

This commit is contained in:
Jason Freeman 2014-09-16 14:36:52 -07:00
parent 63f43e8352
commit 67516a1f61
5 changed files with 36 additions and 58 deletions

View File

@ -11,10 +11,12 @@ module ts {
var result: U;
if (array) {
for (var i = 0, len = array.length; i < len; i++) {
if (result = callback(array[i])) break;
if (result = callback(array[i])) {
return result;
}
}
}
return result;
return undefined;
}
export function contains<T>(array: T[], value: T): boolean {

View File

@ -107,8 +107,10 @@ module ts.formatting {
*/
function getActualIndentationForListItemBeforeComma(commaToken: Node, sourceFile: SourceFile, options: TypeScript.FormattingOptions): number {
// previous token is comma that separates items in list - find the previous item and try to derive indentation from it
var itemInfo = findPrecedingListItem(commaToken);
return deriveActualIndentationFromList(itemInfo.list.getChildren(), itemInfo.listItemIndex, sourceFile, options);
var commaItemInfo = ServicesSyntaxUtilities.findListItemInfo(commaToken);
Debug.assert(commaItemInfo.listItemIndex > 0);
// The item we're interested in is right before the comma
return deriveActualIndentationFromList(commaItemInfo.list.getChildren(), commaItemInfo.listItemIndex - 1, sourceFile, options);
}
/*
@ -166,27 +168,6 @@ module ts.formatting {
return sourceFile.getLineAndCharacterFromPosition(n.getStart(sourceFile));
}
function findPrecedingListItem(commaToken: Node): { listItemIndex: number; list: Node } {
// CommaToken node is synthetic and thus will be stored in SyntaxList, however parent of the CommaToken points to the container of the SyntaxList skipping the list.
// In order to find the preceding list item we first need to locate SyntaxList itself and then search for the position of CommaToken
var syntaxList = forEach(commaToken.parent.getChildren(), c => {
// find syntax list that covers the span of CommaToken
if (c.kind == SyntaxKind.SyntaxList && c.pos <= commaToken.end && c.end >= commaToken.end) {
return c;
}
});
Debug.assert(syntaxList);
var children = syntaxList.getChildren();
var commaIndex = indexOf(children, commaToken);
Debug.assert(commaIndex !== -1 && commaIndex !== 0);
return {
listItemIndex: commaIndex - 1,
list: syntaxList
};
}
function positionBelongsToNode(candidate: Node, position: number, sourceFile: SourceFile): boolean {
return candidate.end > position || !isCompletedNode(candidate, sourceFile);
}

View File

@ -3495,32 +3495,13 @@ module ts {
return 0;
}
var argumentListOrTypeArgumentList: NodeArray<Node>;
if (parent.typeArguments && node.pos >= parent.typeArguments.pos && node.end <= parent.typeArguments.end) {
argumentListOrTypeArgumentList = parent.typeArguments;
}
else if (parent.arguments && node.pos >= parent.arguments.pos && node.end <= parent.arguments.end) {
argumentListOrTypeArgumentList = parent.arguments;
if (node.kind === SyntaxKind.GreaterThanToken
|| node.kind === SyntaxKind.CloseParenToken
|| node === parent.func) {
return -1;
}
return argumentListOrTypeArgumentList ? argumentListOrTypeArgumentList.indexOf(node) : -1;
// if (parent.kind === SyntaxKind.SyntaxList) {
// var grandparent = parent.parent;
// if (grandparent.kind === SyntaxKind.CallExpression || grandparent.kind === SyntaxKind.NewExpression) {
// var index = (<NodeObject>parent).getIndexOfChild(node);
// Debug.assert(index >= 0);
// return index;
// }
// }
// if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) {
// return parent.kind === SyntaxKind.CallExpression || parent.kind === SyntaxKind.NewExpression
// ? 0
// : -1;
// }
// TODO: Handle close paren or close angle bracket on nonempty list
return ServicesSyntaxUtilities.findListItemInfo(node).listItemIndex;
}
function getSignatureHelpArgumentContext(node: Node): {
@ -3532,18 +3513,11 @@ module ts {
// Otherwise we want the previous token
var isToken = node.kind < SyntaxKind.Missing;
if (!isToken || position <= node.getStart() || position >= node.getEnd()) {
// This is a temporary hack until we figure out our token story.
// The correct solution is to get the previous token
node = ServicesSyntaxUtilities.findPrecedingToken(position, sourceFile);
if (!node) {
return undefined;
}
if (node.parent.kind === SyntaxKind.CallExpression || node.parent.kind === SyntaxKind.NewExpression) {
if (node === (<CallExpression>node.parent).func) {
node = node.parent.getChildAt(1);
}
}
}
var signatureHelpAvailable = false;

View File

@ -1,5 +1,26 @@
// These utilities are common to multiple language service features.
module ts.ServicesSyntaxUtilities {
export function findListItemInfo(node: Node): { listItemIndex: number; list: Node } {
// The node might be a list element (nonsynthetic) or a comma (synthetic). Either way, it will
// be parented by the container of the SyntaxList, not the SyntaxList itself.
// In order to find the list item index, we first need to locate SyntaxList itself and then search
// for the position of the relevant node (or comma).
var syntaxList = forEach(node.parent.getChildren(), c => {
// find syntax list that covers the span of the node
if (c.kind == SyntaxKind.SyntaxList && c.pos <= node.pos && c.end >= node.end) {
return c;
}
});
var children = syntaxList.getChildren();
var index = indexOf(children, node);
return {
listItemIndex: index,
list: syntaxList
};
}
export function findNextToken(previousToken: Node, parent: Node): Node {
return find(parent);

View File

@ -1,10 +1,10 @@
/// <reference path='fourslash.ts'/>
////class clsOverload { constructor(); constructor(test: string); constructor(test?: string) { } }
////var x = new clsOverload/*beforeOpenParen*/()/*afterOpenParen*/;
////var x = new clsOverload/*beforeOpenParen*/()/*afterCloseParen*/;
goTo.marker('beforeOpenParen');
verify.not.signatureHelpPresent();
goTo.marker('afterOpenParen');
goTo.marker('afterCloseParen');
verify.not.signatureHelpPresent();