internal static bool TryGetSyntax <TSyntax>( SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, SignatureHelpTriggerReason triggerReason, Func <SyntaxToken, bool> isTriggerToken, Func <TSyntax, SyntaxToken, bool> isArgumentListToken, CancellationToken cancellationToken, out TSyntax expression ) where TSyntax : SyntaxNode { var token = syntaxFacts.FindTokenOnLeftOfPosition(root, position); if (triggerReason == SignatureHelpTriggerReason.TypeCharCommand) { if ( isTriggerToken(token) && !syntaxFacts.IsInNonUserCode(root.SyntaxTree, position, cancellationToken) ) { expression = token.GetAncestor <TSyntax>(); return(true); } } else if (triggerReason == SignatureHelpTriggerReason.InvokeSignatureHelpCommand) { expression = token.Parent ?.GetAncestorsOrThis <TSyntax>() .SkipWhile(syntax => !isArgumentListToken(syntax, token)) .FirstOrDefault(); return(expression != null); } else if (triggerReason == SignatureHelpTriggerReason.RetriggerCommand) { if ( !syntaxFacts.IsInNonUserCode(root.SyntaxTree, position, cancellationToken) || syntaxFacts.IsEntirelyWithinStringOrCharOrNumericLiteral( root.SyntaxTree, position, cancellationToken ) ) { expression = token.Parent ?.AncestorsAndSelf() .TakeWhile(n => !syntaxFacts.IsAnonymousFunction(n)) .OfType <TSyntax>() .SkipWhile(syntax => !isArgumentListToken(syntax, token)) .FirstOrDefault(); return(expression != null); } } expression = null; return(false); }
private Dictionary <TriviaLocation, SyntaxToken> GetTokensAtEdges(SyntaxNode root, TextSpan textSpan) { var tokens = new Dictionary <TriviaLocation, SyntaxToken>(); tokens[TriviaLocation.AfterBeginningOfSpan] = _syntaxFactsService.FindTokenOnRightOfPosition(root, textSpan.Start, includeSkipped: false); tokens[TriviaLocation.BeforeBeginningOfSpan] = tokens[TriviaLocation.AfterBeginningOfSpan].GetPreviousToken(includeZeroWidth: true); tokens[TriviaLocation.BeforeEndOfSpan] = _syntaxFactsService.FindTokenOnLeftOfPosition(root, textSpan.End, includeSkipped: false); tokens[TriviaLocation.AfterEndOfSpan] = tokens[TriviaLocation.BeforeEndOfSpan].GetNextToken(includeZeroWidth: true); return(tokens); }
internal static bool TryGetSyntax <TSyntax>( SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, SignatureHelpTriggerReason triggerReason, Func <SyntaxToken, bool> isTriggerToken, Func <TSyntax, SyntaxToken, bool> isArgumentListToken, CancellationToken cancellationToken, out TSyntax expression) where TSyntax : SyntaxNode { // Bug 1100661 reports an NRE from this method, but no manual repro has been found. To aid in debugging, // any NRE thrown from here will generate a dump via FatalError.Report() below. try/catch was added 1/2/2015 // and is expected to be removed by 4/1/2015. --brettfo try { var token = syntaxFacts.FindTokenOnLeftOfPosition(root, position); if (triggerReason == SignatureHelpTriggerReason.TypeCharCommand) { if (isTriggerToken(token)) { expression = token.GetAncestor <TSyntax>(); return(true); } } else if (triggerReason == SignatureHelpTriggerReason.InvokeSignatureHelpCommand) { expression = token.Parent.GetAncestorsOrThis <TSyntax>().SkipWhile(syntax => !isArgumentListToken(syntax, token)).FirstOrDefault(); return(expression != null); } else if (triggerReason == SignatureHelpTriggerReason.RetriggerCommand) { if (!syntaxFacts.IsInNonUserCode(root.SyntaxTree, position, cancellationToken) || syntaxFacts.IsEntirelyWithinStringOrCharLiteral(root.SyntaxTree, position, cancellationToken)) { expression = token.Parent.AncestorsAndSelf() .TakeWhile(n => !syntaxFacts.IsAnonymousFunction(n)) .OfType <TSyntax>() .SkipWhile(syntax => !isArgumentListToken(syntax, token)) .FirstOrDefault(); return(expression != null); } } expression = null; return(false); } catch (NullReferenceException e) when(FatalError.Report(e)) { throw ExceptionUtilities.Unreachable; } }
/// <summary> /// Find closest token (including one in structured trivia) left of given position /// </summary> private SyntaxToken FindTokenOnLeftOfPosition(ISyntaxFactsService syntaxFactsService, SyntaxNode root, int position) { // find token on left var token = syntaxFactsService.FindTokenOnLeftOfPosition(root, position, includeSkipped: true, includeDirectives: true, includeDocumentationComments: true); if (token.RawKind == 0) { // if there is no token on left, return the first token return(root.GetFirstToken(includeZeroWidth: true, includeSkipped: true, includeDirectives: true, includeDocumentationComments: true)); } return(token); }
/// <summary> /// Find closest token (including one in structured trivia) left of given position /// </summary> private SyntaxToken FindTokenOnLeftOfPosition(ISyntaxFactsService syntaxFactsService, SyntaxNode root, int position) { // find token on left var token = syntaxFactsService.FindTokenOnLeftOfPosition(root, position, includeSkipped: true, includeDirectives: true, includeDocumentationComments: true); if (token.RawKind == 0) { // if there is no token on left, return the first token return root.GetFirstToken(includeZeroWidth: true, includeSkipped: true, includeDirectives: true, includeDocumentationComments: true); } return token; }