예제 #1
0
        private static void Analyze(SyntaxNodeAnalysisContext context, INamedTypeSymbol targetsAttribute)
        {
            if (context.Node is not SimpleBaseTypeSyntax s)
            {
                return;
            }

            if (context.ContainingSymbol is not INamedTypeSymbol symbol || !(symbol.TypeKind is TypeKind.Class or TypeKind.Struct or TypeKind.Interface))
            {
                return;
            }

            if (context.SemanticModel.GetSymbolInfo(s.Type).Symbol is not INamedTypeSymbol target || target.TypeKind != TypeKind.Interface)
            {
                return;
            }

            if (target.GetAttribute(targetsAttribute) is not AttributeData attr || !attr.TryGetConstructorArgumentValue(0, out int value))
            {
                return;
            }

            IntfTargets targets = (IntfTargets)value;

            HandleTargets(context, targets, symbol);
        }
예제 #2
0
        private static void HandleTargets(SyntaxNodeAnalysisContext context, IntfTargets targets, INamedTypeSymbol intf)
        {
            if (targets == IntfTargets.ReflectionOnly)
            {
                context.ReportDiagnostic(Diagnostic.Create(DUR0403_InterfaceIsNotDirectlyAccessible, context.Node.GetLocation(), context.ContainingSymbol, intf));
                return;
            }

            switch (intf.TypeKind)
            {
            case TypeKind.Interface:

                if (!targets.HasFlag(IntfTargets.Interface))
                {
                    context.ReportDiagnostic(Diagnostic.Create(DUR0402_InterfaceCannotBeBaseOfAnotherInterface, context.Node.GetLocation(), context.ContainingSymbol, intf));
                }

                break;

            case TypeKind.Struct:

                if (intf.IsRecord)
                {
                    if (!targets.HasFlag(IntfTargets.RecordStruct))
                    {
                        ReportCannotBeImplemented(context, intf, "a record struct");
                    }
                }
                else
                {
                    if (!targets.HasFlag(IntfTargets.Struct))
                    {
                        ReportCannotBeImplemented(context, intf, "a struct");
                    }
                }

                break;

            case TypeKind.Class:

                if (intf.IsRecord)
                {
                    if (!targets.HasFlag(IntfTargets.RecordClass))
                    {
                        ReportCannotBeImplemented(context, intf, "a record class");
                    }
                }
                else
                {
                    if (!targets.HasFlag(IntfTargets.Class))
                    {
                        ReportCannotBeImplemented(context, intf, "a class");
                    }
                }

                break;
            }
        }