public static ParseTreeNode GetTargetAtTriggerPoint(ITrackingPoint triggerPoint, ITextSnapshot snapshot, ParseTree parseTree) { Contract.Requires(snapshot != null); Contract.Requires(parseTree != null); Contract.Requires(triggerPoint != null); //Can we get our position? var pos = triggerPoint.Convert(snapshot); if (pos == default(Position)) { return(null); } //Can we get our leaf node? var leafNode = parseTree.FindLeafNode(pos); if (leafNode == null) { return(null); } var asPropDecl = leafNode.AsProperty(); if (asPropDecl != null) { return(asPropDecl); } //Is our leaf node a name? var asName = leafNode.AsAnyName(); if (asName == null) { return(null); } //Is anyone in our ancestry a call node? var nodeInQuestion = leafNode; var lastNonBinaryOperatorNode = leafNode; var lastNode = leafNode; while (nodeInQuestion != null) { //Is the node in question a node call? var asCall = nodeInQuestion.AsAnyCall(); if (asCall != null) { //Make sure we aren't on the right side of the call if (asCall.Right == lastNode) { return(null); } return(asCall); } var asProp = nodeInQuestion.AsDot(); if (asProp != null) { //Make sure we aren't on the left side of the dot if (asProp.Right == lastNode && asProp.Right.IsName()) { return(asProp); } } var asCtorCall = nodeInQuestion.AsAnyCreation(); if (asCtorCall != null) { return(asCtorCall); } var declNode = nodeInQuestion.AsAnyMember(); if (declNode != null) { if (lastNode == leafNode) { return(declNode); } return(null); } NamedAssignmentNode na = nodeInQuestion as NamedAssignmentNode; if (na != null) { if (na.Identifier == asName) { return(na); } } //Is our parent a binary operator? var asBinaryOperator = nodeInQuestion.AsAnyBinaryOperator(); if (asBinaryOperator != null) { //Make sure we are always on the rightmost of any binary operator if (asBinaryOperator.Right != lastNonBinaryOperatorNode) { return(null); } } else { lastNonBinaryOperatorNode = nodeInQuestion; } //Climp higher up our ancestry for the next iteration lastNode = nodeInQuestion; nodeInQuestion = nodeInQuestion.Parent; } //Did we successfully find a call node? if (nodeInQuestion == null) { return(null); } if (nodeInQuestion.Kind != NodeKind.Call) { return(null); } var callNode = nodeInQuestion.AsAnyCall(); return(callNode); }
public static SyntaxNode GetTargetAtTriggerPoint(ITrackingPoint triggerPoint, ITextSnapshot snapshot, SyntaxTree parseTree) { Contract.Requires(snapshot != null); Contract.Requires(parseTree != null); Contract.Requires(triggerPoint != null); SyntaxNode syntaxRoot; if (!parseTree.TryGetRoot(out syntaxRoot)) { return(null); } var leafToken = syntaxRoot.FindToken(triggerPoint.GetPosition(snapshot), false); if (leafToken.IsKind(SyntaxKind.None)) { return(null); } var leafNode = leafToken.Parent; var asPropDecl = leafNode as PropertyDeclarationSyntax; if (asPropDecl != null) { return(asPropDecl); } //Is our leaf node a name? var asName = leafNode as IdentifierNameSyntax; if (asName == null) { return(null); } //Is anyone in our ancestry a call node? var nodeInQuestion = leafNode; var lastNonBinaryOperatorNode = leafNode; var lastNode = leafNode; while (nodeInQuestion != null) { //Is the node in question a node call? var asCall = nodeInQuestion as InvocationExpressionSyntax; if (asCall != null) { //Make sure we aren't on the right side of the call if (asCall.Expression == leafNode) { return(asCall); } MemberAccessExpressionSyntax memberAccessExpression = asCall.Expression as MemberAccessExpressionSyntax; if (memberAccessExpression != null && memberAccessExpression.Name == leafNode) { return(asCall); } GenericNameSyntax genericNameSyntax = asCall.Expression as GenericNameSyntax; if (genericNameSyntax != null && genericNameSyntax.Identifier == leafToken) { return(asCall); } return(null); } var asProp = nodeInQuestion as MemberAccessExpressionSyntax; if (asProp != null) { //Make sure we aren't on the left side of the dot if (asProp.Name == lastNode && asProp.Name is IdentifierNameSyntax) { return(asProp); } } var asCtorCall = nodeInQuestion as ObjectCreationExpressionSyntax; if (asCtorCall != null) { return(asCtorCall); } var declNode = nodeInQuestion as MemberDeclarationSyntax; if (declNode != null) { if (lastNode == leafNode) { return(declNode); } return(null); } #warning What exactly is this doing? #if false NamedAssignmentNode na = nodeInQuestion as NamedAssignmentNode; if (na != null) { if (na.Identifier == asName) { return(na); } } #endif //Is our parent a binary operator? var asBinaryOperator = nodeInQuestion as BinaryExpressionSyntax; if (asBinaryOperator != null) { //Make sure we are always on the rightmost of any binary operator if (asBinaryOperator.Right != lastNonBinaryOperatorNode) { return(null); } } else { lastNonBinaryOperatorNode = nodeInQuestion; } //Climb higher up our ancestry for the next iteration lastNode = nodeInQuestion; nodeInQuestion = nodeInQuestion.Parent; } //Did we successfully find a call node? if (nodeInQuestion == null) { return(null); } if (nodeInQuestion.Kind() != SyntaxKind.InvocationExpression) { return(null); } var callNode = nodeInQuestion as InvocationExpressionSyntax; return(callNode); }