protected override AbstractIndenter GetIndenter( ISyntaxFactsService syntaxFacts, SyntaxTree syntaxTree, TextLine lineToBeIndented, IEnumerable<IFormattingRule> formattingRules, OptionSet optionSet, CancellationToken cancellationToken) { return new Indenter( syntaxFacts, syntaxTree, formattingRules, optionSet, lineToBeIndented, cancellationToken); }
public GenerateTypeOptionsResult GetGenerateTypeOptions( string className, GenerateTypeDialogOptions generateTypeDialogOptions, Document document, INotificationService notificationService, IProjectManagementService projectManagementService, ISyntaxFactsService syntaxFactsService) { // Storing the actual values ClassName = className; GenerateTypeDialogOptions = generateTypeDialogOptions; if (DefaultNamespace == null) { DefaultNamespace = projectManagementService.GetDefaultNamespace(Project, Project?.Solution.Workspace); } return new GenerateTypeOptionsResult( accessibility: Accessibility, typeKind: TypeKind, typeName: TypeName, project: Project, isNewFile: IsNewFile, newFileName: NewFileName, folders: Folders, fullFilePath: FullFilePath, existingDocument: ExistingDocument, areFoldersValidIdentifiers: AreFoldersValidIdentifiers, defaultNamespace: DefaultNamespace, isCancelled: IsCancelled); }
public override SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken) { if (GetOuterMostTupleExpressionInSpan(root, position, syntaxFacts, currentSpan, cancellationToken, out var expression)) { return CommonSignatureHelpUtilities.GetSignatureHelpState(expression, position, getOpenToken: s_getOpenToken, getCloseToken: s_getCloseToken, getArgumentsWithSeparators: s_getArgumentsWithSeparators, getArgumentNames: s_getArgumentNames); } if (GetOuterMostParenthesizedExpressionInSpan(root, position, syntaxFacts, currentSpan, cancellationToken, out var parenthesizedExpression)) { if (currentSpan.Start == parenthesizedExpression.SpanStart) { return new SignatureHelpState( argumentIndex: 0, argumentCount: 0, argumentName: string.Empty, argumentNames: null); } } return null; }
protected static bool TryGetNameWithoutAttributeSuffix( string name, ISyntaxFactsService syntaxFacts, out string result) { return name.TryGetWithoutAttributeSuffix(syntaxFacts.IsCaseSensitive, out result); }
public AbstractIndenter( ISyntaxFactsService syntaxFacts, SyntaxTree syntaxTree, IEnumerable<IFormattingRule> rules, OptionSet optionSet, TextLine lineToBeIndented, CancellationToken cancellationToken) { var syntaxRoot = syntaxTree.GetRoot(cancellationToken); this._syntaxFacts = syntaxFacts; this.OptionSet = optionSet; this.Tree = syntaxTree; this.LineToBeIndented = lineToBeIndented; this.TabSize = this.OptionSet.GetOption(FormattingOptions.TabSize, syntaxRoot.Language); this.CancellationToken = cancellationToken; this.Rules = rules; this.Finder = new BottomUpBaseIndentationFinder( new ChainedFormattingRules(this.Rules, OptionSet), this.TabSize, this.OptionSet.GetOption(FormattingOptions.IndentationSize, syntaxRoot.Language), tokenStream: null, lastToken: default(SyntaxToken)); }
private bool TryGetConstructorInitializer(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, SignatureHelpTriggerReason triggerReason, CancellationToken cancellationToken, out ConstructorInitializerSyntax expression) { if (!CommonSignatureHelpUtilities.TryGetSyntax(root, position, syntaxFacts, triggerReason, IsTriggerToken, IsArgumentListToken, cancellationToken, out expression)) { return false; } return expression.ArgumentList != null; }
protected AbstractTokenBraceCompletionSession( ISyntaxFactsService syntaxFactsService, int openingTokenKind, int closingTokenKind) { _syntaxFactsService = syntaxFactsService; this.OpeningTokenKind = openingTokenKind; this.ClosingTokenKind = closingTokenKind; }
private bool TryGetAttributeExpression(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, SignatureHelpTriggerReason triggerReason, CancellationToken cancellationToken, out AttributeSyntax attribute) { if (!CommonSignatureHelpUtilities.TryGetSyntax(root, position, syntaxFacts, triggerReason, IsTriggerToken, IsArgumentListToken, cancellationToken, out attribute)) { return false; } return attribute.ArgumentList != null; }
/// <summary> /// Returns the identifier, keyword, contextual keyword or preprocessor keyword touching this /// position, or a token of Kind = None if the caret is not touching either. /// </summary> public static Task<SyntaxToken> GetTouchingWordAsync( this SyntaxTree syntaxTree, int position, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken, bool findInsideTrivia = false) { return GetTouchingTokenAsync(syntaxTree, position, syntaxFacts.IsWord, cancellationToken, findInsideTrivia); }
private SymbolMapBuilder( ISyntaxFactsService service, SemanticModel semanticModel, TextSpan span, CancellationToken cancellationToken) : base(SyntaxWalkerDepth.Token) { _semanticModel = semanticModel; _service = service; _span = span; _symbolMap = new Dictionary<ISymbol, List<SyntaxToken>>(); _cancellationToken = cancellationToken; }
public GenerateTypeOptionsResult GetGenerateTypeOptions( string typeName, GenerateTypeDialogOptions generateTypeDialogOptions, Document document, INotificationService notificationService, IProjectManagementService projectManagementService, ISyntaxFactsService syntaxFactsService) { var viewModel = new GenerateTypeDialogViewModel( document, notificationService, projectManagementService, syntaxFactsService, _generatedCodeService, generateTypeDialogOptions, typeName, document.Project.Language == LanguageNames.CSharp ? ".cs" : ".vb", _isNewFile, _accessSelectString, _typeKindSelectString); var dialog = new GenerateTypeDialog(viewModel); var result = dialog.ShowModal(); if (result.HasValue && result.Value) { // Retain choice _isNewFile = viewModel.IsNewFile; _accessSelectString = viewModel.SelectedAccessibilityString; _typeKindSelectString = viewModel.SelectedTypeKindString; var defaultNamespace = projectManagementService.GetDefaultNamespace(viewModel.SelectedProject, viewModel.SelectedProject?.Solution.Workspace); return new GenerateTypeOptionsResult( accessibility: viewModel.SelectedAccessibility, typeKind: viewModel.SelectedTypeKind, typeName: viewModel.TypeName, project: viewModel.SelectedProject, isNewFile: viewModel.IsNewFile, newFileName: viewModel.FileName.Trim(), folders: viewModel.Folders, fullFilePath: viewModel.FullFilePath, existingDocument: viewModel.SelectedDocument, defaultNamespace: defaultNamespace, areFoldersValidIdentifiers: viewModel.AreFoldersValidIdentifiers); } else { return GenerateTypeOptionsResult.Cancelled; } }
public static IEnumerable<SyntaxToken> GetIdentifierOrGlobalNamespaceTokensWithText( ISyntaxFactsService syntaxFacts, Document document, VersionStamp version, SemanticModel model, SyntaxNode root, SourceText sourceText, string text, CancellationToken cancellationToken) { var normalized = syntaxFacts.IsCaseSensitive ? text : text.ToLowerInvariant(); var entry = GetCachedEntry(model); if (entry == null) { return GetIdentifierOrGlobalNamespaceTokensWithText(syntaxFacts, document, version, root, sourceText, normalized, cancellationToken); } return entry.IdentifierCache.GetOrAdd(normalized, key => GetIdentifierOrGlobalNamespaceTokensWithText(syntaxFacts, document, version, root, sourceText, key, cancellationToken)); }
public override SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken) { if (TryGetObjectCreationExpression( root, position, syntaxFacts, SignatureHelpTriggerReason.InvokeSignatureHelpCommand, cancellationToken, out var expression) && currentSpan.Start == SignatureHelpUtilities.GetSignatureHelpSpan(expression.ArgumentList).Start) { return SignatureHelpUtilities.GetSignatureHelpState(expression.ArgumentList, position); } return null; }
public static Dictionary<ISymbol, List<SyntaxToken>> Build( ISyntaxFactsService service, SemanticModel semanticModel, SyntaxNode root, TextSpan span, CancellationToken cancellationToken) { Contract.ThrowIfNull(semanticModel); Contract.ThrowIfNull(service); Contract.ThrowIfNull(root); var builder = new SymbolMapBuilder(service, semanticModel, span, cancellationToken); builder.Visit(root); return builder._symbolMap; }
public ExtractInterfaceOptionsResult GetExtractInterfaceOptions(ISyntaxFactsService syntaxFactsService, INotificationService notificationService, List<ISymbol> extractableMembers, string defaultInterfaceName, List<string> conflictingTypeNames, string defaultNamespace, string generatedNameTypeParameterSuffix, string languageName) { var viewModel = new ExtractInterfaceDialogViewModel(syntaxFactsService, defaultInterfaceName, extractableMembers, conflictingTypeNames, defaultNamespace, generatedNameTypeParameterSuffix, languageName, languageName == LanguageNames.CSharp ? ".cs" : ".vb"); var dialog = new ExtractInterfaceDialog(viewModel); dialog.SetOwnerToActive(); var options = dialog.ShowDialog() == true ? new ExtractInterfaceOptionsResult( isCancelled: false, includedMembers: viewModel.MemberContainers.Where(c => c.IsChecked).Select(c => c.MemberSymbol), interfaceName: viewModel.InterfaceName.Trim(), fileName: viewModel.FileName.Trim()) : ExtractInterfaceOptionsResult.Cancelled; return options; }
private static ImmutableArray<SyntaxToken> GetIdentifierOrGlobalNamespaceTokensWithText( ISyntaxFactsService syntaxFacts, Document document, VersionStamp version, SyntaxNode root, SourceText sourceText, string text, CancellationToken cancellationToken) { Func<SyntaxToken, bool> candidate = t => syntaxFacts.IsGlobalNamespaceKeyword(t) || (syntaxFacts.IsIdentifier(t) && syntaxFacts.TextMatch(t.ValueText, text)); // identifier is not escaped if (sourceText != null) { return GetTokensFromText(syntaxFacts, document, version, root, sourceText, text, candidate, cancellationToken); } // identifier is escaped return root.DescendantTokens(descendIntoTrivia: true).Where(candidate).ToImmutableArray(); }
private bool GetOuterMostParenthesizedExpressionInSpan(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken, out ParenthesizedExpressionSyntax result) { result = null; while (TryGetParenthesizedExpression(SignatureHelpTriggerReason.InvokeSignatureHelpCommand, root, position, syntaxFacts, cancellationToken, out var expression)) { if (!currentSpan.Contains(expression.Span)) { break; } result = expression; position = expression.SpanStart; } return result != null; }
protected virtual bool TryGetGenericIdentifier( SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, SignatureHelpTriggerReason triggerReason, CancellationToken cancellationToken, out SyntaxToken genericIdentifier, out SyntaxToken lessThanToken) { if (CommonSignatureHelpUtilities.TryGetSyntax(root, position, syntaxFacts, triggerReason, IsTriggerToken, IsArgumentListToken, cancellationToken, out GenericNameSyntax name)) { genericIdentifier = name.Identifier; lessThanToken = name.TypeArgumentList.LessThanToken; return true; } genericIdentifier = default(SyntaxToken); lessThanToken = default(SyntaxToken); return false; }
public static IEnumerable<SyntaxToken> GetConstructorInitializerTokens( ISyntaxFactsService syntaxFacts, SemanticModel model, SyntaxNode root, CancellationToken cancellationToken) { // this one will only get called when we know given document contains constructor initializer. // no reason to use text to check whether it exist first. var entry = GetCachedEntry(model); if (entry == null) { return GetConstructorInitializerTokens(syntaxFacts, root, cancellationToken); } if (entry.ConstructorInitializerCache == null) { var initializers = GetConstructorInitializerTokens(syntaxFacts, root, cancellationToken); Interlocked.CompareExchange(ref entry.ConstructorInitializerCache, initializers, null); } return entry.ConstructorInitializerCache; }
public ExtractInterfaceOptionsResult GetExtractInterfaceOptions( ISyntaxFactsService syntaxFactsService, INotificationService notificationService, List<ISymbol> extractableMembers, string defaultInterfaceName, List<string> allTypeNames, string defaultNamespace, string generatedNameTypeParameterSuffix, string languageName) { var viewModel = new ExtractInterfaceDialogViewModel( syntaxFactsService, _glyphService, notificationService, defaultInterfaceName, extractableMembers, allTypeNames, defaultNamespace, generatedNameTypeParameterSuffix, languageName, languageName == LanguageNames.CSharp ? ".cs" : ".vb"); var dialog = new ExtractInterfaceDialog(viewModel); var result = dialog.ShowModal(); if (result.HasValue && result.Value) { return new ExtractInterfaceOptionsResult( isCancelled: false, includedMembers: viewModel.MemberContainers.Where(c => c.IsChecked).Select(c => c.MemberSymbol), interfaceName: viewModel.InterfaceName.Trim(), fileName: viewModel.FileName.Trim()); } else { return ExtractInterfaceOptionsResult.Cancelled; } }
public ExtractInterfaceOptionsResult GetExtractInterfaceOptions( ISyntaxFactsService syntaxFactsService, INotificationService notificationService, List<ISymbol> extractableMembers, string defaultInterfaceName, List<string> conflictingTypeNames, string defaultNamespace, string generatedNameTypeParameterSuffix, string languageName) { this.AllExtractableMembers = extractableMembers; this.DefaultInterfaceName = defaultInterfaceName; this.ConflictingTypeNames = conflictingTypeNames; this.DefaultNamespace = defaultNamespace; this.GeneratedNameTypeParameterSuffix = generatedNameTypeParameterSuffix; return IsCancelled ? ExtractInterfaceOptionsResult.Cancelled : new ExtractInterfaceOptionsResult( isCancelled: false, includedMembers: ChosenMembers ?? AllExtractableMembers, interfaceName: ChosenInterfaceName ?? defaultInterfaceName, fileName: ChosenFileName ?? defaultInterfaceName); }
internal ExtractInterfaceDialogViewModel( ISyntaxFactsService syntaxFactsService, IGlyphService glyphService, INotificationService notificationService, string defaultInterfaceName, List<ISymbol> extractableMembers, List<string> conflictingTypeNames, string defaultNamespace, string generatedNameTypeParameterSuffix, string languageName, string fileExtension) { _syntaxFactsService = syntaxFactsService; _notificationService = notificationService; _interfaceName = defaultInterfaceName; _conflictingTypeNames = conflictingTypeNames; _fileExtension = fileExtension; _fileName = string.Format("{0}{1}", defaultInterfaceName, fileExtension); _defaultNamespace = defaultNamespace; _generatedNameTypeParameterSuffix = generatedNameTypeParameterSuffix; _languageName = languageName; MemberContainers = extractableMembers.Select(m => new MemberSymbolViewModel(m, glyphService)).OrderBy(s => s.MemberName).ToList(); }
private static void CalculateContext(SyntaxNode node, ISyntaxFactsService syntaxFacts, out string name, out int arity, out bool inAttributeContext, out bool hasIncompleteParentMember) { // Has to be a simple identifier or generic name. syntaxFacts.GetNameAndArityOfSimpleName(node, out name, out arity); inAttributeContext = syntaxFacts.IsAttributeName(node); hasIncompleteParentMember = syntaxFacts.HasIncompleteParentMember(node); }
internal abstract bool IsViableField(IFieldSymbol field, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken);
internal abstract bool IsViableProperty(IPropertySymbol property, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken);
private static async Task <bool> CanBeMergedAsync( Document document, ISyntaxFactsService syntaxFacts, IIfLikeStatementGenerator ifGenerator, SyntaxNode outerIfOrElseIf, SyntaxNode innerIfStatement, CancellationToken cancellationToken) { // We can only merge this with the outer if statement if any inner else-if and else clauses are equal // to else-if and else clauses following the outer if statement because we'll be removing the inner ones. // Example of what we can merge: // if (a) // { // if (b) // Console.WriteLine(); // else // Foo(); // } // else // { // Foo(); // } if (!System.Linq.ImmutableArrayExtensions.SequenceEqual( ifGenerator.GetElseIfAndElseClauses(outerIfOrElseIf), ifGenerator.GetElseIfAndElseClauses(innerIfStatement), (a, b) => IsElseIfOrElseClauseEquivalent(syntaxFacts, ifGenerator, a, b))) { return(false); } var statements = syntaxFacts.GetStatementContainerStatements(innerIfStatement.Parent); if (statements.Count == 1) { // There are no other statements below the inner if statement. Merging is OK. return(true); } else { // There are statements below the inner if statement. We can merge if // 1. there are equivalent statements below the outer 'if', and // 2. control flow can't reach the end of these statements (otherwise, it would continue // below the outer 'if' and run the same statements twice). // This will typically look like a single return, break, continue or a throw statement. // The opposite refactoring (SplitIntoNestedIfStatements) never generates this but we support it anyway. // Example: // if (a) // { // if (b) // Console.WriteLine(); // return; // } // return; // If we have an else-if, get the topmost if statement. var outerIfStatement = ifGenerator.GetRootIfStatement(outerIfOrElseIf); // A statement should always be in a statement container, but we'll do a defensive check anyway so that // we don't crash if the helper is missing some cases or there's a new language feature it didn't account for. Debug.Assert(syntaxFacts.GetStatementContainer(outerIfStatement) is object); if (syntaxFacts.GetStatementContainer(outerIfStatement) is not { } container) { return(false); } var outerStatements = syntaxFacts.GetStatementContainerStatements(container); var outerIfStatementIndex = outerStatements.IndexOf(outerIfStatement); var remainingStatements = statements.Skip(1); var remainingOuterStatements = outerStatements.Skip(outerIfStatementIndex + 1); if (!remainingStatements.SequenceEqual(remainingOuterStatements.Take(statements.Count - 1), syntaxFacts.AreEquivalent)) { return(false); } var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var controlFlow = semanticModel.AnalyzeControlFlow(statements[0], statements[statements.Count - 1]); return(!controlFlow.EndPointIsReachable); } }
protected static bool ParentIsSkippedTokensTriviaOrNull(ISyntaxFactsService syntaxFactsService, SyntaxToken token) => token.Parent == null || syntaxFactsService.IsSkippedTokensTrivia(token.Parent);
private IEnumerable <IGrouping <SyntaxNode, Diagnostic> > GetDiagnosticsGroupedByMember( ImmutableArray <Diagnostic> diagnostics, ISyntaxFactsService syntaxFacts, SyntaxNode root) => diagnostics.GroupBy(d => syntaxFacts.GetContainingMemberDeclaration(root, d.Location.SourceSpan.Start));
protected AbstractDocumentationCommentService(ISyntaxFactsService syntaxFacts) { _syntaxFacts = syntaxFacts; }
protected override bool CanAddImportForMethod(Diagnostic diagnostic, ISyntaxFactsService syntaxFacts, ref SyntaxNode node) { switch (diagnostic.Id) { case CS1061: if (node.IsKind(SyntaxKind.ConditionalAccessExpression)) { node = (node as ConditionalAccessExpressionSyntax).WhenNotNull; } else if (node.IsKind(SyntaxKind.MemberBindingExpression)) { node = (node as MemberBindingExpressionSyntax).Name; } else if (node.Parent.IsKind(SyntaxKind.CollectionInitializerExpression)) { return(true); } break; case CS0122: case CS1501: if (node is SimpleNameSyntax) { break; } else if (node is MemberBindingExpressionSyntax) { node = (node as MemberBindingExpressionSyntax).Name; } break; case CS1929: var memberAccessName = (node.Parent as MemberAccessExpressionSyntax)?.Name; var conditionalAccessName = (((node.Parent as ConditionalAccessExpressionSyntax)?.WhenNotNull as InvocationExpressionSyntax)?.Expression as MemberBindingExpressionSyntax)?.Name; if (memberAccessName == null && conditionalAccessName == null) { return(false); } node = memberAccessName ?? conditionalAccessName; break; case CS1503: //// look up its corresponding method name var parent = node.GetAncestor <InvocationExpressionSyntax>(); if (parent == null) { return(false); } var method = parent.Expression as MemberAccessExpressionSyntax; if (method != null) { node = method.Name; } break; default: return(false); } var simpleName = node as SimpleNameSyntax; if (!simpleName.IsParentKind(SyntaxKind.SimpleMemberAccessExpression) && !simpleName.IsParentKind(SyntaxKind.MemberBindingExpression)) { return(false); } var memberAccess = simpleName.Parent as MemberAccessExpressionSyntax; var memberBinding = simpleName.Parent as MemberBindingExpressionSyntax; if (memberAccess.IsParentKind(SyntaxKind.SimpleMemberAccessExpression) || memberAccess.IsParentKind(SyntaxKind.ElementAccessExpression) || memberBinding.IsParentKind(SyntaxKind.SimpleMemberAccessExpression) || memberBinding.IsParentKind(SyntaxKind.ElementAccessExpression)) { return(false); } if (!syntaxFacts.IsMemberAccessExpressionName(node)) { return(false); } return(true); }
/// <summary> /// Try to get a new node to replace given node, which is a reference to a top-level type declared inside the /// namespce to be changed. If this reference is the right side of a qualified name, the new node returned would /// be the entire qualified name. Depends on whether <paramref name="newNamespaceParts"/> is provided, the name /// in the new node might be qualified with this new namespace instead. /// </summary> /// <param name="reference">A reference to a type declared inside the namespce to be changed, which is calculated /// based on results from `SymbolFinder.FindReferencesAsync`.</param> /// <param name="newNamespaceParts">If specified, the namespace of original reference will be replaced with given /// namespace in the replacement node.</param> /// <param name="old">The node to be replaced. This might be an ancestor of original </param> /// <param name="new">The replacement node.</param> public abstract bool TryGetReplacementReferenceSyntax(SyntaxNode reference, ImmutableArray <string> newNamespaceParts, ISyntaxFactsService syntaxFacts, out SyntaxNode old, out SyntaxNode @new);
private static void MoveCaretToSemicolonPosition( TypeCharCommandArgs args, Document document, SyntaxNode root, SnapshotPoint caret, ISyntaxFactsService syntaxFacts, SyntaxNode currentNode, bool isInsideDelimiters, CancellationToken cancellationToken) { if (currentNode == null || IsInAStringOrCharacter(currentNode, caret)) { // Don't complete statement. Return without moving the caret. return; } if (currentNode.IsKind(SyntaxKind.ArgumentList, SyntaxKind.ArrayRankSpecifier, SyntaxKind.BracketedArgumentList, SyntaxKind.ParenthesizedExpression, SyntaxKind.ParameterList)) { // make sure the closing delimiter exists if (RequiredDelimiterIsMissing(currentNode)) { return; } // set caret to just outside the delimited span and analyze again // if caret was already in that position, return to avoid infinite loop var newCaretPosition = currentNode.Span.End; if (newCaretPosition == caret.Position) { return; } var newCaret = args.SubjectBuffer.CurrentSnapshot.GetPoint(newCaretPosition); if (!TryGetStartingNode(root, newCaret, out currentNode, cancellationToken)) { return; } MoveCaretToSemicolonPosition(args, document, root, newCaret, syntaxFacts, currentNode, isInsideDelimiters: true, cancellationToken); } else if (currentNode.IsKind(SyntaxKind.DoStatement)) { if (IsInConditionOfDoStatement(currentNode, caret)) { MoveCaretToFinalPositionInStatement(currentNode, args, caret, true); } return; } else if (syntaxFacts.IsStatement(currentNode) || currentNode.IsKind(SyntaxKind.FieldDeclaration, SyntaxKind.DelegateDeclaration)) { MoveCaretToFinalPositionInStatement(currentNode, args, caret, isInsideDelimiters); return; } else { // keep caret the same, but continue analyzing with the parent of the current node currentNode = currentNode.Parent; MoveCaretToSemicolonPosition(args, document, root, caret, syntaxFacts, currentNode, isInsideDelimiters, cancellationToken); return; } }
public CharLiteralCompletionSession(ISyntaxFactsService syntaxFactsService) : base(syntaxFactsService, (int)SyntaxKind.CharacterLiteralToken, (int)SyntaxKind.CharacterLiteralToken, Braces.SingleQuote.OpenCharacter, Braces.SingleQuote.CloseCharacter) { }
private void RemoveAwaitFromCallerIfPresent( SyntaxEditor editor, ISyntaxFactsService syntaxFacts, SyntaxNode root, ReferenceLocation referenceLocation, CancellationToken cancellationToken) { if (referenceLocation.IsImplicit) { return; } var location = referenceLocation.Location; var token = location.FindToken(cancellationToken); var nameNode = token.Parent; if (nameNode == null) { return; } // Look for the following forms: // await M(...) // await <expr>.M(...) // await M(...).ConfigureAwait(...) // await <expr>.M(...).ConfigureAwait(...) var expressionNode = nameNode; if (syntaxFacts.IsNameOfMemberAccessExpression(nameNode)) { expressionNode = nameNode.Parent; } if (!syntaxFacts.IsExpressionOfInvocationExpression(expressionNode)) { return; } // We now either have M(...) or <expr>.M(...) var invocationExpression = expressionNode.Parent; Debug.Assert(syntaxFacts.IsInvocationExpression(invocationExpression)); if (syntaxFacts.IsExpressionOfAwaitExpression(invocationExpression)) { // Handle the case where we're directly awaited. var awaitExpression = invocationExpression.Parent; editor.ReplaceNode(awaitExpression, (currentAwaitExpression, generator) => syntaxFacts.GetExpressionOfAwaitExpression(currentAwaitExpression) .WithTriviaFrom(currentAwaitExpression)); } else if (syntaxFacts.IsExpressionOfMemberAccessExpression(invocationExpression)) { // Check for the .ConfigureAwait case. var parentMemberAccessExpression = invocationExpression.Parent; var parentMemberAccessExpressionNameNode = syntaxFacts.GetNameOfMemberAccessExpression( parentMemberAccessExpression); var parentMemberAccessExpressionName = syntaxFacts.GetIdentifierOfSimpleName(parentMemberAccessExpressionNameNode).ValueText; if (parentMemberAccessExpressionName == nameof(Task.ConfigureAwait)) { var parentExpression = parentMemberAccessExpression.Parent; if (syntaxFacts.IsExpressionOfAwaitExpression(parentExpression)) { var awaitExpression = parentExpression.Parent; editor.ReplaceNode(awaitExpression, (currentAwaitExpression, generator) => { var currentConfigureAwaitInvocation = syntaxFacts.GetExpressionOfAwaitExpression(currentAwaitExpression); var currentMemberAccess = syntaxFacts.GetExpressionOfInvocationExpression(currentConfigureAwaitInvocation); var currentInvocationExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(currentMemberAccess); return(currentInvocationExpression.WithTriviaFrom(currentAwaitExpression)); }); } } } }
public override SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken) { if (TryGetObjectCreationExpression( root, position, syntaxFacts, SignatureHelpTriggerReason.InvokeSignatureHelpCommand, cancellationToken, out var expression) && currentSpan.Start == SignatureHelpUtilities.GetSignatureHelpSpan(expression.ArgumentList).Start) { return(SignatureHelpUtilities.GetSignatureHelpState(expression.ArgumentList, position)); } return(null); }
public abstract SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken);
private bool IsTrackableCharacter(ISyntaxFactsService syntaxFactsService, char c) { // Allow identifier part characters at the beginning of strings (even if they are // not identifier start characters). If an intermediate name is not valid, the smart // tag will not be shown due to later checks. Also allow escape chars anywhere as // they might be in the middle of a complex edit. return syntaxFactsService.IsIdentifierPartCharacter(c) || syntaxFactsService.IsIdentifierEscapeCharacter(c); }
public static void GetPartsOfAssignmentStatement( this ISyntaxFactsService syntaxFacts, SyntaxNode statement, out SyntaxNode left, out SyntaxNode right) { syntaxFacts.GetPartsOfAssignmentStatement(statement, out left, out _, out right); }
internal override bool IsViableProperty(IPropertySymbol property, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken) { return(IsViablePropertyOrField(property, expression, semanticModel, syntaxFacts, cancellationToken)); }
public static bool IsAnyMemberAccessExpression( this ISyntaxFactsService syntaxFacts, SyntaxNode node) { return(syntaxFacts.IsSimpleMemberAccessExpression(node) || syntaxFacts.IsPointerMemberAccessExpression(node)); }
public static bool IsWhitespaceOrEndOfLineTrivia(this ISyntaxFactsService syntaxFacts, SyntaxTrivia trivia) { return(syntaxFacts.IsWhitespaceTrivia(trivia) || syntaxFacts.IsEndOfLineTrivia(trivia)); }
private bool IsViablePropertyOrField(ISymbol propertyOrField, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken) { if (!propertyOrField.IsStatic) { return(false); } var leftName = (expression as MemberAccessExpressionSyntax)?.Expression as SimpleNameSyntax; if (leftName == null) { return(false); } return(StringComparer.Ordinal.Compare(propertyOrField.ContainingType.Name, leftName.Identifier.Text) == 0); }
public static bool IsRegularOrDocumentationComment(this ISyntaxFactsService syntaxFacts, SyntaxTrivia trivia) => syntaxFacts.IsRegularComment(trivia) || syntaxFacts.IsDocumentationComment(trivia);
private static SyntaxNode GetContainer(SemanticModel semanticModel, SyntaxNode parameterNode, ISyntaxFactsService syntaxFactsService) { for (var current = parameterNode; current != null; current = current.Parent) { var declaredSymbol = semanticModel.GetDeclaredSymbol(current); if (declaredSymbol is IMethodSymbol method && method.MethodKind != MethodKind.AnonymousFunction) { return(current); } } return(syntaxFactsService.GetContainingVariableDeclaratorOfFieldDeclaration(parameterNode)); }
/// <summary> /// Try to get a new node to replace given node, which is a reference to a top-level type declared inside the /// namespace to be changed. If this reference is the right side of a qualified name, the new node returned would /// be the entire qualified name. Depends on whether <paramref name="newNamespaceParts"/> is provided, the name /// in the new node might be qualified with this new namespace instead. /// </summary> /// <param name="reference">A reference to a type declared inside the namespace to be changed, which is calculated /// based on results from `SymbolFinder.FindReferencesAsync`.</param> /// <param name="newNamespaceParts">If specified, the namespace of original reference will be replaced with given /// namespace in the replacement node.</param> /// <param name="old">The node to be replaced. This might be an ancestor of original </param> /// <param name="new">The replacement node.</param> public abstract bool TryGetReplacementReferenceSyntax(SyntaxNode reference, ImmutableArray <string> newNamespaceParts, ISyntaxFactsService syntaxFacts, [NotNullWhen(returnValue: true)] out SyntaxNode?old, [NotNullWhen(returnValue: true)] out SyntaxNode? @new);
private string TryGetText(SyntaxToken token, SemanticModel semanticModel, Document document, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken) { if (TryGetTextForSpecialCharacters(token, out var text) || TryGetTextForContextualKeyword(token, out text) || TryGetTextForCombinationKeyword(token, syntaxFacts, out text) || TryGetTextForKeyword(token, syntaxFacts, out text) || TryGetTextForPreProcessor(token, syntaxFacts, out text) || TryGetTextForOperator(token, document, out text) || TryGetTextForSymbol(token, semanticModel, document, cancellationToken, out text)) { return(text); } return(string.Empty); }
public CurlyBraceCompletionSession(ISyntaxFactsService syntaxFactsService, ISmartIndentationService smartIndentationService, ITextBufferUndoManagerProvider undoManager) : base(syntaxFactsService, (int)SyntaxKind.OpenBraceToken, (int)SyntaxKind.CloseBraceToken) { _smartIndentationService = smartIndentationService; _undoManager = undoManager; }
private static bool MatchesPattern(ISyntaxFactsService syntaxFacts, SyntaxNode node1, SyntaxNode node2) => syntaxFacts.IsNullLiteralExpression(syntaxFacts.GetExpressionOfArgument(node1)) && !syntaxFacts.IsNullLiteralExpression(syntaxFacts.GetExpressionOfArgument(node2));
protected override bool CanAddImportForGetAwaiter(string diagnosticId, ISyntaxFactsService syntaxFactsService, SyntaxNode node) => (diagnosticId == CS1061 || // Regular cases diagnosticId == CS4036 || // WinRT async interfaces diagnosticId == CS1929) && // An extension `GetAwaiter()` is in scope, but for another type AncestorOrSelfIsAwaitExpression(syntaxFactsService, node);
public MoveToNamespaceOptionsResult GetChangeNamespaceOptions(string defaultNamespace, ImmutableArray <string> availableNamespaces, ISyntaxFactsService syntaxFactsService) => _optionsResult;
private async Task<IEnumerable<IMethodSymbol>> GetAddMethodsAsync( Project project, Diagnostic diagnostic, SyntaxNode node, SemanticModel semanticModel, ISet<INamespaceSymbol> namespacesInScope, ISyntaxFactsService syntaxFacts, SyntaxNode expression, CancellationToken cancellationToken) { string name; int arity; syntaxFacts.GetNameAndArityOfSimpleName(node, out name, out arity); if (name != null) { return SpecializedCollections.EmptyEnumerable<IMethodSymbol>(); } if (IsAddMethodContext(node, semanticModel)) { var symbols = await SymbolFinder.FindDeclarationsAsync(project, "Add", this.IgnoreCase, SymbolFilter.Member, cancellationToken).ConfigureAwait(false); return symbols .OfType<IMethodSymbol>() .Where(method => method.IsExtensionMethod && method.ContainingType?.IsAccessibleWithin(semanticModel.Compilation.Assembly) == true && IsViableExtensionMethod(method, expression, semanticModel, syntaxFacts, cancellationToken)); } return SpecializedCollections.EmptyEnumerable<IMethodSymbol>(); }
static SyntaxNode TryGetAcceptedNodeOrExtracted(SyntaxNode node, Predicate <SyntaxNode> predicate, Func <SyntaxNode, ISyntaxFactsService, SyntaxNode> extractNode, ISyntaxFactsService syntaxFacts) { if (node == null) { return(null); } if (predicate(node)) { return(node); } var extractedNode = extractNode(node, syntaxFacts); return((extractedNode != null && predicate(extractedNode)) ? extractedNode : null); }
private IEnumerable<INamespaceSymbol> FilterForExtensionMethods(SemanticModel semanticModel, ISet<INamespaceSymbol> namespacesInScope, ISyntaxFactsService syntaxFacts, SyntaxNode expression, IEnumerable<ISymbol> symbols, CancellationToken cancellationToken) { var extensionMethodSymbols = symbols .OfType<IMethodSymbol>() .Where(method => method.IsExtensionMethod && method.ContainingType?.IsAccessibleWithin(semanticModel.Compilation.Assembly) == true && IsViableExtensionMethod(method, expression, semanticModel, syntaxFacts, cancellationToken)) .ToList(); return GetProposedNamespaces( extensionMethodSymbols.Select(s => s.ContainingNamespace), semanticModel, namespacesInScope); }
protected abstract Func <SyntaxToken, bool> GetTokensMatchFunction(ISyntaxFactsService syntaxFacts, string name);
/// <summary> /// Gets the replacement node for a compound assignment expression whose /// assigned value is redundant. /// For example, "x += MethodCall()", where assignment to 'x' is redundant /// is replaced with "_ = MethodCall()" or "var unused = MethodCall()" /// </summary> protected abstract SyntaxNode GetReplacementNodeForCompoundAssignment( SyntaxNode originalCompoundAssignment, SyntaxNode newAssignmentTarget, SyntaxEditor editor, ISyntaxFactsService syntaxFacts);
private async Task FixAllValueAssignedIsUnusedDiagnosticsAsync( IOrderedEnumerable <Diagnostic> diagnostics, Document document, SemanticModel semanticModel, SyntaxNode root, SyntaxNode containingMemberDeclaration, UnusedValuePreference preference, bool removeAssignments, UniqueVariableNameGenerator nameGenerator, SyntaxEditor editor, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken) { // This method applies the code fix for diagnostics reported for unused value assignments to local/parameter. // The actual code fix depends on whether or not the right hand side of the assignment has side effects. // For example, if the right hand side is a constant or a reference to a local/parameter, then it has no side effects. // The lack of side effects is indicated by the "removeAssignments" parameter for this function. // If the right hand side has no side effects, then we can replace the assignments with variable declarations that have no initializer // or completely remove the statement. // If the right hand side does have side effects, we replace the identifier token for unused value assignment with // a new identifier token (either discard '_' or new unused local variable name). // For both the above cases, if the original diagnostic was reported on a local declaration, i.e. redundant initialization // at declaration, then we also add a new variable declaration statement without initializer for this local. using var _1 = PooledDictionary <SyntaxNode, SyntaxNode> .GetInstance(out var nodeReplacementMap); using var _2 = PooledHashSet <SyntaxNode> .GetInstance(out var nodesToRemove); using var _3 = PooledHashSet <(TLocalDeclarationStatementSyntax declarationStatement, SyntaxNode node)> .GetInstance(out var nodesToAdd); // Indicates if the node's trivia was processed. using var _4 = PooledHashSet <SyntaxNode> .GetInstance(out var processedNodes); using var _5 = PooledHashSet <TLocalDeclarationStatementSyntax> .GetInstance(out var candidateDeclarationStatementsForRemoval); var hasAnyUnusedLocalAssignment = false; foreach (var(node, isUnusedLocalAssignment) in GetNodesToFix()) { hasAnyUnusedLocalAssignment |= isUnusedLocalAssignment; var declaredLocal = semanticModel.GetDeclaredSymbol(node, cancellationToken) as ILocalSymbol; if (declaredLocal == null && node.Parent is TCatchStatementSyntax) { declaredLocal = semanticModel.GetDeclaredSymbol(node.Parent, cancellationToken) as ILocalSymbol; } string newLocalNameOpt = null; if (removeAssignments) { // Removable assignment or initialization, such that right hand side has no side effects. if (declaredLocal != null) { // Redundant initialization. // For example, "int a = 0;" var variableDeclarator = node.FirstAncestorOrSelf <TVariableDeclaratorSyntax>(); Debug.Assert(variableDeclarator != null); nodesToRemove.Add(variableDeclarator); // Local declaration statement containing the declarator might be a candidate for removal if all its variables get marked for removal. var candidate = GetCandidateLocalDeclarationForRemoval(variableDeclarator); if (candidate != null) { candidateDeclarationStatementsForRemoval.Add(candidate); } } else { // Redundant assignment or increment/decrement. if (syntaxFacts.IsOperandOfIncrementOrDecrementExpression(node)) { // For example, C# increment operation "a++;" Debug.Assert(node.Parent.Parent is TExpressionStatementSyntax); nodesToRemove.Add(node.Parent.Parent); } else { Debug.Assert(syntaxFacts.IsLeftSideOfAnyAssignment(node)); if (node.Parent is TStatementSyntax) { // For example, VB simple assignment statement "a = 0" nodesToRemove.Add(node.Parent); } else if (node.Parent is TExpressionSyntax && node.Parent.Parent is TExpressionStatementSyntax) { // For example, C# simple assignment statement "a = 0;" nodesToRemove.Add(node.Parent.Parent); } else { // For example, C# nested assignment statement "a = b = 0;", where assignment to 'b' is redundant. // We replace the node with "a = 0;" nodeReplacementMap.Add(node.Parent, syntaxFacts.GetRightHandSideOfAssignment(node.Parent)); } } } } else { // Value initialization/assignment where the right hand side may have side effects, // and hence needs to be preserved in fixed code. // For example, "x = MethodCall();" is replaced with "_ = MethodCall();" or "var unused = MethodCall();" // Replace the flagged variable's indentifier token with new named, based on user's preference. var newNameToken = preference == UnusedValuePreference.DiscardVariable ? document.GetRequiredLanguageService <SyntaxGeneratorInternal>().Identifier(AbstractRemoveUnusedParametersAndValuesDiagnosticAnalyzer.DiscardVariableName) : nameGenerator.GenerateUniqueNameAtSpanStart(node); newLocalNameOpt = newNameToken.ValueText; var newNameNode = TryUpdateNameForFlaggedNode(node, newNameToken); if (newNameNode == null) { continue; } // Is this is compound assignment? if (syntaxFacts.IsLeftSideOfAnyAssignment(node) && !syntaxFacts.IsLeftSideOfAssignment(node)) { // Compound assignment is changed to simple assignment. // For example, "x += MethodCall();", where assignment to 'x' is redundant // is replaced with "_ = MethodCall();" or "var unused = MethodCall();" nodeReplacementMap.Add(node.Parent, GetReplacementNodeForCompoundAssignment(node.Parent, newNameNode, editor, syntaxFacts)); } else { nodeReplacementMap.Add(node, newNameNode); } } if (declaredLocal != null) { // We have a dead initialization for a local declaration. // Introduce a new local declaration statement without an initializer for this local. var declarationStatement = CreateLocalDeclarationStatement(declaredLocal.Type, declaredLocal.Name); if (isUnusedLocalAssignment) { declarationStatement = declarationStatement.WithAdditionalAnnotations(s_unusedLocalDeclarationAnnotation); } nodesToAdd.Add((declarationStatement, node)); } else { // We have a dead assignment to a local/parameter, which is not at the declaration site. // Create a new local declaration for the unused local if both following conditions are met: // 1. User prefers unused local variables for unused value assignment AND // 2. Assignment value has side effects and hence cannot be removed. if (preference == UnusedValuePreference.UnusedLocalVariable && !removeAssignments) { var type = semanticModel.GetTypeInfo(node, cancellationToken).Type; Debug.Assert(type != null); Debug.Assert(newLocalNameOpt != null); var declarationStatement = CreateLocalDeclarationStatement(type, newLocalNameOpt); nodesToAdd.Add((declarationStatement, node)); } } } // Process candidate declaration statements for removal. foreach (var localDeclarationStatement in candidateDeclarationStatementsForRemoval) { // If all the variable declarators for the local declaration statement are being removed, // we can remove the entire local declaration statement. if (ShouldRemoveStatement(localDeclarationStatement, out var variables)) { nodesToRemove.Add(localDeclarationStatement); nodesToRemove.RemoveRange(variables); } } foreach (var(declarationStatement, node) in nodesToAdd) { InsertLocalDeclarationStatement(declarationStatement, node); } if (hasAnyUnusedLocalAssignment) { // Local declaration statements with no initializer, but non-zero references are candidates for removal // if the code fix removes all these references. // We annotate such declaration statements with no initializer abd non-zero references here // and remove them in post process document pass later, if the code fix did remove all these references. foreach (var localDeclarationStatement in containingMemberDeclaration.DescendantNodes().OfType <TLocalDeclarationStatementSyntax>()) { var variables = syntaxFacts.GetVariablesOfLocalDeclarationStatement(localDeclarationStatement); if (variables.Count == 1 && syntaxFacts.GetInitializerOfVariableDeclarator(variables[0]) == null && !(await IsLocalDeclarationWithNoReferencesAsync(localDeclarationStatement, document, cancellationToken).ConfigureAwait(false))) { nodeReplacementMap.Add(localDeclarationStatement, localDeclarationStatement.WithAdditionalAnnotations(s_existingLocalDeclarationWithoutInitializerAnnotation)); } } } foreach (var node in nodesToRemove) { var removeOptions = SyntaxGenerator.DefaultRemoveOptions; // If the leading trivia was not added to a new node, process it now. if (!processedNodes.Contains(node)) { // Don't keep trivia if the node is part of a multiple declaration statement. // e.g. int x = 0, y = 0, z = 0; any white space left behind can cause problems if the declaration gets split apart. var containingDeclaration = node.GetAncestor <TLocalDeclarationStatementSyntax>(); if (containingDeclaration != null && candidateDeclarationStatementsForRemoval.Contains(containingDeclaration)) { removeOptions = SyntaxRemoveOptions.KeepNoTrivia; } else { removeOptions |= SyntaxRemoveOptions.KeepLeadingTrivia; } } editor.RemoveNode(node, removeOptions); } foreach (var kvp in nodeReplacementMap) { editor.ReplaceNode(kvp.Key, kvp.Value.WithAdditionalAnnotations(Formatter.Annotation)); } return; // Local functions. IEnumerable <(SyntaxNode node, bool isUnusedLocalAssignment)> GetNodesToFix() { foreach (var diagnostic in diagnostics) { var node = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); var isUnusedLocalAssignment = AbstractRemoveUnusedParametersAndValuesDiagnosticAnalyzer.GetIsUnusedLocalDiagnostic(diagnostic); yield return(node, isUnusedLocalAssignment); } } // Mark generated local declaration statement with: // 1. "s_newLocalDeclarationAnnotation" for post processing in "MoveNewLocalDeclarationsNearReference" below. // 2. Simplifier annotation so that 'var'/explicit type is correctly added based on user options. TLocalDeclarationStatementSyntax CreateLocalDeclarationStatement(ITypeSymbol type, string name) => (TLocalDeclarationStatementSyntax)editor.Generator.LocalDeclarationStatement(type, name) .WithLeadingTrivia(syntaxFacts.ElasticCarriageReturnLineFeed) .WithAdditionalAnnotations(s_newLocalDeclarationStatementAnnotation, Simplifier.Annotation); void InsertLocalDeclarationStatement(TLocalDeclarationStatementSyntax declarationStatement, SyntaxNode node) { // Find the correct place to insert the given declaration statement based on the node's ancestors. var insertionNode = node.FirstAncestorOrSelf <SyntaxNode, ISyntaxFactsService>((n, syntaxFacts) => n.Parent is TSwitchCaseBlockSyntax || syntaxFacts.IsExecutableBlock(n.Parent) && !(n is TCatchStatementSyntax) && !(n is TCatchBlockSyntax), syntaxFacts); if (insertionNode is TSwitchCaseLabelOrClauseSyntax) { InsertAtStartOfSwitchCaseBlockForDeclarationInCaseLabelOrClause(insertionNode.GetAncestor <TSwitchCaseBlockSyntax>(), editor, declarationStatement); } else if (insertionNode is TStatementSyntax) { // If the insertion node is being removed, keep the leading trivia with the new declaration. if (nodesToRemove.Contains(insertionNode) && !processedNodes.Contains(insertionNode)) { declarationStatement = declarationStatement.WithLeadingTrivia(insertionNode.GetLeadingTrivia()); // Mark the node as processed so that the trivia only gets added once. processedNodes.Add(insertionNode); } editor.InsertBefore(insertionNode, declarationStatement); } } bool ShouldRemoveStatement(TLocalDeclarationStatementSyntax localDeclarationStatement, out SeparatedSyntaxList <SyntaxNode> variables) { Debug.Assert(removeAssignments); Debug.Assert(localDeclarationStatement != null); // We should remove the entire local declaration statement if all its variables are marked for removal. variables = syntaxFacts.GetVariablesOfLocalDeclarationStatement(localDeclarationStatement); foreach (var variable in variables) { if (!nodesToRemove.Contains(variable)) { return(false); } } return(true); } }
private bool TryGetSyntaxFactsService(out ISyntaxFactsService syntaxFactsService) { // Can be called on a background thread syntaxFactsService = null; var document = _buffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges(); if (document != null) { syntaxFactsService = document.Project.LanguageServices.GetService<ISyntaxFactsService>(); } return syntaxFactsService != null; }
protected override bool IsViableExtensionMethod(IMethodSymbol method, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken) { var leftExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(expression); if (leftExpression == null) { if (expression.IsKind(SyntaxKind.CollectionInitializerExpression)) { leftExpression = expression.GetAncestor <ObjectCreationExpressionSyntax>(); } else { return(false); } } var semanticInfo = semanticModel.GetTypeInfo(leftExpression, cancellationToken); var leftExpressionType = semanticInfo.Type; return(leftExpressionType != null && method.ReduceExtensionMethod(leftExpressionType) != null); }
internal bool CanInvokeRename( ISyntaxFactsService syntaxFactsService, IRenameTrackingLanguageHeuristicsService languageHeuristicsService, bool isSmartTagCheck, bool waitForResult, CancellationToken cancellationToken) { if (IsRenamableIdentifier(_isRenamableIdentifierTask, waitForResult, cancellationToken)) { var isRenamingDeclaration = _isRenamableIdentifierTask.Result == TriggerIdentifierKind.RenamableDeclaration; var newName = TrackingSpan.GetText(TrackingSpan.TextBuffer.CurrentSnapshot); var comparison = isRenamingDeclaration || syntaxFactsService.IsCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; if (!string.Equals(OriginalName, newName, comparison) && syntaxFactsService.IsValidIdentifier(newName) && languageHeuristicsService.IsIdentifierValidForRenameTracking(newName)) { // At this point, we want to allow renaming if the user invoked Ctrl+. explicitly, but we // want to avoid showing a smart tag if we're renaming a reference that binds to an existing // symbol. if (!isSmartTagCheck || isRenamingDeclaration || !NewIdentifierDefinitelyBindsToReference()) { return true; } } } return false; }
public EmbeddedLanguageInfo(int stringLiteralTokenKind, int interpolatedTextTokenKind, ISyntaxFactsService syntaxFacts, ISemanticFactsService semanticFacts, IVirtualCharService virtualCharService) { StringLiteralTokenKind = stringLiteralTokenKind; InterpolatedTextTokenKind = interpolatedTextTokenKind; SyntaxFacts = syntaxFacts; SemanticFacts = semanticFacts; VirtualCharService = virtualCharService; }