private static void NoExpectedResultSupplied(
            SyntaxNodeAnalysisContext context,
            IMethodSymbol methodSymbol,
            AttributeSyntax attributeNode)
        {
            var methodReturnValueType = methodSymbol.ReturnType;

            if (methodSymbol.IsAsync &&
                methodReturnValueType.SpecialType == SpecialType.System_Void)
            {
                context.ReportDiagnostic(Diagnostic.Create(asyncNoExpectedResultAndVoidReturnType, attributeNode.GetLocation()));
            }
            else if (methodReturnValueType.IsAwaitable(out var awaitReturnType))
            {
                if (awaitReturnType.SpecialType != SpecialType.System_Void)
                {
                    context.ReportDiagnostic(Diagnostic.Create(asyncNoExpectedResultAndNonTaskReturnType,
                                                               attributeNode.GetLocation(), methodReturnValueType.ToDisplayString()));
                }
            }
            else
            {
                if (methodReturnValueType.SpecialType != SpecialType.System_Void)
                {
                    context.ReportDiagnostic(Diagnostic.Create(noExpectedResultButNonVoidReturnType,
                                                               attributeNode.GetLocation(), methodReturnValueType.ToDisplayString()));
                }
            }
        }
예제 #2
0
        private static void NoExpectedResultSupplied(
            SyntaxNodeAnalysisContext context,
            IMethodSymbol methodSymbol,
            AttributeSyntax attributeNode)
        {
            var methodReturnValueType = methodSymbol.ReturnType;

            if (IsTestMethodAsync(context.Compilation, methodSymbol))
            {
                if (methodReturnValueType.SpecialType == SpecialType.System_Void)
                {
                    context.ReportDiagnostic(Diagnostic.Create(asyncNoExpectedResultAndVoidReturnType, attributeNode.GetLocation()));
                }
                else
                {
                    var isTaskType = methodReturnValueType.Equals(context.Compilation.GetTypeByMetadataName(fullyQualifiedNameOfTask));
                    if (!isTaskType)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(asyncNoExpectedResultAndNonTaskReturnType,
                                                                   attributeNode.GetLocation(), methodReturnValueType.ToDisplayString()));
                    }
                }
            }
            else
            {
                if (methodReturnValueType.SpecialType != SpecialType.System_Void)
                {
                    context.ReportDiagnostic(Diagnostic.Create(noExpectedResultButNonVoidReturnType,
                                                               attributeNode.GetLocation(), methodReturnValueType.ToDisplayString()));
                }
            }
        }
        public static ExpressionSyntax GetSingleBody(SyntaxNodeAnalysisContext context, string ident, AttributeSyntax att, MemberDeclarationSyntax member)
        {
            if (member is MethodDeclarationSyntax)
            {
                var method = (MethodDeclarationSyntax)member;

                if (method.ExpressionBody != null)
                {
                    return(method.ExpressionBody.Expression);
                }

                return(OnlyReturn(context, ident, att, method.Body.Statements));
            }
            else if (member is PropertyDeclarationSyntax)
            {
                var property = (PropertyDeclarationSyntax)member;

                if (property.ExpressionBody != null)
                {
                    return(property.ExpressionBody.Expression);
                }

                var getter = property.AccessorList.Accessors.SingleOrDefault(a => a.Kind() == SyntaxKind.GetAccessorDeclaration);

                if (getter == null)
                {
                    Diagnostic(context, ident, att.GetLocation(), "no getter");
                    return(null);
                }

                if (property.AccessorList.Accessors.Any(a => a.Kind() == SyntaxKind.SetAccessorDeclaration))
                {
                    Diagnostic(context, ident, att.GetLocation(), "setter not allowed");
                    return(null);
                }

                if (getter.Body == null)
                {
                    Diagnostic(context, ident, getter.GetLocation(), "no getter body");
                    return(null);
                }

                return(OnlyReturn(context, ident, att, getter.Body.Statements));
            }

            Diagnostic(context, ident, att.GetLocation(), "no property or method");
            return(null);
        }
        private static void ExpectedResultSupplied(
            SyntaxNodeAnalysisContext context,
            IMethodSymbol methodSymbol,
            AttributeSyntax attributeNode,
            AttributeArgumentSyntax expectedResultNamedArgument)
        {
            var methodReturnValueType = methodSymbol.ReturnType;

            if (methodReturnValueType.IsAwaitable(out var awaitReturnType))
            {
                if (awaitReturnType.SpecialType == SpecialType.System_Void)
                {
                    context.ReportDiagnostic(Diagnostic.Create(asyncExpectedResultButReturnTypeNotGenericTask,
                                                               attributeNode.GetLocation(), methodReturnValueType.ToDisplayString()));
                }
                else
                {
                    ReportIfExpectedResultTypeCannotBeAssignedToReturnType(
                        ref context, expectedResultNamedArgument, awaitReturnType);
                }
            }
            else
            {
                if (methodReturnValueType.SpecialType == SpecialType.System_Void)
                {
                    context.ReportDiagnostic(Diagnostic.Create(specifiedExpectedResultForVoid,
                                                               expectedResultNamedArgument.GetLocation()));
                }
                else
                {
                    ReportIfExpectedResultTypeCannotBeAssignedToReturnType(
                        ref context, expectedResultNamedArgument, methodReturnValueType);
                }
            }
        }
