private bool?HasConflict(IEnumerable <ISymbol> symbols, IPropertySymbol property, Compilation compilation, CancellationToken cancellationToken) { // We're asking the rename API to update a bunch of references to an existing field to // the same name as an existing property. Rename will often flag this situation as // an unresolvable conflict because the new name won't bind to the field anymore. // // To address this, we let rename know that there is no conflict if the new symbol it // resolves to is the same as the property we're trying to get the references pointing // to. foreach (var symbol in symbols) { if (symbol is IPropertySymbol otherProperty) { var mappedProperty = otherProperty.GetSymbolKey().Resolve(compilation, cancellationToken: cancellationToken).Symbol as IPropertySymbol; if (property.Equals(mappedProperty)) { // No conflict. return(false); } } } // Just do the default check. return(null); }
internal bool IsValidAutoProperty(SyntaxNode property, IPropertySymbol propertySymbol) { var fields = propertySymbol.ContainingType.GetMembers().OfType <IFieldSymbol>(); var field = fields.FirstOrDefault(f => propertySymbol.Equals(f.AssociatedSymbol)); return(field != null); }
private static IFieldSymbol GetBackingField(IPropertySymbol property) { var field = property.ContainingType.GetMembers() .OfType <IFieldSymbol>() .FirstOrDefault(f => property.Equals(f.AssociatedSymbol)); if (field == null) { return(null); } // If the field is something can be referenced with the name it has, then just use // it as the backing field we'll generate. This is the case in VB where the backing // field can be referenced as is. if (field.CanBeReferencedByName) { return(field); } // Otherwise, generate a good name for the backing field we're generating. This is // the case for C# where we have mangled names for the backing field and need something // actually usable in code. var uniqueName = NameGenerator.GenerateUniqueName( property.Name.ToCamelCase(), n => !property.ContainingType.GetMembers(n).Any()); return(CodeGenerationSymbolFactory.CreateFieldSymbol( attributes: null, accessibility: field.DeclaredAccessibility, modifiers: DeclarationModifiers.From(field), type: field.Type, name: uniqueName)); }
private static bool IsDefaultGetProperty(IPropertySymbol propertySymbol) { // we need to search through all backing fields of the parent class var parentSymbol = propertySymbol.ContainingType; var hasAutoBackingField = parentSymbol.GetMembers().OfType <IFieldSymbol>().Any(symbol => propertySymbol.Equals(symbol.AssociatedSymbol)); var isImplementedMember = parentSymbol.AllInterfaces .SelectMany(iface => iface.GetMembers(propertySymbol.Name)) .Any(ifaceMember => propertySymbol.Equals(parentSymbol.FindImplementationForInterfaceMember(ifaceMember))); var hasExplicitGetter = GetterHasExplicitBodyOrInitializer(propertySymbol); return(hasAutoBackingField && isImplementedMember && !hasExplicitGetter); }
public static IEnumerable <IPropertySymbol> ImplementedInterfaceMembers(this IPropertySymbol @this) { if (@this == null) { throw new ArgumentNullException(nameof(@this)); } return(@this .ContainingType .AllInterfaces .SelectMany(i => i.GetMembers() .OfType <IPropertySymbol>()) .Where(m => @this.Equals( @this.ContainingType.FindImplementationForInterfaceMember(m)))); }
private bool PropertiesAreEquivalent(IPropertySymbol x, IPropertySymbol y, Dictionary <INamedTypeSymbol, INamedTypeSymbol> equivalentTypesWithDifferingAssemblies) { if (x.ContainingType.IsAnonymousType && y.ContainingType.IsAnonymousType) { // We can short circuit here and just use the symbols themselves to determine // equality. This will properly handle things like the VB case where two // anonymous types will be considered the same if they have properties that // differ in casing. if (x.Equals(y)) { return(true); } } return (x.IsIndexer == y.IsIndexer && x.MetadataName == y.MetadataName && x.Parameters.Length == y.Parameters.Length && ParametersAreEquivalent(x.Parameters, y.Parameters, equivalentTypesWithDifferingAssemblies) && AreEquivalent(x.ContainingSymbol, y.ContainingSymbol, equivalentTypesWithDifferingAssemblies)); }
public static bool Overrides([NotNull] this IPropertySymbol propertySymbol, [NotNull] IPropertySymbol overriddenProperty) { Requires.NotNull(propertySymbol, nameof(propertySymbol)); Requires.NotNull(overriddenProperty, nameof(overriddenProperty)); if (propertySymbol.Equals(overriddenProperty)) { return(true); } if (!propertySymbol.IsOverride) { return(false); } if (propertySymbol.OverriddenProperty.Equals(overriddenProperty)) { return(true); } return(propertySymbol.OverriddenProperty.Overrides(overriddenProperty)); }
internal static bool IsFixable( IndexerDeclarationSyntax indexerDeclaration, AccessorDeclarationSyntax accessor, SemanticModel semanticModel, CancellationToken cancellationToken) { switch (accessor.Kind()) { case SyntaxKind.GetAccessorDeclaration: { ExpressionSyntax expression = GetGetAccessorExpression(accessor); if (expression?.IsKind(SyntaxKind.ElementAccessExpression) != true) { return(false); } var elementAccess = (ElementAccessExpressionSyntax)expression; if (elementAccess.Expression?.IsKind(SyntaxKind.BaseExpression) != true) { return(false); } if (elementAccess.ArgumentList == null) { return(false); } IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(indexerDeclaration, cancellationToken); IPropertySymbol overriddenProperty = propertySymbol?.OverriddenProperty; if (overriddenProperty == null) { return(false); } ISymbol symbol = semanticModel.GetSymbol(elementAccess, cancellationToken); return(overriddenProperty.Equals(symbol) && CheckParameters(indexerDeclaration.ParameterList, elementAccess.ArgumentList, semanticModel, cancellationToken) && CheckDefaultValues(propertySymbol.Parameters, overriddenProperty.Parameters)); } case SyntaxKind.SetAccessorDeclaration: { ExpressionSyntax expression = GetSetAccessorExpression(accessor); if (expression?.IsKind(SyntaxKind.SimpleAssignmentExpression) != true) { return(false); } var assignment = (AssignmentExpressionSyntax)expression; ExpressionSyntax left = assignment.Left; if (left?.IsKind(SyntaxKind.ElementAccessExpression) != true) { return(false); } var elementAccess = (ElementAccessExpressionSyntax)left; if (elementAccess.Expression?.IsKind(SyntaxKind.BaseExpression) != true) { return(false); } if (elementAccess.ArgumentList == null) { return(false); } ExpressionSyntax right = assignment.Right; if (right?.IsKind(SyntaxKind.IdentifierName) != true) { return(false); } var identifierName = (IdentifierNameSyntax)right; if (identifierName.Identifier.ValueText != "value") { return(false); } IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(indexerDeclaration, cancellationToken); IPropertySymbol overriddenProperty = propertySymbol?.OverriddenProperty; if (overriddenProperty == null) { return(false); } ISymbol symbol = semanticModel.GetSymbol(elementAccess, cancellationToken); return(overriddenProperty.Equals(symbol) && CheckParameters(indexerDeclaration.ParameterList, elementAccess.ArgumentList, semanticModel, cancellationToken) && CheckDefaultValues(propertySymbol.Parameters, overriddenProperty.Parameters)); } case SyntaxKind.UnknownAccessorDeclaration: { return(false); } default: { Debug.Fail(accessor.Kind().ToString()); return(false); } } }
internal static bool IsFixable( PropertyDeclarationSyntax propertyDeclaration, AccessorDeclarationSyntax accessor, SemanticModel semanticModel, CancellationToken cancellationToken) { switch (accessor.Kind()) { case SyntaxKind.GetAccessorDeclaration: { ExpressionSyntax expression = GetGetAccessorExpression(accessor); if (expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) != true) { return(false); } var memberAccess = (MemberAccessExpressionSyntax)expression; if (memberAccess.Expression?.IsKind(SyntaxKind.BaseExpression) != true) { return(false); } SimpleNameSyntax simpleName = memberAccess.Name; IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken); IPropertySymbol overriddenProperty = propertySymbol?.OverriddenProperty; if (overriddenProperty == null) { return(false); } ISymbol symbol = semanticModel.GetSymbol(simpleName, cancellationToken); return(overriddenProperty.Equals(symbol)); } case SyntaxKind.SetAccessorDeclaration: { ExpressionSyntax expression = GetSetAccessorExpression(accessor); if (expression?.IsKind(SyntaxKind.SimpleAssignmentExpression) != true) { return(false); } var assignment = (AssignmentExpressionSyntax)expression; ExpressionSyntax left = assignment.Left; if (left?.IsKind(SyntaxKind.SimpleMemberAccessExpression) != true) { return(false); } var memberAccess = (MemberAccessExpressionSyntax)left; if (memberAccess.Expression?.IsKind(SyntaxKind.BaseExpression) != true) { return(false); } ExpressionSyntax right = assignment.Right; if (right?.IsKind(SyntaxKind.IdentifierName) != true) { return(false); } var identifierName = (IdentifierNameSyntax)right; if (identifierName.Identifier.ValueText != "value") { return(false); } SimpleNameSyntax simpleName = memberAccess.Name; if (simpleName == null) { return(false); } IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken); IPropertySymbol overriddenProperty = propertySymbol?.OverriddenProperty; if (overriddenProperty == null) { return(false); } ISymbol symbol = semanticModel.GetSymbol(simpleName, cancellationToken); return(overriddenProperty.Equals(symbol)); } case SyntaxKind.UnknownAccessorDeclaration: { return(false); } default: { Debug.Fail(accessor.Kind().ToString()); return(false); } } }
public static IFieldSymbol?GetBackingFieldIfAny(this IPropertySymbol property) => property.ContainingType.GetMembers() .OfType <IFieldSymbol>() .FirstOrDefault(f => property.Equals(f.AssociatedSymbol));
private static bool IsAutoGetterPropertyAssigned(SymbolAnalysisContext context, IPropertySymbol property) { Debug.Assert(!property.IsImplicitlyDeclared); var propertySyntax = (PropertyDeclarationSyntax)property.DeclaringSyntaxReferences.First().GetSyntax(); if (propertySyntax.Initializer != null) { return(true); } if (// A null accessor list indicates an expression-bodied property propertySyntax.AccessorList == null || // If accessor body is non-null, this is a computed property, not an auto property propertySyntax.AccessorList.Accessors.Any(a => a.Body != null)) { return(true); } // if any constructor exists which does not assign the property (including implicit constructor), return false foreach (var ctorSymbol in property.ContainingType.InstanceConstructors) { Debug.Assert(ctorSymbol.DeclaringSyntaxReferences.Length <= 1); var ctorSyntax = ctorSymbol.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() as ConstructorDeclarationSyntax; if (ctorSyntax == null) { // implicit constructor return(false); } var bodyOpt = (SyntaxNode)ctorSyntax.Body ?? ctorSyntax.ExpressionBody; if (bodyOpt == null) { // don't check extern constructors continue; } if (ctorSyntax.Initializer != null && ctorSyntax.Initializer.ThisOrBaseKeyword.Kind() == SyntaxKind.ThisKeyword) { // If the constructor calls out to another constructor in the same class, rely on the other constructor to initialize // (if the other constructor doesn't initialize, we'll warn anyway) return(true); } var isAssigned = false; var assignments = bodyOpt.DescendantNodes().OfType <AssignmentExpressionSyntax>(); foreach (var assignment in assignments) { var symbol = context.Compilation.GetSemanticModel(ctorSyntax.SyntaxTree).GetSymbolInfo(assignment.Left, context.CancellationToken); if (property.Equals(symbol.Symbol)) { isAssigned = true; break; } } if (!isAssigned) { return(false); } } return(true); }
static bool IsInterfaceImplementation(IPropertySymbol method) { return(method.ContainingType.AllInterfaces.SelectMany(@interface => @interface.GetMembers().OfType <IPropertySymbol>()).Any(interfaceMethod => method.Equals(method.ContainingType.FindImplementationForInterfaceMember(interfaceMethod)))); }
/// <summary> /// Check if a property is an auto-property. /// TODO: Remove this helper when https://github.com/dotnet/roslyn/issues/46682 is handled. /// </summary> public static bool IsAutoProperty(this IPropertySymbol propertySymbol) => propertySymbol.ContainingType.GetMembers().OfType <IFieldSymbol>().Any(f => f.IsImplicitlyDeclared && propertySymbol.Equals(f.AssociatedSymbol));
private bool PropertiesAreEquivalent(IPropertySymbol x, IPropertySymbol y, Dictionary<INamedTypeSymbol, INamedTypeSymbol> equivalentTypesWithDifferingAssemblies) { if (x.ContainingType.IsAnonymousType && y.ContainingType.IsAnonymousType) { // We can short circuit here and just use the symbols themselves to determine // equality. This will properly handle things like the VB case where two // anonymous types will be considered the same if they have properties that // differ in casing. if (x.Equals(y)) { return true; } } return x.IsIndexer == y.IsIndexer && x.MetadataName == y.MetadataName && x.Parameters.Length == y.Parameters.Length && ParametersAreEquivalent(x.Parameters, y.Parameters, equivalentTypesWithDifferingAssemblies) && AreEquivalent(x.ContainingSymbol, y.ContainingSymbol, equivalentTypesWithDifferingAssemblies); }
internal static bool CanRefactor( IndexerDeclarationSyntax indexerDeclaration, AccessorDeclarationSyntax accessor, SemanticModel semanticModel, CancellationToken cancellationToken) { switch (accessor.Kind()) { case SyntaxKind.GetAccessorDeclaration: { ExpressionSyntax expression = GetGetAccessorExpression(accessor); if (expression?.IsKind(SyntaxKind.ElementAccessExpression) == true) { var elementAccess = (ElementAccessExpressionSyntax)expression; if (elementAccess.Expression?.IsKind(SyntaxKind.BaseExpression) == true && elementAccess.ArgumentList != null) { IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(indexerDeclaration, cancellationToken); if (propertySymbol != null) { IPropertySymbol overriddenProperty = propertySymbol.OverriddenProperty; if (overriddenProperty != null) { ISymbol symbol = semanticModel.GetSymbol(elementAccess, cancellationToken); if (overriddenProperty.Equals(symbol)) { return(true); } } } } } return(false); } case SyntaxKind.SetAccessorDeclaration: { ExpressionSyntax expression = GetSetAccessorExpression(accessor); if (expression?.IsKind(SyntaxKind.SimpleAssignmentExpression) == true) { var assignment = (AssignmentExpressionSyntax)expression; ExpressionSyntax left = assignment.Left; if (left?.IsKind(SyntaxKind.ElementAccessExpression) == true) { var elementAccess = (ElementAccessExpressionSyntax)left; if (elementAccess.Expression?.IsKind(SyntaxKind.BaseExpression) == true && elementAccess.ArgumentList != null) { ExpressionSyntax right = assignment.Right; if (right?.IsKind(SyntaxKind.IdentifierName) == true) { var identifierName = (IdentifierNameSyntax)right; if (identifierName.Identifier.ValueText == "value") { IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(indexerDeclaration, cancellationToken); if (propertySymbol != null) { IPropertySymbol overriddenProperty = propertySymbol.OverriddenProperty; if (overriddenProperty != null) { ISymbol symbol = semanticModel.GetSymbol(elementAccess, cancellationToken); if (overriddenProperty.Equals(symbol)) { return(true); } } } } } } } } return(false); } case SyntaxKind.UnknownAccessorDeclaration: { return(false); } default: { Debug.Assert(false, accessor.Kind().ToString()); return(false); } } }