コード例 #1
0
        internal static bool ShouldEvaluateMethod(ApiControllerSymbolCache symbolCache, IMethodSymbol method)
        {
            if (method == null)
            {
                return(false);
            }

            if (method.ReturnsVoid || method.ReturnType.TypeKind == TypeKind.Error)
            {
                return(false);
            }

            if (!MvcFacts.IsController(method.ContainingType, symbolCache.ControllerAttribute, symbolCache.NonControllerAttribute))
            {
                return(false);
            }

            if (!method.ContainingType.HasAttribute(symbolCache.IApiBehaviorMetadata, inherit: true))
            {
                return(false);
            }

            if (!MvcFacts.IsControllerAction(method, symbolCache.NonActionAttribute, symbolCache.IDisposableDispose))
            {
                return(false);
            }

            return(true);
        }
コード例 #2
0
        private async Task IsControllerReturnsTrue(Type type)
        {
            var compilation = await GetIsControllerCompilation();

            var controllerAttribute    = compilation.GetTypeByMetadataName(ControllerAttribute);
            var nonControllerAttribute = compilation.GetTypeByMetadataName(NonControllerAttribute);
            var typeSymbol             = compilation.GetTypeByMetadataName(type.FullName);

            // Act
            var isController = MvcFacts.IsController(typeSymbol, controllerAttribute, nonControllerAttribute);

            // Assert
            Assert.True(isController);
        }
コード例 #3
0
        private async Task IsActionReturnsTrue(Type type, string methodName)
        {
            var compilation = await GetIsControllerActionCompilation();

            var nonActionAttribute = compilation.GetTypeByMetadataName(NonActionAttribute);
            var disposableDispose  = GetDisposableDispose(compilation);
            var typeSymbol         = compilation.GetTypeByMetadataName(type.FullName);
            var method             = (IMethodSymbol)typeSymbol.GetMembers(methodName).First();

            // Act
            var isControllerAction = MvcFacts.IsControllerAction(method, nonActionAttribute, disposableDispose);

            // Assert
            Assert.True(isControllerAction);
        }
コード例 #4
0
        public async Task IsAction_ReturnsTrueForNotDisposableDisposeOnTypeWithImplicitImplementation()
        {
            var compilation = await GetIsControllerActionCompilation();

            var nonActionAttribute = compilation.GetTypeByMetadataName(NonActionAttribute);
            var disposableDispose  = GetDisposableDispose(compilation);
            var typeSymbol         = compilation.GetTypeByMetadataName(typeof(NotDisposableWithDisposeThatIsNotInterfaceContract).FullName);
            var method             = typeSymbol.GetMembers(nameof(IDisposable.Dispose)).OfType <IMethodSymbol>().First(f => !f.ReturnsVoid);

            // Act
            var isControllerAction = MvcFacts.IsControllerAction(method, nonActionAttribute, disposableDispose);

            // Assert
            Assert.True(isControllerAction);
        }
コード例 #5
0
        private void InitializeWorker(CompilationStartAnalysisContext compilationStartAnalysisContext, SymbolCache symbolCache)
        {
            compilationStartAnalysisContext.RegisterSymbolAction(symbolAnalysisContext =>
            {
                var method = (IMethodSymbol)symbolAnalysisContext.Symbol;
                if (method.MethodKind != MethodKind.Ordinary)
                {
                    return;
                }

                if (method.Parameters.Length == 0)
                {
                    return;
                }

                if (!MvcFacts.IsController(method.ContainingType, symbolCache.ControllerAttribute, symbolCache.NonControllerAttribute) ||
                    !MvcFacts.IsControllerAction(method, symbolCache.NonActionAttribute, symbolCache.IDisposableDispose))
                {
                    return;
                }

                if (method.ContainingType.HasAttribute(symbolCache.IApiBehaviorMetadata, inherit: true))
                {
                    // The issue of parameter name collision with properties affects complex model-bound types
                    // and not input formatting. Ignore ApiController instances since they default to formatting.
                    return;
                }

                for (var i = 0; i < method.Parameters.Length; i++)
                {
                    var parameter = method.Parameters[i];
                    if (IsProblematicParameter(symbolCache, parameter))
                    {
                        var location = parameter.Locations.Length != 0 ?
                                       parameter.Locations[0] :
                                       Location.None;

                        symbolAnalysisContext.ReportDiagnostic(
                            Diagnostic.Create(
                                DiagnosticDescriptors.MVC1004_ParameterNameCollidesWithTopLevelProperty,
                                location,
                                parameter.Type.Name,
                                parameter.Name));
                    }
                }
            }, SymbolKind.Method);
        }