Exemple #1
0
        static string GetContextName(RoslynReflectionAllowedContext context)
        {
            switch (context)
            {
            case RoslynReflectionAllowedContext.Analyzers:
                return("analyzers");

            case RoslynReflectionAllowedContext.CodeFixes:
                return("code fixes/refactorings");
            }

            return("");
        }
Exemple #2
0
        static RoslynReflectionAllowedContext GetContextFromClass(INamedTypeSymbol symbol)
        {
            RoslynReflectionAllowedContext surroundingContext = RoslynReflectionAllowedContext.None;
            var surroundingClassAttributes = symbol.GetAttributes();

            if (surroundingClassAttributes.Any(a => a.AttributeClass.GetFullName() == typeof(DiagnosticAnalyzerAttribute).FullName))
            {
                surroundingContext = RoslynReflectionAllowedContext.Analyzers;
            }
            else if (surroundingClassAttributes.Any(a => a.AttributeClass.GetFullName() == typeof(ExportCodeFixProviderAttribute).FullName))
            {
                surroundingContext = RoslynReflectionAllowedContext.CodeFixes;
            }
            else if (surroundingClassAttributes.Any(a => a.AttributeClass.GetFullName() == typeof(ExportCodeRefactoringProviderAttribute).FullName))
            {
                surroundingContext = RoslynReflectionAllowedContext.CodeFixes;
            }

            return(surroundingContext);
        }
 public RoslynReflectionUsageAttribute(RoslynReflectionAllowedContext allowedContexts = RoslynReflectionAllowedContext.None)
 {
     AllowedContexts = allowedContexts;
 }
Exemple #4
0
        static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);
            var semanticModel = nodeContext.SemanticModel;

            var node = nodeContext.Node as MemberAccessExpressionSyntax;

            var symbol = semanticModel.GetSymbolInfo(node.Name).Symbol;

            if (symbol == null)
            {
                return(false);
            }

            RoslynReflectionAllowedContext surroundingContext = RoslynReflectionAllowedContext.None;
            var surroundingClass = node.Ancestors().OfType <ClassDeclarationSyntax>().FirstOrDefault();

            if (surroundingClass == null)
            {
                return(false);
            }
            var surroundingClassSymbol = semanticModel.GetDeclaredSymbol(surroundingClass);

            if (surroundingClassSymbol == null)
            {
                return(false);
            }
            surroundingContext = GetContextFromClass(surroundingClassSymbol);

            if (surroundingContext == RoslynReflectionAllowedContext.None)
            {
                return(false);
            }

            var reflectionUsageAttributeData =
                symbol.GetAttributes().FirstOrDefault(a => a.AttributeClass.GetFullName() == typeof(RoslynReflectionUsageAttribute).FullName);

            if (reflectionUsageAttributeData == null)
            {
                var containingTypeSymbol = symbol.ContainingType;
                if (containingTypeSymbol != null)
                {
                    reflectionUsageAttributeData =
                        containingTypeSymbol.GetAttributes().FirstOrDefault(a => a.AttributeClass.GetFullName() == typeof(RoslynReflectionUsageAttribute).FullName);
                }
            }

            string diagnosticMessage = "";

            RoslynReflectionAllowedContext allowedContext = RoslynReflectionAllowedContext.None;

            if (reflectionUsageAttributeData != null)
            {
                var attributeParam = reflectionUsageAttributeData.ConstructorArguments.FirstOrDefault();
                if (attributeParam.Value is int)
                {
                    allowedContext = (RoslynReflectionAllowedContext)attributeParam.Value;
                }

                diagnosticMessage = "This call accesses Roslyn features through reflection, although not allowed in {0}.";
            }
            else
            {
                if (surroundingContext == RoslynReflectionAllowedContext.Analyzers)
                {
                    var symbolContainingType = symbol.ContainingType;
                    if (symbolContainingType != null)
                    {
                        allowedContext = GetContextFromClass(symbolContainingType);
                    }
                }
                else
                {
                    allowedContext = RoslynReflectionAllowedContext.Analyzers | RoslynReflectionAllowedContext.CodeFixes;
                }

                diagnosticMessage = "Accessing members from code fixes/refactorings is not allowed in {0}.";
            }

            if ((allowedContext == RoslynReflectionAllowedContext.None) || (allowedContext.HasFlag(surroundingContext)))
            {
                return(false);
            }

            diagnostic = Diagnostic.Create(
                descriptor,
                node.Name.GetLocation(),
                string.Format(diagnosticMessage, GetContextName(surroundingContext))
                );
            return(true);
        }
        static string GetContextName(RoslynReflectionAllowedContext context)
        {
            switch (context)
            {
                case RoslynReflectionAllowedContext.Analyzers:
                    return "analyzers";
                case RoslynReflectionAllowedContext.CodeFixes:
                    return "code fixes/refactorings";
            }

            return "";
        }
Exemple #6
0
 public RoslynReflectionUsageAttribute(RoslynReflectionAllowedContext allowedContexts = RoslynReflectionAllowedContext.None)
 {
     AllowedContexts = allowedContexts;
 }