예제 #5
0
 // The [FunctionName] attribute has an illegal function name.
 public static Diagnostic IllegalFunctionName(AttributeSyntax syntax, string value)
 {
     return(Diagnostic.Create(Rule4,
                              syntax.GetLocation(),
                              value
                              ));
 }
예제 #6
0
        internal static ExpressionSyntax OnlyReturn(SyntaxNodeAnalysisContext context, string ident, AttributeSyntax att, SyntaxList <StatementSyntax> statements)
        {
            var only = statements.Only();

            if (only == null)
            {
                Diagnostic(context, ident, att.GetLocation(), statements.Count + " statements");
                return(null);
            }

            var ret = only as ReturnStatementSyntax;

            if (ret == null)
            {
                Diagnostic(context, ident, only.GetLocation(), "no return");
                return(null);
            }

            if (ret.Expression == null)
            {
                Diagnostic(context, ident, only.GetLocation(), "no return expression");
                return(null);
            }

            return(ret.Expression);
        }
        protected override void Analyze(SyntaxNodeAnalysisContext context, AttributeSyntax attributeSyntax)
        {
            var(refinedAttr, targetString) = GetRefinedAttributeWithItsMigrationTarget(attributeSyntax);

            context.ReportDiagnostic(Diagnostic.Create(
                                         Descriptors.DeprecatedReplaceableAttribute, attributeSyntax.GetLocation(), refinedAttr, targetString));
        }
예제 #8
0
        protected virtual void Analyze(SyntaxNodeAnalysisContext context, AttributeSyntax attributeSyntax)
        {
            var attributeLocation = attributeSyntax.GetLocation();

            context.ReportDiagnostic(Diagnostic.Create(
                                         SupportedDiagnostics.First(), attributeLocation, attributeSyntax.Name.ToString()));
        }
예제 #9
0
        private AttributeSyntax TransformExplicitAttribute(AttributeSyntax node)
        {
            var location = node.GetLocation();
            var original = node.ToFullString();

            // MSTest V2 does not support "[Explicit]".
            // Convert "[Explicit]" to "[Ignore("EXPLICIT")]"
            // Convert "[Explicit("yadayada")]" to "[Ignore("EXPLICIT: yadayada")]"

            string text        = "EXPLICIT";
            var    description = node.GetPositionExpression(0);

            if (description != null)
            {
                text += ": " + description.GetFirstToken().ValueText;
            }

            var literalExpression = SyntaxFactory.LiteralExpression(
                SyntaxKind.StringLiteralExpression,
                SyntaxFactory.Literal("\"" + text + "\"", text));

            var arguments = new SeparatedSyntaxList <AttributeArgumentSyntax>();

            arguments = arguments.Add(SyntaxFactory.AttributeArgument(literalExpression));

            node = node.WithName(SyntaxFactory.IdentifierName("Ignore")).WithArgumentList(
                SyntaxFactory.AttributeArgumentList(arguments));

            m_diagnostics.Add(Diagnostic.Create(DiagnosticsDescriptors.TransformedUnsupported, location, original,
                                                node.ToFullString()));

            return(node);
        }
        private void HandleAttribute(SyntaxNodeAnalysisContext context)
        {
            AttributeSyntax syntax       = (AttributeSyntax)context.Node;
            SymbolInfo      symbolInfo   = context.SemanticModel.GetSymbolInfo(syntax, context.CancellationToken);
            IMethodSymbol   methodSymbol = symbolInfo.Symbol as IMethodSymbol;

            if (methodSymbol == null)
            {
                return;
            }

            if (!string.Equals("JsonObjectAttribute", methodSymbol.ContainingType?.Name, StringComparison.Ordinal))
            {
                return;
            }

            if (syntax.ArgumentList?.Arguments.Count > 0)
            {
                bool?isOptIn = null;

                // check property assignments first, because they override the first argument when both are specified
                foreach (var attributeArgumentSyntax in syntax.ArgumentList.Arguments)
                {
                    if (attributeArgumentSyntax.NameEquals == null)
                    {
                        continue;
                    }

                    if (!string.Equals("MemberSerialization", attributeArgumentSyntax.NameEquals.Name?.ToString(), StringComparison.Ordinal))
                    {
                        continue;
                    }

                    if (IsMemberSerializationOptIn(context, attributeArgumentSyntax.Expression))
                    {
                        return;
                    }

                    isOptIn = false;
                }

                if (!isOptIn.HasValue)
                {
                    AttributeArgumentSyntax firstArgument = syntax.ArgumentList.Arguments[0];
                    if (firstArgument?.Expression != null &&
                        (firstArgument.NameColon == null || string.Equals("memberSerialization", firstArgument.NameColon?.Name?.ToString(), StringComparison.Ordinal)) &&
                        firstArgument.NameEquals == null)
                    {
                        if (IsMemberSerializationOptIn(context, firstArgument?.Expression))
                        {
                            return;
                        }
                    }
                }
            }

            context.ReportDiagnostic(Diagnostic.Create(Descriptor, syntax.GetLocation()));
        }
        protected override void Analyze(SyntaxNodeAnalysisContext context, AttributeSyntax attributeSyntax)
        {
            var attributeLocation = attributeSyntax.GetLocation();

            (var attrName, var nunitTreatedAsAttrName) = ResolveNames(attributeSyntax);

            context.ReportDiagnostic(Diagnostic.Create(
                                         Descriptors.AttributeChangedSemantic, attributeLocation, attrName, nunitTreatedAsAttrName));
        }
