/// <summary> /// Verify member belongs to Non-Public Data Member Region /// if member is of type method, throw an error /// if member is of type field, check if it is non-public /// </summary> /// <param name="member"></param> /// <param name="locationRange"></param> /// <param name="context"></param> private static void VerifyMemberForNonPublicDataMemberRegion(MemberDeclarationSyntax member, LocationRangeModel locationRange, SyntaxNodeAnalysisContext context) { SyntaxTokenList modifiers = default(SyntaxTokenList); bool shouldProcess = false; switch (member.Kind()) { case SyntaxKind.FieldDeclaration: modifiers = ((FieldDeclarationSyntax)member).Modifiers; shouldProcess = true; break; case SyntaxKind.EnumDeclaration: modifiers = ((EnumDeclarationSyntax)member).Modifiers; shouldProcess = true; break; case SyntaxKind.DelegateDeclaration: modifiers = ((DelegateDeclarationSyntax)member).Modifiers; shouldProcess = true; break; } if (shouldProcess) { if (!HasAccessModifier(modifiers)) { return; } else if (MemberIsPublic(modifiers)) { CreateDiagnostic(member.GetLocation(), context, NonPublicDataMembersRegion, EnforceMemberLocation); } return; } if (member.Kind() == SyntaxKind.StructDeclaration) { return; } switch (member.Kind()) { case SyntaxKind.ConstructorDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.PropertyDeclaration: case SyntaxKind.EventDeclaration: case SyntaxKind.EventFieldDeclaration: case SyntaxKind.OperatorDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.IndexerDeclaration: case SyntaxKind.DestructorDeclaration: CreateDiagnostic(member.GetLocation(), context, NonPublicDataMembersRegion, EnforceMemberLocation); break; default: CreateDiagnostic(member.GetLocation(), context, NonPublicDataMembersRegion, NonCheckedMember); break; } }
public void InternalFourParameterConstructorSetsAllData() { MemberDeclarationSyntax decl = CreateValidDeclaration(); ICompilationData compilation = CreateValidCompilationData(decl.SyntaxTree); SemanticModel semanticModel = compilation.Compilation.GetSemanticModel(decl.SyntaxTree, true); ISymbol symbol = semanticModel.GetDeclaredSymbol(decl) !; Location location = decl.GetLocation(); ITypeData[] containingTypes = symbol.GetContainingTypes(compilation).ToArray(); INamespaceSymbol[] containingNamespaces = symbol.GetContainingNamespaces().ToArray(); ImmutableArray <AttributeData> attributes = symbol.GetAttributes(); Data.MemberData data = new(decl, compilation, symbol, semanticModel, containingTypes, containingNamespaces, attributes); Assert.True( data.SemanticModel is not null && data.SemanticModel.SyntaxTree.IsEquivalentTo(semanticModel.SyntaxTree) && data.Symbol is not null && SymbolEqualityComparer.Default.Equals(data.Symbol, symbol) && data.Location is not null && data.Location == location && data.Declaration is not null && data.Declaration.IsEquivalentTo(decl) && data.ParentCompilation is not null && data.ParentCompilation == compilation && data._containingTypes is not null & data._containingTypes == containingTypes && !data._attributes.IsDefault && data._attributes == attributes && data._containingNamespaces is not null && data._containingNamespaces == containingNamespaces ); }
/// <summary> /// Check is member is present in the given region /// </summary> /// <param name="member"></param> /// <param name="locationRange"></param> /// <returns>true if member is inside the given region, else false</returns> private static bool MemberPresentInRegion(MemberDeclarationSyntax member, LocationRangeModel locationRange) { int memberLocation = GetMemberLineNumber(member.GetLocation()); if (memberLocation > locationRange.StartLine && memberLocation < locationRange.EndLine) { return(true); } return(false); }
public void LocationReturnsActualNodeLocation() { MemberDeclarationSyntax member = CreateValidDeclaration(); Location location = member.GetLocation(); Data.MemberData data = new(member, CreateValidCompilationData(member.SyntaxTree)); Location dataLocation = data.Location; Assert.True(dataLocation is not null && dataLocation == location); }
private void ProcessMemberDeclaration( SyntaxTreeAnalysisContext context, SyntaxGenerator generator, CodeStyleOption <AccessibilityModifiersRequired> option, MemberDeclarationSyntax member) { if (member.IsKind(SyntaxKind.NamespaceDeclaration, out NamespaceDeclarationSyntax namespaceDeclaration)) { ProcessMembers(context, generator, option, namespaceDeclaration.Members); } // If we have a class or struct, recurse inwards. if (member.IsKind(SyntaxKind.ClassDeclaration, out TypeDeclarationSyntax typeDeclaration) || member.IsKind(SyntaxKind.StructDeclaration, out typeDeclaration)) { ProcessMembers(context, generator, option, typeDeclaration.Members); } #if false // Add this once we have the language version for C# that supports accessibility // modifiers on interface methods. if (option.Value == AccessibilityModifiersRequired.Always && member.IsKind(SyntaxKind.InterfaceDeclaration, out typeDeclaration)) { // Only recurse into an interface if the user wants accessibility modifiers on ProcessTypeDeclaration(context, generator, option, typeDeclaration); } #endif // Have to have a name to report the issue on. var name = member.GetNameToken(); if (name.Kind() == SyntaxKind.None) { return; } // Certain members never have accessibility. Don't bother reporting on them. if (!generator.CanHaveAccessibility(member)) { return; } // If they already have accessibility, no need to report anything. var accessibility = generator.GetAccessibility(member); if (accessibility != Accessibility.NotApplicable) { return; } // Missing accessibility. Report issue to user. var additionalLocations = ImmutableArray.Create(member.GetLocation()); context.ReportDiagnostic(Diagnostic.Create( CreateDescriptorWithSeverity(option.Notification.Value), name.GetLocation(), additionalLocations: additionalLocations)); }
protected CodeItem(MemberDeclarationSyntax memberDeclarationSyntax, TextSelection selection) { if (memberDeclarationSyntax == null) { return; } this.selection = selection; this.location = memberDeclarationSyntax.GetLocation(); this.modifiers = memberDeclarationSyntax.Modifiers.Select(m => m.ValueText); this.name = GetNameFromDeclarationSyntaxCore(memberDeclarationSyntax); }
private void ProcessMemberDeclaration( SyntaxTreeAnalysisContext context, CodeStyleOption2 <AccessibilityModifiersRequired> option, MemberDeclarationSyntax member) { if (member is BaseNamespaceDeclarationSyntax namespaceDeclaration) { ProcessMembers(context, option, namespaceDeclaration.Members); } // If we have a class or struct, recurse inwards. if (member.IsKind(SyntaxKind.ClassDeclaration, out TypeDeclarationSyntax? typeDeclaration) || member.IsKind(SyntaxKind.StructDeclaration, out typeDeclaration) || member.IsKind(SyntaxKind.RecordDeclaration, out typeDeclaration) || member.IsKind(SyntaxKind.RecordStructDeclaration, out typeDeclaration)) { ProcessMembers(context, option, typeDeclaration.Members); } #if false // Add this once we have the language version for C# that supports accessibility // modifiers on interface methods. if (option.Value == AccessibilityModifiersRequired.Always && member.IsKind(SyntaxKind.InterfaceDeclaration, out typeDeclaration)) { // Only recurse into an interface if the user wants accessibility modifiers on ProcessTypeDeclaration(context, generator, option, typeDeclaration); } #endif if (!CSharpAddAccessibilityModifiers.Instance.ShouldUpdateAccessibilityModifier(CSharpAccessibilityFacts.Instance, member, option.Value, out var name)) { return; } // Have an issue to flag, either add or remove. Report issue to user. var additionalLocations = ImmutableArray.Create(member.GetLocation()); context.ReportDiagnostic(DiagnosticHelper.Create( Descriptor, name.GetLocation(), option.Notification.Severity, additionalLocations: additionalLocations, properties: null)); }
public void InternalTwoParameterConstructorSetsAllData() { MemberDeclarationSyntax decl = CreateValidDeclaration(); ICompilationData compilation = CreateValidCompilationData(decl.SyntaxTree); SemanticModel semanticModel = compilation.Compilation.GetSemanticModel(decl.SyntaxTree, true); ISymbol symbol = semanticModel.GetDeclaredSymbol(decl) !; Location location = decl.GetLocation(); Data.MemberData data = new(symbol, compilation); Assert.True( data.SemanticModel is not null && data.SemanticModel.SyntaxTree.IsEquivalentTo(semanticModel.SyntaxTree) && data.Symbol is not null && SymbolEqualityComparer.Default.Equals(data.Symbol, symbol) && data.Location is not null && data.Location == location && data.Declaration is not null && data.Declaration.IsEquivalentTo(decl) && data.ParentCompilation is not null && data.ParentCompilation == compilation ); }
private void ProcessMemberDeclaration( SyntaxTreeAnalysisContext context, CodeStyleOption2 <AccessibilityModifiersRequired> option, MemberDeclarationSyntax member) { if (member.IsKind(SyntaxKind.NamespaceDeclaration, out NamespaceDeclarationSyntax namespaceDeclaration)) { ProcessMembers(context, option, namespaceDeclaration.Members); } // If we have a class or struct, recurse inwards. if (member.IsKind(SyntaxKind.ClassDeclaration, out TypeDeclarationSyntax typeDeclaration) || member.IsKind(SyntaxKind.StructDeclaration, out typeDeclaration)) { ProcessMembers(context, option, typeDeclaration.Members); } #if false // Add this once we have the language version for C# that supports accessibility // modifiers on interface methods. if (option.Value == AccessibilityModifiersRequired.Always && member.IsKind(SyntaxKind.InterfaceDeclaration, out typeDeclaration)) { // Only recurse into an interface if the user wants accessibility modifiers on ProcessTypeDeclaration(context, generator, option, typeDeclaration); } #endif // Have to have a name to report the issue on. var name = member.GetNameToken(); if (name.Kind() == SyntaxKind.None) { return; } // Certain members never have accessibility. Don't bother reporting on them. if (!SyntaxFacts.CanHaveAccessibility(member)) { return; } // This analyzer bases all of its decisions on the accessibility var accessibility = SyntaxFacts.GetAccessibility(member); // Omit will flag any accessibility values that exist and are default // The other options will remove or ignore accessibility var isOmit = option.Value == AccessibilityModifiersRequired.OmitIfDefault; if (isOmit) { if (accessibility == Accessibility.NotApplicable) { return; } var parentKind = member.Parent.Kind(); switch (parentKind) { // Check for default modifiers in namespace and outside of namespace case SyntaxKind.CompilationUnit: case SyntaxKind.NamespaceDeclaration: { // Default is internal if (accessibility != Accessibility.Internal) { return; } } break; case SyntaxKind.ClassDeclaration: case SyntaxKind.StructDeclaration: { // Inside a type, default is private if (accessibility != Accessibility.Private) { return; } } break; default: return; // Unknown parent kind, don't do anything } } else { // Mode is always, so we have to flag missing modifiers if (accessibility != Accessibility.NotApplicable) { return; } } // Have an issue to flag, either add or remove. Report issue to user. var additionalLocations = ImmutableArray.Create(member.GetLocation()); context.ReportDiagnostic(DiagnosticHelper.Create( Descriptor, name.GetLocation(), option.Notification.Severity, additionalLocations: additionalLocations, properties: null)); }