private static SyntaxNode RemoveCall(SyntaxNode root, InvocationExpressionSyntax castInvocation, MemberAccessExpressionSyntax memberAccess) { return castInvocation != null ? RemoveExtensionMethodCall(root, castInvocation) : RemoveStaticMemberCall(root, memberAccess); }
public bool ShouldUseTap(MemberAccessExpressionSyntax memberAccessExpression) { if (memberAccessExpression.IsWrappedInAwaitExpression() || memberAccessExpression.IsWrappedInLock()) { return false; } var identifierName = memberAccessExpression.Name as IdentifierNameSyntax; if (identifierName?.Identifier.ValueText != nameof(Task<int>.Result)) { return false; } var lambdaExpression = memberAccessExpression.FirstAncestorOrSelf<LambdaExpressionSyntax>(); if (lambdaExpression == null) { var methodDeclaration = memberAccessExpression.FirstAncestorOrSelf<MethodDeclarationSyntax>(); if (methodDeclaration == null || methodDeclaration.HasOutOrRefParameters()) { return false; } } var symbol = FindSymbol(memberAccessExpression.Expression); if (symbol == null) { return false; } var taskSymbol = semanticModel.Compilation.GetTypeByMetadataName(typeof(Task).FullName); var taskOfTSymbol = semanticModel.Compilation.GetTypeByMetadataName(typeof(Task).FullName + "`1"); return symbol.IsGenericType ? symbol.ConstructedFrom.Equals(taskOfTSymbol) : symbol.Equals(taskSymbol); }
public override void VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { base.VisitMemberAccessExpression(node); if (node.Parent is MemberAccessExpressionSyntax || node.Parent is InvocationExpressionSyntax) return; if (node.Expression.IsKind(SyntaxKind.ThisExpression)) Check(node); }
static SyntaxNode ToStaticMethodInvocation(SemanticModel model, InvocationExpressionSyntax invocation, MemberAccessExpressionSyntax memberAccess, SymbolInfo invocationRR) { var newArgumentList = invocation.ArgumentList.Arguments.ToList(); newArgumentList.Insert(0, SyntaxFactory.Argument(memberAccess.Expression.WithoutLeadingTrivia())); var newTarget = memberAccess.WithExpression(SyntaxFactory.ParseTypeName(invocationRR.Symbol.ContainingType.ToMinimalDisplayString(model, memberAccess.SpanStart))); return SyntaxFactory.InvocationExpression(newTarget, SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList<ArgumentSyntax>(newArgumentList))); }
private static bool IsInvocationOfApply(MemberAccessExpressionSyntax memberAccessSyntax, string bindingSetIdentifierString) { var identifierName = memberAccessSyntax.Expression as IdentifierNameSyntax; if (identifierName?.Identifier.ValueText != bindingSetIdentifierString) return false; return memberAccessSyntax.Name.Identifier.ValueText == "Apply"; }
private static bool IsInvocationOfBind(MemberAccessExpressionSyntax memberAccessSyntax, string bindingSetIdentifierString) { var identifierName = GetIdentifierRecursive(memberAccessSyntax); if (identifierName?.Identifier.ValueText != bindingSetIdentifierString) return false; return memberAccessSyntax.Name.Identifier.ValueText == "Bind"; }
public override void VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { // Dong Xie: node.Name.GetText() if (node.Name.GetText().ToString() != PublishKeyword) return; PublicationCalls.Add(node); Publications.Add(node.Ancestors().OfType<InvocationExpressionSyntax>().Last()); }
public void FixStringToCharInvocation(MemberAccessExpressionSyntax toCharArrayInvocation, Diagnostic diagnostic, CodeFixContext context, SyntaxNode root) { context.RegisterCodeFix(CodeActionFactory.Create(toCharArrayInvocation.Span, diagnostic.Severity, "Remove redundant 'string.ToCharArray()' call", token => { var newRoot = root.ReplaceNode(toCharArrayInvocation.Parent, toCharArrayInvocation.Expression .WithAdditionalAnnotations(Formatter.Annotation)); return Task.FromResult(context.Document.WithSyntaxRoot(newRoot)); }), diagnostic); }
static bool CouldBeAnAssert(MemberAccessExpressionSyntax memberAccess) { for (var i = 0; i < NUnitAssertMethods.All.Count; i++) { if (NUnitAssertMethods.All[i].CouldBeEqualto(memberAccess)) { return true; } } return false; }
private async Task<Document> InsertAsyncCall(Document document, MemberAccessExpressionSyntax memberAccess, CancellationToken cancellationToken) { var name = memberAccess.Name.Identifier.ValueText; ExpressionSyntax oldNode, newNode, newMemberAccess; switch (name) { case "WaitAny": newMemberAccess = memberAccess.WithName((SimpleNameSyntax)SyntaxFactory.ParseName("WhenAny")); break; case "WaitAll": newMemberAccess = memberAccess.WithName((SimpleNameSyntax)SyntaxFactory.ParseName("WhenAny")); break; case "Wait": newMemberAccess = memberAccess.Expression; break; case "Result": newMemberAccess = memberAccess.Expression; break; case "Sleep": newMemberAccess = SyntaxFactory.ParseExpression("Task.Delay"); break; default: newMemberAccess = memberAccess.WithName((SimpleNameSyntax)SyntaxFactory.ParseName(memberAccess.Name.Identifier.ValueText + "Async")); break; } var invoc = memberAccess.Parent as InvocationExpressionSyntax; // WaitAny, WaitAll, Wait, Sleep, XyzAsync etc. if (invoc != null) { oldNode = invoc; newNode = name == "Wait" ? newMemberAccess : invoc.WithExpression(newMemberAccess); } // t.Result else { oldNode = memberAccess; newNode = newMemberAccess; } newNode = SyntaxFactory.AwaitExpression(newNode) .WithAdditionalAnnotations(Formatter.Annotation) .WithLeadingTrivia(memberAccess.GetLeadingTrivia()) .WithTrailingTrivia(memberAccess.GetTrailingTrivia()); if (oldNode.Parent.Kind() == SyntaxKind.SimpleMemberAccessExpression) { newNode = SyntaxFactory.ParenthesizedExpression(newNode); } var root = await document.GetSyntaxRootAsync().ConfigureAwait(false); var newRoot = root.ReplaceNode(oldNode, newNode); return document.WithSyntaxRoot(newRoot); }
private bool IsPrivateField(MemberAccessExpressionSyntax memberSyntax, SemanticModel model, CancellationToken token) { var symbolInfo = model.GetSymbolInfo(memberSyntax, token); if (symbolInfo.Symbol != null && symbolInfo.Symbol.Kind == SymbolKind.Field) { var field = (IFieldSymbol)symbolInfo.Symbol; return field.DeclaredAccessibility == Accessibility.Private; } return false; }
public MemberAccessExpressionTranslation(MemberAccessExpressionSyntax syntax, SyntaxTranslation parent) : base(syntax, parent) { Expression = syntax.Expression.Get<ExpressionTranslation>(this); Name = syntax.Name.Get<SimpleNameTranslation>(this); var simpleName = Name as SimpleNameTranslation; if (simpleName != null) { simpleName.DetectApplyThis = false; } }
public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { node = (MemberAccessExpressionSyntax)base.VisitMemberAccessExpression(node); var name = node.Name.Identifier.ValueText; if (node.Expression != null && node.Expression.Kind() == SyntaxKind.ThisExpression && IsPrivateField(node)) { _addedAnnotations = true; return node.WithAdditionalAnnotations(Simplifier.Annotation); } return node; }
private bool IsPrivateField(MemberAccessExpressionSyntax memberSyntax) { if (_semanticModel == null) { _semanticModel = _document.GetSemanticModelAsync(_cancellationToken).Result; } var symbolInfo = _semanticModel.GetSymbolInfo(memberSyntax, _cancellationToken); if (symbolInfo.Symbol != null && symbolInfo.Symbol.Kind == SymbolKind.Field) { var field = (IFieldSymbol)symbolInfo.Symbol; return field.DeclaredAccessibility == Accessibility.Private; } return false; }
/// <summary> /// Determines if a MemberAccessExpressionSyntax can be fixed by our codefix /// </summary> public static bool CanFix(MemberAccessExpressionSyntax memberAccessExpression) { // Verify if it is a call to one of the methods we can fix if (!MethodNamesToRefactor.Contains(memberAccessExpression.Name.ToString())) return false; // The parent should be an InvocationExpressionSyntax var defaultIfNullexpression = memberAccessExpression.Parent as InvocationExpressionSyntax; // There should be one argument, the lambda expression if (defaultIfNullexpression?.ArgumentList.Arguments.Count != 1) return false; var lambda = GetLambdaFromFirstArgument(defaultIfNullexpression); if (lambda == null) return false; // Check if the Lambas body starts with a AccessExpression of the parameter return GetLeftMostAccessExpression(lambda) != null; }
public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { bool oldAlwaysSimplify = this.alwaysSimplify; if (!this.alwaysSimplify) { this.alwaysSimplify = node.HasAnnotation(Simplifier.Annotation); } var result = SimplifyExpression( node, newNode: base.VisitMemberAccessExpression(node), simplifier: SimplifyName); this.alwaysSimplify = oldAlwaysSimplify; return result; }
private static CompilationUnitSyntax ImportNeededNamespace(CompilationUnitSyntax root, SemanticModel semanticModel, MemberAccessExpressionSyntax callerMethod) { var symbolInfo = semanticModel.GetSymbolInfo(callerMethod.Name); var methodSymbol = symbolInfo.Symbol as IMethodSymbol; if (methodSymbol == null) return root; var namespaceDisplayString = methodSymbol.ContainingNamespace.ToDisplayString(); var hasNamespaceImported = root .DescendantNodes() .OfType<UsingDirectiveSyntax>() .Select(s => s.Name.ToString()) .Any(n => n == namespaceDisplayString); if (!hasNamespaceImported) { var namespaceQualifiedName = methodSymbol.ContainingNamespace.ToNameSyntax(); root = root.AddUsings(SyntaxFactory.UsingDirective(namespaceQualifiedName)); } return root; }
public static IMethodSymbol LookupMethodSymbol(this SemanticModel model, MemberAccessExpressionSyntax memberAccess) { if (model == null) throw new ArgumentNullException("model"); if (memberAccess == null) throw new ArgumentNullException("memberAccess"); var expression = memberAccess; Logger.Trace("Looking up symbol for: {0}", expression); var symbol = model.GetSymbolInfo(expression).Symbol; var methodSymbol = symbol as IMethodSymbol; if (methodSymbol != null) { NumMethodSymbolLookups++; return methodSymbol; } throw new MethodSymbolMissingException(memberAccess); }
public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { SyntaxNode r_node = node; if (node.IsKind(SyntaxKind.SimpleMemberAccessExpression) && node.ToString() == "ById.OnLeft") { var p = node.HasParent<ArgumentSyntax, ArgumentListSyntax, InvocationExpressionSyntax, EqualsValueClauseSyntax, VariableDeclaratorSyntax>(); if (p == null) { } else { var byId = SyntaxFactory.ParseExpression("\"#" + p.Identifier.Text + "\""); //var argById = SyntaxFactory.Argument(byId); r_node = byId; } } return r_node; }
private static async Task ConvertStringEmptyToEmptyStringLiteralAsync(RefactoringContext context, MemberAccessExpressionSyntax memberAccess) { if (ReplaceStringEmptyWithEmptyStringLiteralRefactoring.CanRefactor(memberAccess, await context.GetSemanticModelAsync().ConfigureAwait(false), context.CancellationToken)) { context.RegisterRefactoring( $"Replace '{memberAccess}' with \"\"", cancellationToken => { return(ReplaceStringEmptyWithEmptyStringLiteralRefactoring.RefactorAsync( context.Document, memberAccess, cancellationToken)); }); } else { memberAccess = (MemberAccessExpressionSyntax)memberAccess .FirstAncestor(SyntaxKind.SimpleMemberAccessExpression); if (memberAccess != null) { await ConvertStringEmptyToEmptyStringLiteralAsync(context, memberAccess).ConfigureAwait(false); } } }
public override void ExtractValues(MemberAccessExpressionSyntax node) { var invocation = (InvocationExpressionSyntax)node.Parent; Arguments = invocation.ArgumentList.Arguments; }
/// <summary> /// Initializes a new instance of the <see cref="MemberAccessExpression"/> class. /// </summary> /// <param name="syntaxNode"></param> /// <param name="semanticModel"></param> public MemberAccessExpression(MemberAccessExpressionSyntax syntaxNode, SemanticModel semanticModel) : base(syntaxNode, semanticModel) { }
public static ConditionalAccessExpressionSyntax ToConditionalAccessExpression(this MemberAccessExpressionSyntax memberAccess) { return(SyntaxFactory.ConditionalAccessExpression(memberAccess.Expression, SyntaxFactory.MemberBindingExpression(memberAccess.Name))); }
public override void VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { Visit(node.Expression); cb.Append("->"); Visit(node.Name); }
private static bool TryReduceMemberAccessExpression( MemberAccessExpressionSyntax memberAccess, SemanticModel semanticModel, out TypeSyntax replacementNode, out TextSpan issueSpan, OptionSet optionSet, CancellationToken cancellationToken) { replacementNode = null; issueSpan = default; if (memberAccess.Name == null || memberAccess.Expression == null) { return(false); } // if this node is annotated as being a SpecialType, let's use this information. if (memberAccess.HasAnnotations(SpecialTypeAnnotation.Kind)) { replacementNode = SyntaxFactory.PredefinedType( SyntaxFactory.Token( memberAccess.GetLeadingTrivia(), GetPredefinedKeywordKind(SpecialTypeAnnotation.GetSpecialType(memberAccess.GetAnnotations(SpecialTypeAnnotation.Kind).First())), memberAccess.GetTrailingTrivia())); issueSpan = memberAccess.Span; return(true); } // See https://github.com/dotnet/roslyn/issues/40974 // // To be very safe, we only support simplifying code that bound to a symbol without any // sort of problems. We could potentially relax this in the future. However, we would // need to be very careful about the implications of us offering to fixup 'broken' code // in a manner that might end up making things worse or confusing the user. var symbol = SimplificationHelpers.GetOriginalSymbolInfo(semanticModel, memberAccess); if (symbol == null) { return(false); } if (memberAccess.Expression.IsKind(SyntaxKind.ThisExpression) && !SimplificationHelpers.ShouldSimplifyThisOrMeMemberAccessExpression(semanticModel, optionSet, symbol)) { return(false); } // if this node is on the left side, we could simplify to aliases if (!memberAccess.IsRightSideOfDot()) { // Check if we need to replace this syntax with an alias identifier if (TryReplaceExpressionWithAlias( memberAccess, semanticModel, symbol, cancellationToken, out var aliasReplacement)) { // get the token text as it appears in source code to preserve e.g. unicode character escaping var text = aliasReplacement.Name; var syntaxRef = aliasReplacement.DeclaringSyntaxReferences.FirstOrDefault(); if (syntaxRef != null) { var declIdentifier = ((UsingDirectiveSyntax)syntaxRef.GetSyntax(cancellationToken)).Alias.Name.Identifier; text = declIdentifier.IsVerbatimIdentifier() ? declIdentifier.ToString().Substring(1) : declIdentifier.ToString(); } replacementNode = SyntaxFactory.IdentifierName( memberAccess.Name.Identifier.CopyAnnotationsTo(SyntaxFactory.Identifier( memberAccess.GetLeadingTrivia(), SyntaxKind.IdentifierToken, text, aliasReplacement.Name, memberAccess.GetTrailingTrivia()))); replacementNode = memberAccess.CopyAnnotationsTo(replacementNode); replacementNode = memberAccess.Name.CopyAnnotationsTo(replacementNode); issueSpan = memberAccess.Span; // In case the alias name is the same as the last name of the alias target, we only include // the left part of the name in the unnecessary span to Not confuse uses. if (memberAccess.Name.Identifier.ValueText == ((IdentifierNameSyntax)replacementNode).Identifier.ValueText) { issueSpan = memberAccess.Expression.Span; } return(true); } // Check if the Expression can be replaced by Predefined Type keyword if (PreferPredefinedTypeKeywordInMemberAccess(memberAccess, optionSet, semanticModel)) { if (symbol != null && symbol.IsKind(SymbolKind.NamedType)) { var keywordKind = GetPredefinedKeywordKind(((INamedTypeSymbol)symbol).SpecialType); if (keywordKind != SyntaxKind.None) { replacementNode = CreatePredefinedTypeSyntax(memberAccess, keywordKind); replacementNode = replacementNode .WithAdditionalAnnotations <TypeSyntax>(new SyntaxAnnotation( nameof(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInMemberAccess))); issueSpan = memberAccess.Span; // we want to show the whole expression as unnecessary return(true); } } } } // Try to eliminate cases without actually calling CanReplaceWithReducedName. For expressions of the form // 'this.Name' or 'base.Name', no additional check here is required. if (!memberAccess.Expression.IsKind(SyntaxKind.ThisExpression, SyntaxKind.BaseExpression)) { GetReplacementCandidates( semanticModel, memberAccess, symbol, out var speculativeSymbols, out var speculativeNamespacesAndTypes); if (!IsReplacementCandidate(symbol, speculativeSymbols, speculativeNamespacesAndTypes)) { return(false); } } replacementNode = memberAccess.GetNameWithTriviaMoved(); issueSpan = memberAccess.Expression.Span; return(CanReplaceWithReducedName( memberAccess, replacementNode, semanticModel, symbol, cancellationToken)); }
private static bool IsParentMemberAccess(MemberAccessExpressionSyntax parent, ExpressionSyntax node) { return parent != null && parent.Expression == node; }
internal static void ValidateMemberAccessInLinqExpression(MemberAccessExpressionSyntax node, EFCodeFirstClassInfo rootQueryableType, SyntaxNodeAnalysisContext context, Dictionary<string, ContextualLinqParameter> parameterNodes, bool treatAsWarning) { var identifier = (node.Expression as IdentifierNameSyntax); var memberName = node?.Name; if (identifier != null && memberName != null) { var identText = identifier?.Identifier.ValueText ?? string.Empty; if (!string.IsNullOrEmpty(identText) && parameterNodes.ContainsKey(identText)) { //TODO: Properties of explicit interface implementations. Does EF recognize these or not? string propName = memberName.Identifier.ValueText; if (rootQueryableType.IsReadOnly(propName)) { var diagnostic = Diagnostic.Create(treatAsWarning ? DiagnosticCodes.EFLINQ005 : DiagnosticCodes.EFLINQ002, node.GetLocation(), memberName.Identifier.ValueText, rootQueryableType.Name); context.ReportDiagnostic(diagnostic); } if (rootQueryableType.IsExplicitlyUnmapped(propName)) { var diagnostic = Diagnostic.Create(treatAsWarning ? DiagnosticCodes.EFLINQ014 : DiagnosticCodes.EFLINQ013, node.GetLocation(), memberName.Identifier.ValueText, rootQueryableType.Name); context.ReportDiagnostic(diagnostic); } } } }
protected abstract void AnalyzeMember( SyntaxNodeAnalysisContext analysisContext, string identifierValueText, MemberAccessExpressionSyntax memberAccessExpressionSyntax);
private bool IsHasValueAccess(MemberAccessExpressionSyntax memberAccess) { return(memberAccess.Name.Identifier.ValueText == HasValueLiteral && (semanticModel.GetTypeInfo(memberAccess.Expression).Type?.OriginalDefinition).Is(KnownType.System_Nullable_T)); }
private static bool IsBaseProperty(IPropertySymbol propertySymbol, SemanticModel semanticModel, MemberAccessExpressionSyntax memberAccess) { return(semanticModel.GetSymbolInfo(memberAccess).Symbol is IPropertySymbol invokedPropertySymbol && invokedPropertySymbol.Equals(propertySymbol.OverriddenProperty)); }
private static ITranslationUnit BuildMemberAccessExpressionTranslationUnit(MemberAccessExpressionSyntax expression, SemanticModel semanticModel) { var helper = new MemberAccessExpression(expression, semanticModel); //translate these Knockout-specific statements if ("SetValue".Equals(helper.MemberName) || "GetValue".Equals(helper.MemberName) || "SetItems".Equals(helper.MemberName) || "GetItems".Equals(helper.MemberName)) { return(new ExpressionTranslationUnitBuilder(expression.Expression, semanticModel).Build()); } if (expression.Expression is ThisExpressionSyntax) { return(MemberAccessExpressionTranslationUnit.Create( IdentifierTranslationUnit.Create(helper.MemberName), MemberAccessExpressionTranslationUnit.MemberAccessMethod.This)); } else if (expression.Expression is BaseExpressionSyntax) { return(MemberAccessExpressionTranslationUnit.Create( IdentifierTranslationUnit.Create(helper.MemberName), MemberAccessExpressionTranslationUnit.MemberAccessMethod.Base)); } else if (expression.Expression is IdentifierNameSyntax) { // The target is a simple identifier, the code being analysed is of the form // "command.ExecuteReader()" and memberAccess.Expression is the "command" // node return(MemberAccessExpressionTranslationUnit.Create( new ExpressionTranslationUnitBuilder(expression.Expression, semanticModel).Build(), IdentifierTranslationUnit.Create(helper.MemberName))); } else if (expression.Expression is PredefinedTypeSyntax) { // The target is a simple identifier, the code being analysed is of the form // "command.ExecuteReader()" and memberAccess.Expression is the "command" // node return(MemberAccessExpressionTranslationUnit.Create( new ExpressionTranslationUnitBuilder(expression.Expression, semanticModel).Build(), IdentifierTranslationUnit.Create(helper.MemberName))); } else if (expression.Expression is InvocationExpressionSyntax) { // The target is another invocation, the code being analysed is of the form // "GetCommand().ExecuteReader()" and memberAccess.Expression is the // "GetCommand()" node return(MemberAccessExpressionTranslationUnit.Create( new ExpressionTranslationUnitBuilder(expression.Expression, semanticModel).Build(), IdentifierTranslationUnit.Create(helper.MemberName))); } else if (expression.Expression is MemberAccessExpressionSyntax) { // The target is a member access, the code being analysed is of the form // "x.Command.ExecuteReader()" and memberAccess.Expression is the "x.Command" // node return(MemberAccessExpressionTranslationUnit.Create( new ExpressionTranslationUnitBuilder(expression.Expression, semanticModel).Build(), IdentifierTranslationUnit.Create(helper.MemberName))); } else if (expression.Expression is ElementAccessExpressionSyntax) { return(BuildElementAccessExpressionTranslationUnit((ElementAccessExpressionSyntax)expression.Expression, semanticModel)); } else if (expression.Expression is ParenthesizedExpressionSyntax) { return(MemberAccessExpressionTranslationUnit.Create( new ExpressionTranslationUnitBuilder(expression.Expression, semanticModel).Build(), IdentifierTranslationUnit.Create(helper.MemberName))); } return(MemberAccessExpressionTranslationUnit.Create( IdentifierTranslationUnit.Create(helper.MemberName), MemberAccessExpressionTranslationUnit.MemberAccessMethod.This)); }
private static void UseEmptyStringLiteralInsteadOfStringEmpty(RefactoringContext context, SemanticModel semanticModel, MemberAccessExpressionSyntax memberAccess) { while (memberAccess != null) { if (UseEmptyStringLiteralInsteadOfStringEmptyRefactoring.CanRefactor(memberAccess, semanticModel, context.CancellationToken)) { context.RegisterRefactoring( $"Use \"\" instead of '{memberAccess}'", cancellationToken => { return(UseEmptyStringLiteralInsteadOfStringEmptyRefactoring.RefactorAsync( context.Document, memberAccess, cancellationToken)); }); break; } memberAccess = (MemberAccessExpressionSyntax)memberAccess.FirstAncestor(SyntaxKind.SimpleMemberAccessExpression); } }
protected override SyntaxToken GetIdentifierToken(MemberAccessExpressionSyntax memberAccess) => analyzer.GetIdentifierToken(memberAccess);
private static bool ParserWouldTreatExpressionAsCast(ExpressionSyntax reducedNode, MemberAccessExpressionSyntax originalNode) { SyntaxNode parent = originalNode; while (parent != null) { if (parent.IsParentKind(SyntaxKind.SimpleMemberAccessExpression)) { parent = parent.Parent; continue; } if (!parent.IsParentKind(SyntaxKind.ParenthesizedExpression)) { return false; } break; } var newExpression = parent.ReplaceNode(originalNode, reducedNode); // detect cast ambiguities according to C# spec #7.7.6 if (IsNameOrMemberAccessButNoExpression(newExpression)) { var nextToken = parent.Parent.GetLastToken().GetNextToken(); return nextToken.Kind() == SyntaxKind.OpenParenToken || nextToken.Kind() == SyntaxKind.TildeToken || nextToken.Kind() == SyntaxKind.ExclamationToken || (SyntaxFacts.IsKeywordKind(nextToken.Kind()) && !(nextToken.Kind() == SyntaxKind.AsKeyword || nextToken.Kind() == SyntaxKind.IsKeyword)); } return false; }
protected override SyntaxNode GetName(MemberAccessExpressionSyntax memberAccess) => analyzer.GetName(memberAccess);
private static bool IsThisOrTypeOrNamespace(MemberAccessExpressionSyntax memberAccess, SemanticModel semanticModel) { if (memberAccess.Expression.Kind() == SyntaxKind.ThisExpression) { var previousToken = memberAccess.Expression.GetFirstToken().GetPreviousToken(); var symbol = semanticModel.GetSymbolInfo(memberAccess.Name).Symbol; if (previousToken.Kind() == SyntaxKind.OpenParenToken && previousToken.Parent.IsKind(SyntaxKind.ParenthesizedExpression) && !previousToken.Parent.IsParentKind(SyntaxKind.ParenthesizedExpression) && ((ParenthesizedExpressionSyntax)previousToken.Parent).Expression.Kind() == SyntaxKind.SimpleMemberAccessExpression && symbol != null && symbol.Kind == SymbolKind.Method) { return false; } return true; } var expressionInfo = semanticModel.GetSymbolInfo(memberAccess.Expression); if (SimplificationHelpers.IsValidSymbolInfo(expressionInfo.Symbol)) { if (expressionInfo.Symbol is INamespaceOrTypeSymbol) { return true; } if (expressionInfo.Symbol.IsThisParameter()) { return true; } } return false; }
private static bool ParserWouldTreatExpressionAsCast(ExpressionSyntax reducedNode, MemberAccessExpressionSyntax originalNode) { SyntaxNode parent = originalNode; while (parent != null) { if (parent.IsParentKind(SyntaxKind.SimpleMemberAccessExpression)) { parent = parent.Parent; continue; } if (!parent.IsParentKind(SyntaxKind.ParenthesizedExpression)) { return(false); } break; } var newExpression = parent.ReplaceNode(originalNode, reducedNode); // detect cast ambiguities according to C# spec #7.7.6 if (IsNameOrMemberAccessButNoExpression(newExpression)) { var nextToken = parent.Parent.GetLastToken().GetNextToken(); return(nextToken.Kind() == SyntaxKind.OpenParenToken || nextToken.Kind() == SyntaxKind.TildeToken || nextToken.Kind() == SyntaxKind.ExclamationToken || (SyntaxFacts.IsKeywordKind(nextToken.Kind()) && !(nextToken.Kind() == SyntaxKind.AsKeyword || nextToken.Kind() == SyntaxKind.IsKeyword))); } return(false); }
public override void VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { base.VisitMemberAccessExpression(node); if (!IsTargetOfInvocation(node)) { var mgr = ctx.GetSymbolInfo(node); if (mgr.Symbol?.IsKind(SymbolKind.Method) == true) UsedMethods.Add(mgr.Symbol); } }
public static Task <Document> RefactorAsync( Document document, ForEachStatementSyntax forEachStatement, SemanticModel semanticModel, bool reverseLoop = false, CancellationToken cancellationToken = default(CancellationToken)) { string name = NameGenerator.Default.EnsureUniqueLocalName( DefaultNames.ForVariable, semanticModel, forEachStatement.Statement.SpanStart, cancellationToken: cancellationToken); SyntaxToken identifier = Identifier(name); if (name != DefaultNames.ForVariable) { identifier = identifier.WithRenameAnnotation(); } ExpressionSyntax forEachExpression = forEachStatement.Expression; MemberAccessExpressionSyntax countOrLengthMemberAccess = SimpleMemberAccessExpression( forEachExpression.WithoutTrivia(), IdentifierName(CSharpUtility.GetCountOrLengthPropertyName(forEachExpression, semanticModel, cancellationToken))); VariableDeclarationSyntax declaration = null; BinaryExpressionSyntax condition = null; PostfixUnaryExpressionSyntax incrementor = null; if (reverseLoop) { declaration = VariableDeclaration( IntType(), identifier, EqualsValueClause( SubtractExpression( countOrLengthMemberAccess, NumericLiteralExpression(1)))); condition = GreaterThanOrEqualExpression(IdentifierName(name), NumericLiteralExpression(0)); incrementor = PostDecrementExpression(IdentifierName(name)); } else { declaration = VariableDeclaration( IntType(), identifier, EqualsValueClause(NumericLiteralExpression(0))); condition = LessThanExpression( IdentifierName(name), countOrLengthMemberAccess); incrementor = PostIncrementExpression(IdentifierName(name)); } StatementSyntax statement = forEachStatement.Statement.ReplaceNodes( GetVariableReferences(forEachStatement, semanticModel, cancellationToken), (node, rewrittenNode) => { return(ElementAccessExpression( forEachExpression.WithoutTrivia(), BracketedArgumentList(SingletonSeparatedList(Argument(IdentifierName(name)))) ).WithTriviaFrom(node)); }); ForStatementSyntax forStatement = ForStatement( declaration: declaration, initializers: default(SeparatedSyntaxList <ExpressionSyntax>), condition: condition, incrementors: SingletonSeparatedList <ExpressionSyntax>(incrementor), statement: statement); forStatement = forStatement .WithTriviaFrom(forEachStatement) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(forEachStatement, forStatement, cancellationToken)); }
private static bool TryFindDoubleCall( SyntaxNode containerNode, string methodName, Func <ExpressionSyntax, bool> argumentPredicate, Stack <ExpressionSyntax> methodArguments, out InvocationExpressionSyntax outerInvocation, out MemberAccessExpressionSyntax innerMemberAccess) { outerInvocation = null; innerMemberAccess = null; bool isFound = false; foreach (var x in containerNode.DescendantNodes()) { if (!x.IsKind(SyntaxKind.IdentifierName) || !x.Parent.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { continue; } var outerMethodName = (IdentifierNameSyntax)x; if (outerMethodName.Identifier.Text != methodName) { continue; } var outerMemberAccess = (MemberAccessExpressionSyntax)x.Parent; if (!outerMemberAccess.Parent.IsKind(SyntaxKind.InvocationExpression)) { continue; } outerInvocation = (InvocationExpressionSyntax)outerMemberAccess.Parent; if (outerInvocation.ArgumentList.Arguments.Count != 1) { continue; } var outerArgument = outerInvocation.ArgumentList.Arguments[0]; ExpressionSyntax outerArgumentExpression; if (!TryGetLambdaLikeExpressionFromArgument(outerArgument, out outerArgumentExpression)) { continue; } if (argumentPredicate != null && !argumentPredicate(outerArgumentExpression)) { continue; } if (!outerInvocation.Expression.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { continue; } if (!outerMemberAccess.Expression.IsKind(SyntaxKind.InvocationExpression)) { continue; } var innerInvocation = (InvocationExpressionSyntax)outerMemberAccess.Expression; if (innerInvocation.ArgumentList.Arguments.Count != 1) { continue; } var innerArgument = innerInvocation.ArgumentList.Arguments[0]; ExpressionSyntax innerArgumentExpression; if (!TryGetLambdaLikeExpressionFromArgument(innerArgument, out innerArgumentExpression)) { continue; } if (argumentPredicate != null && !argumentPredicate(innerArgumentExpression)) { continue; } if (!innerInvocation.Expression.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { continue; } innerMemberAccess = (MemberAccessExpressionSyntax)innerInvocation.Expression; if (innerMemberAccess.Name.Identifier.Text != methodName) { continue; } isFound = true; methodArguments.Push(outerArgumentExpression); methodArguments.Push(innerArgumentExpression); break; } return(isFound); }
/// <summary> /// Initializes a new instance of the <see cref="MemberAccessExpression"/> class. /// </summary> /// <param name="syntaxNode"></param> public MemberAccessExpression(MemberAccessExpressionSyntax syntaxNode) : this(syntaxNode, null) { }
public static void Analyze(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation, MemberAccessExpressionSyntax memberAccess) { if (!invocation.IsParentKind(SyntaxKind.SimpleMemberAccessExpression)) { SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; MethodInfo methodInfo; if (semanticModel.TryGetExtensionMethodInfo(invocation, out methodInfo, ExtensionMethodKind.Reduced, cancellationToken) && methodInfo.IsLinqExtensionOfIEnumerableOfTWithoutParameters("Any")) { string propertyName = GetCountOrLengthPropertyName(memberAccess.Expression, semanticModel, cancellationToken); if (propertyName != null) { bool success = false; TextSpan span = TextSpan.FromBounds(memberAccess.Name.Span.Start, invocation.Span.End); if (invocation.DescendantTrivia(span).All(f => f.IsWhitespaceOrEndOfLineTrivia())) { if (invocation.IsParentKind(SyntaxKind.LogicalNotExpression)) { var logicalNot = (PrefixUnaryExpressionSyntax)invocation.Parent; if (logicalNot.OperatorToken.TrailingTrivia.IsEmptyOrWhitespace() && logicalNot.Operand.GetLeadingTrivia().IsEmptyOrWhitespace()) { success = true; } } else { success = true; } } if (success) { Diagnostic diagnostic = Diagnostic.Create( DiagnosticDescriptors.UseCountOrLengthPropertyInsteadOfAnyMethod, Location.Create(context.Node.SyntaxTree, span), ImmutableDictionary.CreateRange(new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("PropertyName", propertyName) }), propertyName); context.ReportDiagnostic(diagnostic); } } } } }
public override void VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { Emit <MemberAccessExpressionBlock, MemberAccessExpressionSyntax>(node); }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, MemberAccessExpressionSyntax memberAccess) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddUsingStaticDirective) && memberAccess.Expression?.IsMissing == false && memberAccess.Name?.IsMissing == false && context.SupportsSemanticModel) { memberAccess = GetTopmostMemberAccessExpression(memberAccess); if (context.Span.IsBetweenSpans(memberAccess.Expression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var typeSymbol = semanticModel .GetSymbolInfo(memberAccess.Expression, context.CancellationToken) .Symbol as INamedTypeSymbol; if (typeSymbol?.IsStaticClass() == true && (typeSymbol.IsPublic() || typeSymbol.IsInternal()) && !SyntaxUtility.IsUsingStaticDirectiveInScope(memberAccess, typeSymbol, semanticModel, context.CancellationToken)) { context.RegisterRefactoring($"using static {typeSymbol.ToString()};", cancellationToken => { return(RefactorAsync( context.Document, typeSymbol.ToString(), memberAccess, cancellationToken)); }); } } } }
private Location GetMemberInvocationLocation([NotNull] MemberAccessExpressionSyntax memberAccessSyntax) { SyntaxNode lastChild = memberAccessSyntax.ChildNodes().LastOrDefault(); return(lastChild != null?lastChild.GetLocation() : memberAccessSyntax.GetLocation()); }
/// <summary> /// For expressions, we switch to a precedence climbing parser. /// </summary> public ExpressionSyntax ParseExpression(OperatorPrecedence minPrecedence) { var expression = ParseAtom(); for (; ;) { IOperatorToken @operator = null; OperatorPrecedence?precedence = null; var leftAssociative = true; switch (Tokens.Current) { case IEqualsToken _: case IPlusEqualsToken _: case IMinusEqualsToken _: case IAsteriskEqualsToken _: case ISlashEqualsToken _: if (minPrecedence <= OperatorPrecedence.Assignment) { precedence = OperatorPrecedence.Assignment; leftAssociative = false; @operator = Tokens.RequiredToken <IOperatorToken>(); } break; case IQuestionQuestionToken _: if (minPrecedence <= OperatorPrecedence.Coalesce) { precedence = OperatorPrecedence.Coalesce; @operator = Tokens.RequiredToken <IOperatorToken>(); } break; case IOrKeywordToken _: if (minPrecedence <= OperatorPrecedence.LogicalOr) { precedence = OperatorPrecedence.LogicalOr; @operator = Tokens.RequiredToken <IOperatorToken>(); } break; case IAndKeywordToken _: if (minPrecedence <= OperatorPrecedence.LogicalAnd) { precedence = OperatorPrecedence.LogicalAnd; @operator = Tokens.RequiredToken <IOperatorToken>(); } break; case IEqualsEqualsToken _: case INotEqualToken _: if (minPrecedence <= OperatorPrecedence.Equality) { precedence = OperatorPrecedence.Equality; @operator = Tokens.RequiredToken <IOperatorToken>(); } break; case ILessThanToken _: case ILessThanOrEqualToken _: case IGreaterThanToken _: case IGreaterThanOrEqualToken _: case ILessThanColonToken _: // Subtype operator case IAsKeywordToken _: if (minPrecedence <= OperatorPrecedence.Relational) { precedence = OperatorPrecedence.Relational; @operator = Tokens.RequiredToken <IOperatorToken>(); } break; case IColonToken _: // type kind if (minPrecedence <= OperatorPrecedence.Relational) { var colon = Tokens.Expect <IColonToken>(); TypeKind typeKind; switch (Tokens.Current) { case IClassKeywordToken _: typeKind = TypeKind.Class; break; case IStructKeywordToken _: typeKind = TypeKind.Struct; break; default: Tokens.Expect <ITypeKindKeywordToken>(); // We saw a colon without what we expected after, just assume it is missing continue; } var typeKindSpan = Tokens.Expect <ITypeKindKeywordToken>(); var span = TextSpan.Covering(colon, typeKindSpan); expression = new TypeKindExpressionSyntax(span, typeKind); continue; } break; case IDotDotToken _: case ILessThanDotDotToken _: case IDotDotLessThanToken _: case ILessThanDotDotLessThanToken _: if (minPrecedence <= OperatorPrecedence.Range) { precedence = OperatorPrecedence.Range; @operator = Tokens.RequiredToken <IOperatorToken>(); } break; case IPlusToken _: case IMinusToken _: if (minPrecedence <= OperatorPrecedence.Additive) { precedence = OperatorPrecedence.Additive; @operator = Tokens.RequiredToken <IOperatorToken>(); } break; case IAsteriskToken _: case ISlashToken _: if (minPrecedence <= OperatorPrecedence.Multiplicative) { precedence = OperatorPrecedence.Multiplicative; @operator = Tokens.RequiredToken <IOperatorToken>(); } break; case IDollarToken _: if (minPrecedence <= OperatorPrecedence.Lifetime) { Tokens.Expect <IDollarToken>(); var(nameSpan, lifetime) = ParseLifetimeName(); expression = new ReferenceLifetimeSyntax(expression, nameSpan, lifetime); continue; } break; case IQuestionToken _: if (minPrecedence <= OperatorPrecedence.Unary) { var question = Tokens.Required <IQuestionToken>(); var span = TextSpan.Covering(expression.Span, question); expression = new UnaryExpressionSyntax(span, UnaryOperatorFixity.Postfix, UnaryOperator.Question, expression); continue; } break; case IOpenParenToken _: if (minPrecedence <= OperatorPrecedence.Primary) { var callee = expression; Tokens.Expect <IOpenParenToken>(); var arguments = ParseArguments(); var closeParenSpan = Tokens.Expect <ICloseParenToken>(); var span = TextSpan.Covering(callee.Span, closeParenSpan); expression = new InvocationSyntax(span, callee, arguments); continue; } break; case IDotToken _: case ICaretDotToken _: case IQuestionDotToken _: if (minPrecedence <= OperatorPrecedence.Primary) { // Member Access var accessOperator = BuildAccessOperator(Tokens.RequiredToken <IAccessOperatorToken>()); var member = ParseSimpleName(); var span = TextSpan.Covering(expression.Span, member.Span); expression = new MemberAccessExpressionSyntax(span, expression, accessOperator, member); continue; } break; default: return(expression); } if (@operator is IOperatorToken operatorToken && precedence is OperatorPrecedence operatorPrecedence) { if (leftAssociative) { operatorPrecedence += 1; } var rightOperand = ParseExpression(operatorPrecedence); expression = BuildOperatorExpression(expression, operatorToken, rightOperand); }
public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { _options.RequiresXUnitImport = true; return(base.VisitMemberAccessExpression(ReplaceMemberAccessExpression(node))); }
public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { // not descending into node to simplify the whole expression return(base.VisitMemberAccessExpression(AnnotateNodeWithSimplifyAnnotation(node))); }
public override void VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { base.VisitMemberAccessExpression(node); // check for possible dereference of null on member access (dot) var state = this.flowAnalysis.GetFlowState(node.Expression); switch (state.GetReferenceState(node.Expression)) { case NullState.Null: case NullState.CouldBeNull: context.ReportDiagnostic(Diagnostic.Create(PossibleNullDereference, node.Name.GetLocation())); break; } }
private static MemberAccessExpressionSyntax ReplaceMemberAccessExpression(MemberAccessExpressionSyntax node) { return(node.IsAssertExpression() && Assertions.ContainsKey(node.Name.ToString()) ? CreateAssertExpression(node) : node); }
public static bool MemberAccessIsAccessingDbContext(MemberAccessExpressionSyntax memberExpr, SyntaxNodeAnalysisContext context, EFUsageContext efContext, out EFCodeFirstClassInfo clsInfo) { clsInfo = null; var compIdent = memberExpr.Expression as IdentifierNameSyntax; var prop = memberExpr.Name; if (compIdent != null && prop != null) { var si = context.SemanticModel.GetSymbolInfo(compIdent); var type = si.Symbol?.TryGetType(); if (type != null) { //$ident is a DbContext if (efContext.DbContexts.Contains(type)) { //We're expecting $prop to be a symbol si = context.SemanticModel.GetSymbolInfo(prop); var ps = si.Symbol as IPropertySymbol; if (ps.IsDbSetProperty()) { var nts = ps.Type as INamedTypeSymbol; if (nts != null) { var typeArg = nts.TypeArguments[0]; clsInfo = efContext.GetClassInfo(typeArg); return true; } } } } } return false; }
private static bool IsParentMemberAccess(MemberAccessExpressionSyntax parent, ExpressionSyntax node) { return(parent != null && parent.Expression == node); }
private static bool IsSupportedLinqToEntitiesMethod(InvocationExpressionSyntax node, MemberAccessExpressionSyntax memberExpr, EFCodeFirstClassInfo rootQueryableType, EFUsageContext efContext, SyntaxNodeAnalysisContext context) => CanonicalMethodNames.IsKnownMethod(node, memberExpr, rootQueryableType, efContext, context);
public static string VariableName(this MemberAccessExpressionSyntax access) { var identifierName = access.Expression as IdentifierNameSyntax; return(identifierName.Identifier.ValueText); }
/// <summary> /// Tells if the Member access is the starting part of a Dynamic Invocation /// </summary> /// <param name="memberAccess"></param> /// <param name="semanticModel"></param> /// <returns>Return true, if the member access is the starting point of a Dynamic Invocation</returns> private static bool IsMemberAccessADynamicInvocation(MemberAccessExpressionSyntax memberAccess, SemanticModel semanticModel) { var ancestorInvocation = memberAccess.FirstAncestorOrSelf<InvocationExpressionSyntax>(); if (ancestorInvocation != null && ancestorInvocation.SpanStart == memberAccess.SpanStart) { var typeInfo = semanticModel.GetTypeInfo(ancestorInvocation); if (typeInfo.Type != null && typeInfo.Type.Kind == SymbolKind.DynamicType) { return true; } } return false; }
public static string AccessedMemberName(this MemberAccessExpressionSyntax access) => access.Name.Identifier.ValueText;
private ExpressionSyntax ParsePostFixExpression(ExpressionSyntax expr) { Debug.Assert(expr != null); while (true) { var tk = Current.Kind; switch (tk) { case SyntaxKind.OpenParenToken: expr = new InvocationExpressionSyntax(expr, ParseParenthesizedArgumentList(false)); break; case SyntaxKind.OpenBracketToken: expr = new ElementAccessExpressionSyntax(expr, Match(SyntaxKind.OpenBracketToken), ParseExpression(), Match(SyntaxKind.CloseBracketToken)); break; case SyntaxKind.PlusPlusToken: case SyntaxKind.MinusMinusToken: expr = new PostfixUnaryExpressionSyntax(SyntaxFacts.GetPostfixUnaryExpression(tk), expr, NextToken()); break; case SyntaxKind.DotToken: expr = new MemberAccessExpressionSyntax(expr, NextToken(), ParseIdentifier()); break; default: return expr; } } }
public static string ExpressionString(this MemberAccessExpressionSyntax access) => access.Expression.ToString();
public InitializeBodyInfo(InvocationExpressionSyntax invocationExpr = null, MemberAccessExpressionSyntax memberExpr = null) { InvocationExpr = invocationExpr; MemberExpr = memberExpr; }
public static string CalleeParentTypeName(this MemberAccessExpressionSyntax access, SyntaxNodeAnalysisContext context) { var identifierType = context.SemanticModel.GetTypeInfo(access.Expression); return(identifierType.Type.Name); }