예제 #12
0
        /// <summary> Находит импорты сторонних DLL </summary>
        private void CheckDllImport(AttributeSyntax node)
        {
            var dllImportType = semanticModel.Compilation.GetTypeByMetadataName(typeof(DllImportAttribute).FullName);
            var nodeType      = semanticModel.GetTypeInfo(node).Type;

            if (dllImportType != null && dllImportType.Equals(nodeType))
            {
                Error(node.GetLocation(), "Импорт сторонней DLL", ListViewErrors.Criticality.Высокий, $"Провести анализ DLL: {node.ArgumentList.Arguments[0]}");
            }
        }
예제 #13
0
        /// <summary>
        /// Returns location of attribute argument at the specified <paramref name="position"/> and with the given <paramref name="argumentName"/>
        /// or location of the <paramref name="attribute"/> is no appropriate argument was found.
        /// </summary>
        /// <param name="attribute"><see cref="AttributeSyntax"/> to get the location of argument of.</param>
        /// <param name="position">Position of argument to get.</param>
        /// <param name="argumentName">Name of the argument to get the location of.</param>
        /// <exception cref="ArgumentNullException"><paramref name="attribute"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> cannot be less than <c>0</c>.</exception>
        public static Location GetArgumentLocation(this AttributeSyntax attribute, int position, string?argumentName = null)
        {
            AttributeArgumentSyntax?arg = attribute.GetArgument(position, argumentName);

            if (arg is null)
            {
                return(attribute.GetLocation());
            }

            return(arg.GetLocation());
        }
예제 #14
0
        /// <summary>
        /// Returns location of attribute argument with the specified <paramref name="argumentName"/>
        /// or location of the <paramref name="attribute"/> if no argument with the <paramref name="argumentName"/> was found.
        /// </summary>
        /// <param name="attribute"><see cref="AttributeSyntax"/> to get the location of argument of.</param>
        /// <param name="argumentName">Name of the argument to get the location of.</param>
        /// <param name="includeParameters">Determines whether to include arguments with colons in the search.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="attribute"/> is <see langword="null"/>. -or-
        /// <paramref name="argumentName"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException"><paramref name="argumentName"/> cannot be empty or white space only.</exception>
        public static Location GetArgumentLocation(this AttributeSyntax attribute, string argumentName, bool includeParameters = false)
        {
            AttributeArgumentSyntax?arg = attribute.GetArgument(argumentName, includeParameters);

            if (arg is null)
            {
                return(attribute.GetLocation());
            }

            return(arg.GetLocation());
        }
        protected override void Analyze(SyntaxNodeAnalysisContext context, AttributeSyntax attributeSyntax)
        {
            var ignoringModel = new TestIgnoringModel(attributeSyntax);

            if (!ignoringModel.DoesIgnoringNeedAdjustment)
            {
                return;
            }

            var attributeLocation = attributeSyntax.GetLocation();

            var reportMessage = ignoringModel.ReportMessage;

            context.ReportDiagnostic(Diagnostic.Create(Descriptors.IgnoreReason, attributeLocation, reportMessage));
        }
예제 #16
0
        public static AttributeSyntax WithoutNameEquals(
            this AttributeSyntax node, string nameEquals, List <Diagnostic> diagnostics = null,
            Location location = null)
        {
            var candidate = FindByNameEquals(node.ArgumentList, nameEquals);

            if (candidate != null)
            {
                diagnostics?.Add(Diagnostic.Create(DiagnosticsDescriptors.IgnoredUnsupportedNamedArgument,
                                                   node.GetLocation(location), nameEquals));

                return(node.WithArgumentList(node.ArgumentList.RemoveNode(candidate, SyntaxRemoveOptions.KeepDirectives)));
            }

            return(node);
        }
