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())); } } }
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); } } }
// The [FunctionName] attribute has an illegal function name. public static Diagnostic IllegalFunctionName(AttributeSyntax syntax, string value) { return(Diagnostic.Create(Rule4, syntax.GetLocation(), value )); }
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)); }
protected virtual void Analyze(SyntaxNodeAnalysisContext context, AttributeSyntax attributeSyntax) { var attributeLocation = attributeSyntax.GetLocation(); context.ReportDiagnostic(Diagnostic.Create( SupportedDiagnostics.First(), attributeLocation, attributeSyntax.Name.ToString())); }
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)); }
/// <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]}"); } }
/// <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()); }
/// <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)); }
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); }
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); }
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); } } }
/// <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)); }
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)); } }
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())); }
/// <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()); }
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())); } } }
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; }
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"; }
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); } }
/// <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); }
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))); }