예제 #17
0
        public static AttributeSyntax WithoutArgumentList(
            this AttributeSyntax node, List <Diagnostic> diagnostics = null, Location location = null,
            params string[] ignore)
        {
            if (node.ArgumentList?.Arguments.Count > 0)
            {
                int count = node.ArgumentList.Arguments.Count(a => ignore.All(i => i != a.NameEquals?.Name?.ToFullString()?.Trim()));
                if (count > 0)
                {
                    diagnostics?.Add(Diagnostic.Create(DiagnosticsDescriptors.IgnoredAllArguments,
                                                       node.GetLocation(location), node.ToFullString()));
                }

                node = node.WithArgumentList(null);
            }

            return(node);
        }
        private void AnalyzeAttribute(SyntaxNodeAnalysisContext context)
        {
            AttributeSyntax attribute = context.Node as AttributeSyntax;

            if (attribute == null)
            {
                return;
            }

            if (!attribute.Name.ToString().Equals("JsonParamBinder"))
            {
                return;
            }

            ISymbol methodSymbol = context.ContainingSymbol;

            if (methodSymbol.Kind != SymbolKind.Method)
            {
                return;
            }

            ISymbol classSymbol = methodSymbol.ContainingSymbol;

            if (classSymbol.Kind != SymbolKind.NamedType)
            {
                return;
            }

            string className = classSymbol.ToDisplayString(ClassDisplayFormat);

            if (LegacyJsonParamBinderClasses.Classes.Contains(className))
            {
                return;
            }

            Location   location   = attribute.GetLocation();
            Diagnostic diagnostic = Diagnostic.Create(
                Diagnostics.ObsoleteJsonParamBinder,
                location
                );

            context.ReportDiagnostic(diagnostic);
        }
예제 #19
0
        private static void ExpectedResultSupplied(
            SyntaxNodeAnalysisContext context,
            IMethodSymbol methodSymbol,
            AttributeSyntax attributeNode,
            AttributeArgumentSyntax expectedResultNamedArgument)
        {
            var methodReturnValueType = methodSymbol.ReturnType;

            if (IsTestMethodAsync(context.Compilation, methodSymbol))
            {
                var genericTaskType = context.Compilation.GetTypeByMetadataName(fullyQualifiedNameOfGenericTask);
                if (!methodReturnValueType.OriginalDefinition.Equals(genericTaskType))
                {
                    context.ReportDiagnostic(Diagnostic.Create(asyncExpectedResultButReturnTypeNotGenericTask,
                                                               attributeNode.GetLocation(), methodReturnValueType.ToDisplayString()));
                }
                else
                {
                    var namedTypeSymbol = methodReturnValueType as INamedTypeSymbol;
                    if (namedTypeSymbol == null)
                    {
                        return;
                    }

                    var taskTypeParameter = namedTypeSymbol.TypeArguments.First();
                    ReportIfExpectedResultTypeCannotBeAssignedToReturnType(
                        ref context, expectedResultNamedArgument, taskTypeParameter);
                }
            }
            else
            {
                if (methodReturnValueType.SpecialType == SpecialType.System_Void)
                {
                    context.ReportDiagnostic(Diagnostic.Create(specifiedExpectedResultForVoid,
                                                               expectedResultNamedArgument.GetLocation()));
                }
                else
                {
                    ReportIfExpectedResultTypeCannotBeAssignedToReturnType(
                        ref context, expectedResultNamedArgument, methodReturnValueType);
                }
            }
        }
예제 #20
0
        /// <summary>
        /// Attempts to create a new <see cref="CommandClass" />.
        /// </summary>
        /// <param name="commandManager"></param>
        /// <param name="classSymbol"></param>
        /// <param name="attributeSyntax"></param>
        /// <param name="verb"></param>
        /// <returns></returns>
        public static Result<CommandClass, Diagnostic> Create(
            CommandManagerClass commandManager,
            INamedTypeSymbol classSymbol,
            AttributeSyntax attributeSyntax,
            string? verb = null)
        {
            if (verb is not null && string.IsNullOrWhiteSpace(verb))
            {
                return Result.Err<CommandClass, Diagnostic>(Diagnostic.Create(
                    DiagnosticDescriptors.InvalidVerbPassedToCommandManagerAttribute,
                    attributeSyntax.GetLocation()));
            }

            return Result.Ok<CommandClass, Diagnostic>(new CommandClass(
                commandManager,
                classSymbol,
                attributeSyntax,
                verb));
        }
예제 #21
0
        protected override void Analyze(SyntaxNodeAnalysisContext context, AttributeSyntax attributeSyntax)
        {
            var model = new StaticSourceAttribute(attributeSyntax);

            var containerTypeSymbol = model.GetContainerTypeSymbol(context.SemanticModel);

            if (containerTypeSymbol == null)
            {
                return;
            }

            var attributeLocation = attributeSyntax.GetLocation();

            if (!IsMemberStatic(containerTypeSymbol, model.SourceName, attributeLocation, context.SemanticModel))
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             Descriptors.StaticSource, attributeLocation, model.AttributeName, model.MemberFullPath));
            }
        }
예제 #22
0
        public static bool IsAttribute(AttributeSyntax attribute, SyntaxNodeAnalysisContext context, string name, string fullName, out Location location, out AttributeArgumentSyntax argument)
        {
            location = null;
            argument = default(AttributeArgumentSyntax);

            if (attribute.Name.ToString().Contains(name))
            {
                IMethodSymbol memberSymbol = context.SemanticModel.GetSymbolInfo(attribute).Symbol as IMethodSymbol;
                if (memberSymbol != null && memberSymbol.ToString().StartsWith(fullName))
                {
                    location = attribute.GetLocation();
                    if (attribute.ArgumentList != null && attribute.ArgumentList.Arguments.Count > 0)
                    {
                        argument = attribute.ArgumentList.Arguments.First();
                    }
                    return(true);
                }
            }

            return(false);
        }
        private void HandleAttribute(SyntaxNodeAnalysisContext context)
        {
            AttributeSyntax syntax       = (AttributeSyntax)context.Node;
            SymbolInfo      symbolInfo   = context.SemanticModel.GetSymbolInfo(syntax, context.CancellationToken);
            IMethodSymbol   methodSymbol = symbolInfo.Symbol as IMethodSymbol;

            if (methodSymbol == null)
            {
                return;
            }

            if (!string.Equals("JsonPropertyAttribute", methodSymbol.ContainingType?.Name, StringComparison.Ordinal))
            {
                return;
            }

            if (syntax.ArgumentList?.Arguments.Count > 0)
            {
                foreach (var attributeArgumentSyntax in syntax.ArgumentList.Arguments)
                {
                    if (attributeArgumentSyntax.NameEquals == null)
                    {
                        continue;
                    }

                    if (!string.Equals("DefaultValueHandling", attributeArgumentSyntax.NameEquals.Name?.ToString(), StringComparison.Ordinal))
                    {
                        continue;
                    }

                    if (IsDefaultValueHandlingIgnore(context, attributeArgumentSyntax.Expression))
                    {
                        return;
                    }
                }
            }

            context.ReportDiagnostic(Diagnostic.Create(Descriptor, syntax.GetLocation()));
        }
예제 #24
0
        /// <summary>
        /// Gets all command methods from this command class.
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Result<ImmutableDictionary<string, CommandMethod>, Diagnostic> GetCommandMethods(CancellationToken cancellationToken = default)
        {
            var dictionaryBuilder =
                ImmutableDictionary.CreateBuilder<string, CommandMethod>();

            foreach (var methodSymbol in ClassSymbol.GetMembers()
                                                    .OfType<IMethodSymbol>()
                                                    .Where(method => method.GetAttributes()
                                                                           .Any(attr => CommandManager.IsCommandAttributeSymbol(attr.AttributeClass!))))
            {
                cancellationToken.ThrowIfCancellationRequested();
                foreach (var attrData in methodSymbol.GetAttributes()
                                                     .Where(attr => CommandManager.IsCommandAttributeSymbol(attr.AttributeClass!)))
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    var attr = Utilities.AttributeFromAttributeData<CommandAttribute>(attrData);

                    if (Utilities.IsValidCommandName(attr.Name))
                    {
                        return Result.Err<ImmutableDictionary<string, CommandMethod>, Diagnostic>(Diagnostic.Create(
                            DiagnosticDescriptors.InvalidNamePassedToCommandAttribute,
                            AttributeSyntax.GetLocation(),
                            methodSymbol.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat)));
                    }

                    if (!dictionaryBuilder.ContainsKey(attr.Name)
                        || attr.Overwrite)
                    {
                        var commandMethod = CommandMethod.Create(attr, this, methodSymbol);
                        if (commandMethod.IsErr)
                            return Result.Err<ImmutableDictionary<string, CommandMethod>, Diagnostic>(commandMethod.Err.Value);
                        else
                            dictionaryBuilder[attr.Name] = commandMethod.Ok.Value;
                    }
                }
            }

            return Result.Ok<ImmutableDictionary<string, CommandMethod>, Diagnostic>(dictionaryBuilder.ToImmutable());
        }
예제 #25
0
        private static Outcome <(ImmutableArray <string>, Location)> ExtractRule(IMethodSymbol method, AttributeSyntax attribute)
        {
            var attributeArgs = attribute.ArgumentList?.Arguments;

            if (attributeArgs == null || attributeArgs.Value.Count < 2)
            {
                return(new Outcome <(ImmutableArray <string>, Location)>(Diagnostic.Create(
                                                                             Descriptors.LessThenTwoArguments,
                                                                             attribute.GetLocation())));
            }

            var allParameters = method.Parameters.ToImmutableDictionary(x => x.Name);

            var result = new List <string>();
            var errors = new List <Diagnostic>();

            foreach (var arg in attributeArgs.Value)
            {
                var name = arg.Expression.ToFullString().Trim('"');

                if (allParameters.ContainsKey(name))
                {
                    result.Add(name);
                }
                else
                {
                    errors.Add(Diagnostic.Create(Descriptors.ArgumentShouldReferAParameter, arg.GetLocation()));
                }
            }

            if (errors.Any())
            {
                return(new Outcome <(ImmutableArray <string>, Location)>(errors));
            }

            return(new Outcome <(ImmutableArray <string>, Location)>((result.ToImmutableArray(), attribute.GetLocation())));
        }
        private static void AnalyzeExpectedResult(SyntaxNodeAnalysisContext context,
                                                  AttributeSyntax attributeNode, IMethodSymbol methodSymbol)
        {
            var attributePositionalAndNamedArguments = attributeNode.GetArguments();
            var attributeNamedArguments = attributePositionalAndNamedArguments.Item2;

            var methodReturnValueType = methodSymbol.ReturnType;

            var expectedResultNamedArgument = attributeNamedArguments.SingleOrDefault(
                _ => _.DescendantTokens().Any(__ => __.Text == NunitFrameworkConstants.NameOfExpectedResult));

            if (expectedResultNamedArgument != null)
            {
                if (methodReturnValueType.SpecialType == SpecialType.System_Void)
                {
                    context.ReportDiagnostic(Diagnostic.Create(specifiedExpectedResultForVoid,
                                                               expectedResultNamedArgument.GetLocation()));
                }
                else
                {
                    if (!expectedResultNamedArgument.CanAssignTo(methodReturnValueType, context.SemanticModel))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(expectedResultTypeMismatch,
                                                                   expectedResultNamedArgument.GetLocation(), methodReturnValueType.MetadataName));
                    }
                }
            }
            else
            {
                if (methodReturnValueType.SpecialType != SpecialType.System_Void)
                {
                    context.ReportDiagnostic(Diagnostic.Create(noExpectedResultButNonVoidReturnType,
                                                               attributeNode.GetLocation()));
                }
            }
        }
예제 #27
0
        public override SyntaxNode VisitAttribute(AttributeSyntax node)
        {
            int id;
            string description;
            if (!BasicAttributeUtil.TryGetInformation(node, out id, out description))
            {
                return node;
            }

            var info = _workItemUtil.GetUpdatedWorkItemInfo(_filePath, node.GetLocation().GetMappedLineSpan(), id, description);
            if (info.HasValue)
            {
                node = BasicAttributeUtil.UpdateAttribute(node, info.Value.Id, info.Value.Description);
            }

            return node;
        }
예제 #28
0
        private AttributeSyntax TransformTestCaseSourceAttribute(AttributeSyntax node)
        {
            var location = node.GetLocation();

            // There are a number of possible overloads for the TestCaseDataAttribute,
            // for sanity, we currently support only two:
            //
            //  [TestCaseData(string sourceName)]
            //  [TestCaseData(Type sourceType, string sourceName)]

            bool   supported          = false;
            string targetName         = null;
            string targetType         = null;
            string explicitTargetType = null;

            if (node.ArgumentList != null)
            {
                int count = node.ArgumentList.Arguments.Count;
                if (count == 1)
                {
                    var arg0  = node.ArgumentList.Arguments[0];
                    var type0 = m_semanticModel.GetTypeInfo(arg0.Expression);
                    if (type0.ConvertedType?.SpecialType == SpecialType.System_String &&
                        (targetName = arg0.Expression.GetLiteralString()) != null)
                    {
                        supported  = true;
                        targetType = GetMethodContainingType(m_perMethodState.CurrentMethod);
                    }
                }
                else if (count == 2)
                {
                    var arg0  = node.ArgumentList.Arguments[0];
                    var arg1  = node.ArgumentList.Arguments[1];
                    var type0 = m_semanticModel.GetTypeInfo(arg0.Expression);
                    var type1 = m_semanticModel.GetTypeInfo(arg1.Expression);

                    if (m_semanticModel.TypeSymbolMatchesType(type0.ConvertedType, typeof(Type)) &&
                        arg0.Expression is TypeOfExpressionSyntax typeOfExpression &&
                        type1.ConvertedType?.SpecialType == SpecialType.System_String &&
                        (targetName = arg1.Expression.GetLiteralString()) != null)
                    {
                        targetType         = m_semanticModel.GetTypeInfo(typeOfExpression.Type).ConvertedType?.ToString();
                        explicitTargetType = targetType;
                        supported          = targetType != null;
                    }
                }
            }

            if (!supported)
            {
                m_diagnostics.Add(Diagnostic.Create(DiagnosticsDescriptors.UnsupportedAttributeUsage, location, node.Name,
                                                    "Specific syntax not supported."));
                return(node);
            }

            string sourceType;

            if (m_semanticModel.Compilation.FindSymbol <MethodDeclarationSyntax>(
                    symbol => symbol is IMethodSymbol method && method.Name == targetName && method.ContainingType.Name == targetType) != null)
            {
                sourceType = "DynamicDataSourceType.Method";
            }
예제 #29
0
        private SyntaxNode HandleAttribute(AttributeSyntax node)
        {
            var existing = m_semanticModel.GetSymbolInfo(node.Name);

            string existingTypeName = existing.Symbol?.ContainingType?.ToDisplayString();
            var    location         = node.GetLocation();
            var    originalNode     = node;

            try
            {
                switch (existingTypeName)
                {
                case "NUnit.Framework.SetUpAttribute":
                    WarnIfNotSuitableForTestInitialize("TestInitialize", location, true);
                    node = node.WithName(SyntaxFactory.IdentifierName("TestInitialize"));
                    break;

                case "NUnit.Framework.TearDownAttribute":
                    WarnIfNotSuitableForTestInitialize("TestCleanup", location, false);
                    node = node.WithName(SyntaxFactory.IdentifierName("TestCleanup"));
                    break;

                case "NUnit.Framework.OneTimeSetUpAttribute":
                    WarnIfNotSuitableForClassInitialize("ClassInitialize", location, true);
                    node = node.WithName(SyntaxFactory.IdentifierName("ClassInitialize"));
                    break;

                case "NUnit.Framework.OneTimeTearDownAttribute":
                    WarnIfNotSuitableForClassInitialize("ClassCleanup", location, false);
                    node = node.WithName(SyntaxFactory.IdentifierName("ClassCleanup"));
                    break;

                case "NUnit.Framework.PropertyAttribute":
                    node = node.WithName(SyntaxFactory.IdentifierName("TestProperty"))
                           .ConvertArgumentsToString(m_diagnostics, location);
                    break;

                case "NUnit.Framework.TimeoutAttribute":
                    node = node.WithName(SyntaxFactory.IdentifierName("Timeout"))
                           .WithoutArgumentList(m_diagnostics, location);
                    Changed = true;
                    break;

                case "NUnit.Framework.TestFixtureAttribute":
                    node = node.WithName(SyntaxFactory.IdentifierName("TestClass"))
                           .WithoutArgumentList(m_diagnostics, location);
                    Changed = true;
                    break;

                case "NUnit.Framework.TestCaseAttribute":
                    node = node.WithName(SyntaxFactory.IdentifierName("DataRow"))
                           .RenameNameEquals("TestName", "DisplayName");
                    m_perMethodState.DataRowSeen = true;
                    Changed = true;
                    break;

                case "NUnit.Framework.TestCaseSourceAttribute":
                    node    = TransformTestCaseSourceAttribute(node);
                    Changed = true;
                    break;

                case "NUnit.Framework.TestAttribute":
                    m_perMethodState.Description = node.GetNameEqualsExpression("Description");
                    node = node.WithName(SyntaxFactory.IdentifierName("TestMethod"))
                           .WithoutArgumentList(m_diagnostics, location, "Description");
                    Changed = true;
                    break;

                case "NUnit.Framework.CategoryAttribute":
                    node    = node.WithName(SyntaxFactory.IdentifierName("TestCategory"));
                    Changed = true;
                    break;

                case "NUnit.Framework.ExplicitAttribute":
                    node    = TransformExplicitAttribute(node);
                    Changed = true;
                    break;

                case "NUnit.Framework.IgnoreAttribute":
                    node = node.WithName(SyntaxFactory.IdentifierName("Ignore"))
                           .WithoutNameEquals("Until", m_diagnostics, location);
                    Changed = true;
                    break;

                case "NUnit.Framework.DescriptionAttribute"
                    // With MSTest DescriptionAttribute only supported on methods
                    when node.GetParentKind() == SyntaxKind.MethodDeclaration:
                    node = node.WithName(SyntaxFactory.IdentifierName("Description"));

                    Changed = true;
                    break;

                default:
                {
                    if (existingTypeName != null && existingTypeName.StartsWith("NUnit."))
                    {
                        // Replace (potential) unqualified name with qualified name.
                        // Otherwise, an attribute whose unqualified name is accidentally the same
                        // as that of some other, unrelated, attribute could semantically change (since we
                        // replace the "using NUnit.Framework" with "using <MSTest>").
                        var fullQualifiedName = SyntaxFactory.ParseName(existingTypeName);
                        m_diagnostics.Add(Diagnostic.Create(DiagnosticsDescriptors.UnsupportedAttribute, location,
                                                            node.ToFullString()));
                        node    = node.WithName(fullQualifiedName);
                        Changed = true;
                    }

                    break;
                }
                }

                return(node);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"Failed to process '{originalNode}' [{location}]: {ex.Message}", ex);
            }
        }
예제 #30
0
            /// <inheritdoc />
            public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
            {
                CancellationToken token  = cancellationToken;
                INamedTypeSymbol  symbol = semanticModel.GetDeclaredSymbol(node, token);

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

                int totalAttributes = 0;
                ImmutableArray <AttributeData> attrs = symbol.GetAttributes();

                if (attrs.IsDefaultOrEmpty)
                {
                    return(node);
                }

                SyntaxList <AttributeListSyntax> attributeLists = node.AttributeLists;

                for (int i = 0; i < attributeLists.Count; i++)
                {
                    AttributeListSyntax attributeList = attributeLists[i];
                    SeparatedSyntaxList <AttributeSyntax> attributes = attributeList.Attributes;

                    for (int j = 0; j < attributes.Count; j++, totalAttributes++)
                    {
                        AttributeSyntax attr     = attributes[j];
                        string          attrName = attr.Name.ToString();

                        if (attrName == "Component" || attrName == nameof(ComponentAttribute))
                        {
                            // There is a 'Component' attribute: Specify its content.
                            string contentStr = node.ToString();

                            // TODO: Use b64 and serialization
                            // It works, except Roslyn <= 2.0.0 has a bug with serialization
                            //using (MemoryStream ms = new MemoryStream())
                            //{
                            //    node.SerializeTo(ms, cancellationToken);

                            //    contentStr = ms.TryGetBuffer(out ArraySegment<byte> buffer)
                            //        ? Convert.ToBase64String(buffer.Array, buffer.Offset, buffer.Count)
                            //        : Convert.ToBase64String(ms.ToArray());
                            //}

                            AttributeArgumentSyntax contentArg = SyntaxFactory.AttributeArgument(
                                SyntaxFactory.LiteralExpression(
                                    SyntaxKind.StringLiteralExpression,
                                    SyntaxFactory.Literal(contentStr)
                                    )
                                );

                            node = node.WithAttributeLists(
                                attributeLists.Replace(
                                    attributeList,
                                    attributeList.WithAttributes(
                                        attributes.Replace(attr, attr.WithArgumentList(
                                                               SyntaxFactory.AttributeArgumentList().AddArguments(contentArg)
                                                               ))
                                        )
                                    )
                                );
                        }

                        // Maybe a component?
                        AttributeData attrData = attrs[totalAttributes];

                        if (attrData.AttributeClass.MetadataName == nameof(CopyFromAttribute))
                        {
                            // CopyFrom component: copy members
                            node = CopyMembers(node, attrData, token);
                        }
                        else if (InheritsCompositionAttribute(attrData.AttributeClass))
                        {
                            // Component: apply it
                            CompositionAttribute builtAttr = attrData.Construct <CompositionAttribute>();

                            try
                            {
                                node = builtAttr.Component.Apply(node, symbol, token);

                                if (node == null)
                                {
                                    throw new NullReferenceException("A component cannot return null.");
                                }
                            }
                            catch (Exception e)
                            {
                                throw new DiagnosticException($"Error applying the {builtAttr.Component} component.", e, attr.GetLocation());
                            }
                        }
                    }
                }

                return(node);
            }
예제 #31
0
        public static AttributeSyntax ConvertArgumentsToString(this AttributeSyntax node, List <Diagnostic> diagnostics = null, Location location = null)
        {
            var newList = new SeparatedSyntaxList <AttributeArgumentSyntax>();

            foreach (var entry in node.ArgumentList.Arguments)
            {
                if (entry.Expression.Kind() != SyntaxKind.StringLiteralExpression)
                {
                    var existingToken = entry.Expression.GetFirstToken();
                    diagnostics?.Add(Diagnostic.Create(DiagnosticsDescriptors.ConvertedArgumentValueToString, node.GetLocation(location), existingToken.ValueText));

                    var newEntry = entry.WithExpression(ToLiteralExpression(existingToken.Text, s_singleWhitespace, SyntaxTriviaList.Empty));
                    newList = newList.Add(newEntry);
                }
                else
                {
                    newList = newList.Add(entry);
                }
            }

            return(node.WithArgumentList(SyntaxFactory.AttributeArgumentList(newList)));
        }