private static bool TryGetThreadStaticAttribute(SyntaxList<AttributeListSyntax> attributeLists, SemanticModel semanticModel, out AttributeSyntax threadStaticAttribute) { threadStaticAttribute = null; if (!attributeLists.Any()) { return false; } foreach (var attributeList in attributeLists) { foreach (var attribute in attributeList.Attributes) { var attributeType = semanticModel.GetTypeInfo(attribute).Type; if (attributeType != null && attributeType.ToDisplayString() == ThreadStaticAttributeName) { threadStaticAttribute = attribute; return true; } } } return false; }
private static List<TestCase> ExtractMethodsFromAttributes(TestFixtureDetails testFixture, ISemanticModel semanticModel, AttributeSyntax attribute) { List<TestCase> methodTestCases=new List<TestCase>(); if (attribute.Name.ToString() == "Test") { var testCase = ExtractTest(attribute, testFixture); if (testCase != null) methodTestCases.Add(testCase); } else if (attribute.Name.ToString() == "TestCase") { var testCase = ExtractTestCase(attribute, testFixture, semanticModel); if (testCase != null) methodTestCases.Add(testCase); } else if (attribute.Name.ToString() == "SetUp") testFixture.TestSetUpMethodName = GetAttributeMethod(attribute).Identifier.ValueText; else if (attribute.Name.ToString() == "TestFixtureSetUp") testFixture.TestFixtureSetUpMethodName = GetAttributeMethod(attribute).Identifier.ValueText; else if (attribute.Name.ToString() == "TearDown") testFixture.TestTearDownMethodName = GetAttributeMethod(attribute).Identifier.ValueText; else if (attribute.Name.ToString() == "TestFixtureTearDown") testFixture.TestFixtureTearDownMethodName = GetAttributeMethod(attribute).Identifier.ValueText; return methodTestCases; }
private bool CompareAttributes( AttributeSyntax oldAttribute, AttributeSyntax newAttribute, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue) { Debug.Assert(oldAttribute != null && newAttribute != null); bool same = true; if (!CompareNames(oldAttribute.Name, newAttribute.Name)) { EnqueueChangeEvent(newAttribute, newNodeParent, CodeModelEventType.Rename, eventQueue); same = false; } // If arguments have changed enqueue a element changed (arguments changed) node if (!CompareAttributeArguments(oldAttribute.ArgumentList, newAttribute.ArgumentList)) { EnqueueChangeEvent(newAttribute, newNodeParent, CodeModelEventType.ArgChange, eventQueue); same = false; } return same; }
private static void ReportDiagnostic(SyntaxNodeAnalysisContext context, AttributeSyntax matchingNode) { context.ReportDiagnostic( Diagnostic.Create(Rule, DetermineDiagnosticTarget(matchingNode).GetLocation(), GetClassName(matchingNode))); }
public Property(SemanticModel model, PropertyDeclarationSyntax syntax, AttributeSyntax attribute = null, AttributeSyntax classAttribute = null) { this.model = model; Syntax = syntax; propertyAttribute = attribute; ClassAttribute = classAttribute; }
private static CSharpSyntaxNode DetermineDiagnosticTarget(AttributeSyntax attributeNode) { var attributesParentNode = (AttributeListSyntax)attributeNode.Parent; return ShouldKeepSquareBrackets(attributesParentNode) ? (CSharpSyntaxNode) attributeNode : attributesParentNode; }
public static glsl.QualifierSyntax Translate(this cs.AttributeSyntax node) { return(new glsl.QualifierSyntax() { Name = node.Name }); }
/// <summary> /// Creates a speculative AttributeSemanticModel that allows asking semantic questions about an attribute node that did not appear in the original source code. /// </summary> public static AttributeSemanticModel CreateSpeculative(SyntaxTreeSemanticModel parentSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder, int position) { Debug.Assert(parentSemanticModel != null); Debug.Assert(rootBinder != null); Debug.Assert(rootBinder.IsSemanticModelBinder); return new AttributeSemanticModel(parentSemanticModel.Compilation, syntax, attributeType, aliasOpt, rootBinder, parentSemanticModel, position); }
private static Task<Document> AddJustificationToAttributeAsync(Document document, SyntaxNode syntaxRoot, AttributeSyntax attribute) { var attributeName = SyntaxFactory.IdentifierName(nameof(SuppressMessageAttribute.Justification)); var newArgument = SyntaxFactory.AttributeArgument(SyntaxFactory.NameEquals(attributeName), null, GetNewAttributeValue()); var newArgumentList = attribute.ArgumentList.AddArguments(newArgument); return Task.FromResult(document.WithSyntaxRoot(syntaxRoot.ReplaceNode(attribute.ArgumentList, newArgumentList))); }
internal CSharpAttributeData GetAttribute(AttributeSyntax node, NamedTypeSymbol boundAttributeType, out bool generatedDiagnostics) { var dummyDiagnosticBag = DiagnosticBag.GetInstance(); var boundAttribute = base.GetAttribute(node, boundAttributeType, dummyDiagnosticBag); generatedDiagnostics = !dummyDiagnosticBag.IsEmptyWithoutResolution; dummyDiagnosticBag.Free(); return boundAttribute; }
private bool TryGetAttributeExpression(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, SignatureHelpTriggerReason triggerReason, CancellationToken cancellationToken, out AttributeSyntax attribute) { if (!CommonSignatureHelpUtilities.TryGetSyntax(root, position, syntaxFacts, triggerReason, IsTriggerToken, IsArgumentListToken, cancellationToken, out attribute)) { return false; } return attribute.ArgumentList != null; }
private static Tuple<ITypeSymbol, ITypeSymbol> GetSourceSymbols(SemanticModel semModel, AttributeSyntax mapperAttribute) { var attrArguments = mapperAttribute.ArgumentList.Arguments; var toExpr = attrArguments[0].Expression as TypeOfExpressionSyntax; var toMetadataExpr = attrArguments.Count > 1 ? attrArguments[1].Expression as TypeOfExpressionSyntax : null; var to = semModel.GetSymbolInfo(toExpr?.Type).Symbol as ITypeSymbol; var toMetadata = toMetadataExpr == null ? null : semModel.GetSymbolInfo(toMetadataExpr.Type).Symbol as ITypeSymbol; return Tuple.Create(to, toMetadata); }
/// <summary> /// Detects whether an attribute is a certain SharpSwift-specific Attribute (like [ExportAs]) /// </summary> /// <param name="attribute">The AttributeSyntax to check</param> /// <param name="expectingName">The attribute name you're looking for, or null to match all SharpSwift attributes</param> /// <returns>A boolean value representing whether it is or isn't the SharpSwift attribute</returns> private static bool IsSharpSwiftAttribute(AttributeSyntax attribute, string expectingName = null) { var symbol = Model.GetSymbolInfo(attribute.Name).Symbol; if (symbol == null) return false; var containingNamespace = symbol.ContainingSymbol.ContainingNamespace; var containingContainingNamespace = containingNamespace.ContainingNamespace; if (containingContainingNamespace == null) return false; return containingContainingNamespace.Name == "SharpSwift" && containingNamespace.Name == "Attributes" && (expectingName == null || symbol.ContainingSymbol.Name == expectingName); }
public static string AttributeSyntax(AttributeSyntax attribute) { var output = "@" + SyntaxNode(attribute.Name).TrimEnd('!'); if (IsSharpSwiftAttribute(attribute)) { return ""; } if (attribute.ArgumentList != null) { output += SyntaxNode(attribute.ArgumentList); } return output; }
private static TestCase ExtractTest(AttributeSyntax attribute, TestFixtureDetails testFixture) { var methodDeclarationSyntax = GetAttributeMethod(attribute); bool isAsync = IsAsync(methodDeclarationSyntax); if (isAsync && IsVoid(methodDeclarationSyntax)) return null; var testCase = new TestCase(testFixture) { SyntaxNode = methodDeclarationSyntax, IsAsync = isAsync, MethodName = methodDeclarationSyntax.Identifier.ValueText, Arguments = new string[0] }; return testCase; }
private static IEnumerable<Diagnostic> Analyze(AttributeSyntax mapperAttribute, SemanticModel semModel) { if (mapperAttribute?.Name.ToString() != "Mapper") { yield break; } var symbol = semModel.GetSymbolInfo(mapperAttribute).Symbol as IMethodSymbol; if (!symbol?.ToString().StartsWith("NCR.Engage.RoslynAnalysis.MapperAttribute") ?? true) { yield break; } var sourceClass = GetSourceSymbols(semModel, mapperAttribute); if (sourceClass == null) { yield break; } var sourceProperties = GetSourceProperties(semModel, sourceClass.Item1, sourceClass.Item2); var mapperClass = GetMapperClass(semModel, mapperAttribute); if (mapperClass == null) { yield break; } foreach (var sourceProperty in sourceProperties) { if (IsPropertyMentioned(sourceProperty, mapperAttribute)) { continue; } var sourcePropertyName = $"'{sourceProperty.Type} {sourceClass.Item1.Name}.{sourceProperty.Name}'"; var mapperClassName = $"'{mapperClass.Name}'"; yield return Diagnostic.Create(PropertyNotMapped, mapperAttribute.GetLocation(), sourcePropertyName, mapperClassName); } }
public AttributeInspector(AttributeSyntax attributeSyntax, SemanticModel semanticModel) { _attributeName = attributeSyntax.Name.ToString(); TypeInfo typeInfo = semanticModel.GetTypeInfo(attributeSyntax); ITypeSymbol typeSymbol = typeInfo.Type; _attributeQualifiedName = typeSymbol.ToString(); var unamedArguments = new List<string>(); var namedArguments = new Dictionary<string, string>(); if (attributeSyntax.ArgumentList != null) { foreach (AttributeArgumentSyntax attributeArgumentSyntax in attributeSyntax.ArgumentList.Arguments) { String argValue = attributeArgumentSyntax.Expression.ToString(); if (attributeArgumentSyntax.NameEquals != null) { string argName = attributeArgumentSyntax.NameEquals.Name.Identifier.Text; namedArguments.Add(argName, argValue); } else { // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (argValue.StartsWith("@")) { argValue = argValue.Remove(0, 1).Replace("\"\"", "\""); } else { argValue = Regex.Unescape(argValue); } argValue = argValue.Trim('"'); unamedArguments.Add(argValue); } } } _unamedArguments = unamedArguments.AsReadOnly(); _namedArguments = new ReadOnlyDictionary<string, string>(namedArguments); }
public static bool TryGetAttribute(this SyntaxList<AttributeListSyntax> attributeLists, KnownType attributeKnownType, SemanticModel semanticModel, out AttributeSyntax searchedAttribute) { searchedAttribute = null; if (!attributeLists.Any()) { return false; } foreach (var attribute in attributeLists.SelectMany(attributeList => attributeList.Attributes)) { var attributeType = semanticModel.GetTypeInfo(attribute).Type; if (attributeType.Is(attributeKnownType)) { searchedAttribute = attribute; return true; } } return false; }
private TypedConstant GetMatchingNamedOrOptionalConstructorArgument( out int matchingArgumentIndex, ImmutableArray<TypedConstant> constructorArgsArray, ImmutableArray<string> constructorArgumentNamesOpt, ParameterSymbol parameter, int startIndex, int argumentsCount, ref int argsConsumedCount, AttributeSyntax syntax, DiagnosticBag diagnostics) { int index = GetMatchingNamedConstructorArgumentIndex(parameter.Name, constructorArgumentNamesOpt, startIndex, argumentsCount); if (index < argumentsCount) { // found a matching named argument Debug.Assert(index >= startIndex); // increment argsConsumedCount argsConsumedCount++; matchingArgumentIndex = index; return constructorArgsArray[index]; } else { matchingArgumentIndex = -1; return GetDefaultValueArgument(parameter, syntax, diagnostics); } }
/// <summary> /// Gets the rewritten attribute constructor arguments, i.e. the arguments /// are in the order of parameters, which may differ from the source /// if named constructor arguments are used. /// /// For example: /// void Foo(int x, int y, int z, int w = 3); /// /// Foo(0, z: 2, y: 1); /// /// Arguments returned: 0, 1, 2, 3 /// </summary> /// <returns>Rewritten attribute constructor arguments</returns> /// <remarks> /// CONSIDER: Can we share some code will call rewriting in the local rewriter? /// </remarks> private ImmutableArray<TypedConstant> GetRewrittenAttributeConstructorArguments( out ImmutableArray<int> constructorArgumentsSourceIndices, MethodSymbol attributeConstructor, ImmutableArray<TypedConstant> constructorArgsArray, ImmutableArray<string> constructorArgumentNamesOpt, AttributeSyntax syntax, DiagnosticBag diagnostics, ref bool hasErrors) { Debug.Assert((object)attributeConstructor != null); Debug.Assert(!constructorArgsArray.IsDefault); Debug.Assert(!hasErrors); int argumentsCount = constructorArgsArray.Length; // argsConsumedCount keeps track of the number of constructor arguments // consumed from this.ConstructorArguments array int argsConsumedCount = 0; bool hasNamedCtorArguments = !constructorArgumentNamesOpt.IsDefault; Debug.Assert(!hasNamedCtorArguments || constructorArgumentNamesOpt.Length == argumentsCount); // index of the first named constructor argument int firstNamedArgIndex = -1; ImmutableArray<ParameterSymbol> parameters = attributeConstructor.Parameters; int parameterCount = parameters.Length; var reorderedArguments = new TypedConstant[parameterCount]; int[] sourceIndices = null; for (int i = 0; i < parameterCount; i++) { Debug.Assert(argsConsumedCount <= argumentsCount); ParameterSymbol parameter = parameters[i]; TypedConstant reorderedArgument; if (parameter.IsParams && parameter.Type.IsSZArray() && i + 1 == parameterCount) { reorderedArgument = GetParamArrayArgument(parameter, constructorArgsArray, argumentsCount, argsConsumedCount, this.Conversions); sourceIndices = sourceIndices ?? CreateSourceIndicesArray(i, parameterCount); } else if (argsConsumedCount < argumentsCount) { if (!hasNamedCtorArguments || constructorArgumentNamesOpt[argsConsumedCount] == null) { // positional constructor argument reorderedArgument = constructorArgsArray[argsConsumedCount]; if (sourceIndices != null) { sourceIndices[i] = argsConsumedCount; } argsConsumedCount++; } else { // named constructor argument // Store the index of the first named constructor argument if (firstNamedArgIndex == -1) { firstNamedArgIndex = argsConsumedCount; } // Current parameter must either have a matching named argument or a default value // For the former case, argsConsumedCount must be incremented to note that we have // consumed a named argument. For the latter case, argsConsumedCount stays same. int matchingArgumentIndex; reorderedArgument = GetMatchingNamedOrOptionalConstructorArgument(out matchingArgumentIndex, constructorArgsArray, constructorArgumentNamesOpt, parameter, firstNamedArgIndex, argumentsCount, ref argsConsumedCount, syntax, diagnostics); sourceIndices = sourceIndices ?? CreateSourceIndicesArray(i, parameterCount); sourceIndices[i] = matchingArgumentIndex; } } else { reorderedArgument = GetDefaultValueArgument(parameter, syntax, diagnostics); sourceIndices = sourceIndices ?? CreateSourceIndicesArray(i, parameterCount); } if (!hasErrors) { if (reorderedArgument.Kind == TypedConstantKind.Error) { hasErrors = true; } else if (reorderedArgument.Kind == TypedConstantKind.Array && parameter.Type.TypeKind == TypeKind.Array && (TypeSymbol)reorderedArgument.Type != parameter.Type) { // NOTE: As in dev11, we don't allow array covariance conversions (presumably, we don't have a way to // represent the conversion in metadata). diagnostics.Add(ErrorCode.ERR_BadAttributeArgument, syntax.Location); hasErrors = true; } } reorderedArguments[i] = reorderedArgument; } constructorArgumentsSourceIndices = sourceIndices != null ? sourceIndices.AsImmutableOrNull() : default(ImmutableArray<int>); return reorderedArguments.AsImmutableOrNull(); }
protected virtual MethodSymbol BindAttributeConstructor( AttributeSyntax node, NamedTypeSymbol attributeType, AnalyzedArguments boundConstructorArguments, DiagnosticBag diagnostics, ref LookupResultKind resultKind, bool suppressErrors, ref HashSet<DiagnosticInfo> useSiteDiagnostics) { MemberResolutionResult<MethodSymbol> memberResolutionResult; ImmutableArray<MethodSymbol> candidateConstructors; if (!TryPerformConstructorOverloadResolution( attributeType, boundConstructorArguments, attributeType.Name, node.Location, suppressErrors, //don't cascade in these cases diagnostics, out memberResolutionResult, out candidateConstructors, allowProtectedConstructorsOfBaseType: true)) { resultKind = resultKind.WorseResultKind( memberResolutionResult.IsValid && !IsConstructorAccessible(memberResolutionResult.Member, ref useSiteDiagnostics) ? LookupResultKind.Inaccessible : LookupResultKind.OverloadResolutionFailure); } return memberResolutionResult.Member; }
private BoundAttribute BindAttributeCore(AttributeSyntax node, NamedTypeSymbol attributeType, DiagnosticBag diagnostics) { Debug.Assert(this.SkipSemanticModelBinder() == this.GetBinder(node).SkipSemanticModelBinder()); // If attribute name bound to an error type with a single named type // candidate symbol, we want to bind the attribute constructor // and arguments with that named type to generate better semantic info. // CONSIDER: Do we need separate code paths for IDE and // CONSIDER: batch compilation scenarios? Above mentioned scenario // CONSIDER: is not useful for batch compilation. NamedTypeSymbol attributeTypeForBinding = attributeType; LookupResultKind resultKind = LookupResultKind.Viable; if (attributeTypeForBinding.IsErrorType()) { var errorType = (ErrorTypeSymbol)attributeTypeForBinding; resultKind = errorType.ResultKind; if (errorType.CandidateSymbols.Length == 1 && errorType.CandidateSymbols[0] is NamedTypeSymbol) { attributeTypeForBinding = (NamedTypeSymbol)errorType.CandidateSymbols[0]; } } // Bind constructor and named attribute arguments using the attribute binder var argumentListOpt = node.ArgumentList; Binder attributeArgumentBinder = this.WithAdditionalFlags(BinderFlags.AttributeArgument); AnalyzedAttributeArguments analyzedArguments = attributeArgumentBinder.BindAttributeArguments(argumentListOpt, attributeTypeForBinding, diagnostics); HashSet<DiagnosticInfo> useSiteDiagnostics = null; // Bind attributeType's constructor based on the bound constructor arguments MethodSymbol attributeConstructor = attributeTypeForBinding.IsErrorType() ? null : BindAttributeConstructor(node, attributeTypeForBinding, analyzedArguments.ConstructorArguments, diagnostics, ref resultKind, suppressErrors: attributeType.IsErrorType(), useSiteDiagnostics: ref useSiteDiagnostics); diagnostics.Add(node, useSiteDiagnostics); if ((object)attributeConstructor != null) { ReportDiagnosticsIfObsolete(diagnostics, attributeConstructor, node, hasBaseReceiver: false); } var constructorArguments = analyzedArguments.ConstructorArguments; ImmutableArray<BoundExpression> boundConstructorArguments = constructorArguments.Arguments.ToImmutableAndFree(); ImmutableArray<string> boundConstructorArgumentNamesOpt = constructorArguments.GetNames(); ImmutableArray<BoundExpression> boundNamedArguments = analyzedArguments.NamedArguments; constructorArguments.Free(); return new BoundAttribute(node, attributeConstructor, boundConstructorArguments, boundConstructorArgumentNamesOpt, boundNamedArguments, resultKind, attributeType, hasErrors: resultKind != LookupResultKind.Viable); }
internal BoundAttribute BindAttribute(AttributeSyntax node, NamedTypeSymbol attributeType, DiagnosticBag diagnostics) { return this.GetBinder(node).BindAttributeCore(node, attributeType, diagnostics); }
public override VisualBasicSyntaxNode VisitAttribute(CSS.AttributeSyntax node) { var list = (CSS.AttributeListSyntax)node.Parent; return(SyntaxFactory.Attribute((AttributeTargetSyntax)list.Target.Accept(this), (TypeSyntax)node.Name.Accept(this), (ArgumentListSyntax)node.ArgumentList?.Accept(this))); }
private Document Delete(Document document, AttributeSyntax node) { var attributeList = node.FirstAncestorOrSelf<AttributeListSyntax>(); // If we don't have anything left, then just delete the whole attribute list. if (attributeList.Attributes.Count == 1) { var text = document.GetTextAsync(CancellationToken.None) .WaitAndGetResult_CodeModel(CancellationToken.None); // Note that we want to keep all leading trivia and delete all trailing trivia. var deletionStart = attributeList.SpanStart; var deletionEnd = attributeList.FullSpan.End; text = text.Replace(TextSpan.FromBounds(deletionStart, deletionEnd), string.Empty); return document.WithText(text); } else { var newAttributeList = attributeList.RemoveNode(node, SyntaxRemoveOptions.KeepNoTrivia); return document.ReplaceNodeAsync(attributeList, newAttributeList, CancellationToken.None) .WaitAndGetResult_CodeModel(CancellationToken.None); } }
private void AddEventToEventQueueForAttributes(AttributeSyntax attribute, SyntaxNode parent, Action<SyntaxNode, SyntaxNode> enqueueAddOrRemoveEvent) { if (parent is BaseFieldDeclarationSyntax) { foreach (var variableDeclarator in ((BaseFieldDeclarationSyntax)parent).Declaration.Variables) { enqueueAddOrRemoveEvent(attribute, variableDeclarator); } } else { enqueueAddOrRemoveEvent(attribute, parent); } }
private static void ChangeEventQueueForAttributes(AttributeSyntax attribute, SyntaxNode parent, CodeModelEventType eventType, CodeModelEventQueue eventQueue) { if (parent is BaseFieldDeclarationSyntax) { foreach (var variableDeclarator in ((BaseFieldDeclarationSyntax)parent).Declaration.Variables) { eventQueue.EnqueueChangeEvent(attribute, variableDeclarator, eventType); } } else { eventQueue.EnqueueChangeEvent(attribute, parent, eventType); } }
private TypedConstant GetDefaultValueArgument(ParameterSymbol parameter, AttributeSyntax syntax, DiagnosticBag diagnostics) { var parameterType = parameter.Type; ConstantValue defaultConstantValue = parameter.IsOptional ? parameter.ExplicitDefaultConstantValue : ConstantValue.NotAvailable; TypedConstantKind kind; object defaultValue = null; if (!IsEarlyAttributeBinder && parameter.IsCallerLineNumber) { int line = syntax.SyntaxTree.GetDisplayLineNumber(syntax.Name.Span); kind = TypedConstantKind.Primitive; HashSet<DiagnosticInfo> useSiteDiagnostics = null; var conversion = Conversions.GetCallerLineNumberConversion(parameterType, ref useSiteDiagnostics); diagnostics.Add(syntax, useSiteDiagnostics); if (conversion.IsNumeric || conversion.IsConstantExpression) { // DoUncheckedConversion() keeps "single" floats as doubles internally to maintain higher // precision, so make sure they get cast to floats here. defaultValue = (parameterType.SpecialType == SpecialType.System_Single) ? (float)line : Binder.DoUncheckedConversion(parameterType.SpecialType, ConstantValue.Create(line)); } else { // Boxing or identity conversion: parameterType = Compilation.GetSpecialType(SpecialType.System_Int32); defaultValue = line; } } else if (!IsEarlyAttributeBinder && parameter.IsCallerFilePath) { parameterType = Compilation.GetSpecialType(SpecialType.System_String); kind = TypedConstantKind.Primitive; defaultValue = syntax.SyntaxTree.GetDisplayPath(syntax.Name.Span, Compilation.Options.SourceReferenceResolver); } else if (!IsEarlyAttributeBinder && parameter.IsCallerMemberName && (object)((ContextualAttributeBinder)this).AttributedMember != null) { parameterType = Compilation.GetSpecialType(SpecialType.System_String); kind = TypedConstantKind.Primitive; defaultValue = ((ContextualAttributeBinder)this).AttributedMember.GetMemberCallerName(); } else if (defaultConstantValue == ConstantValue.NotAvailable) { // There is no constant value given for the parameter in source/metadata. // For example, the attribute constructor with signature: M([Optional] int x), has no default value from syntax or attributes. // Default value for these cases is "default(parameterType)". // Optional parameter of System.Object type is treated specially though. // Native compiler treats "M([Optional] object x)" equivalent to "M(object x)" for attributes if parameter type is System.Object. // We generate a better diagnostic for this case by treating "x" in the above case as optional, but generating CS7067 instead. if (parameterType.SpecialType == SpecialType.System_Object) { // CS7067: Attribute constructor parameter '{0}' is optional, but no default parameter value was specified. diagnostics.Add(ErrorCode.ERR_BadAttributeParamDefaultArgument, syntax.Name.Location, parameter.Name); kind = TypedConstantKind.Error; } else { kind = TypedConstant.GetTypedConstantKind(parameterType, this.Compilation); Debug.Assert(kind != TypedConstantKind.Error); defaultConstantValue = parameterType.GetDefaultValue(); if (defaultConstantValue != null) { defaultValue = defaultConstantValue.Value; } } } else if (defaultConstantValue.IsBad) { // Constant value through syntax had errors, don't generate cascading diagnostics. kind = TypedConstantKind.Error; } else if (parameterType.SpecialType == SpecialType.System_Object && !defaultConstantValue.IsNull) { // error CS1763: '{0}' is of type '{1}'. A default parameter value of a reference type other than string can only be initialized with null diagnostics.Add(ErrorCode.ERR_NotNullRefDefaultParameter, syntax.Location, parameter.Name, parameterType); kind = TypedConstantKind.Error; } else { kind = TypedConstant.GetTypedConstantKind(parameterType, this.Compilation); Debug.Assert(kind != TypedConstantKind.Error); defaultValue = defaultConstantValue.Value; } if (kind == TypedConstantKind.Array) { Debug.Assert(defaultValue == null); return new TypedConstant(parameterType, default(ImmutableArray<TypedConstant>)); } else { return new TypedConstant(parameterType, kind, defaultValue); } }
public override SyntaxNode VisitAttribute(AttributeSyntax node) { _foundTestFixture |= _testsExtractor.IsAttributeTestFixture(node); return base.VisitAttribute(node); }
private void ValidateIndexerNameAttribute(CSharpAttributeData attribute, AttributeSyntax node, DiagnosticBag diagnostics) { if (!this.IsIndexer || this.IsExplicitInterfaceImplementation) { diagnostics.Add(ErrorCode.ERR_BadIndexerNameAttr, node.Name.Location, node.GetErrorDisplayName()); } else { string indexerName = attribute.CommonConstructorArguments[0].DecodeValue<string>(SpecialType.System_String); if (indexerName == null || !SyntaxFacts.IsValidIdentifier(indexerName)) { diagnostics.Add(ErrorCode.ERR_BadArgumentToAttribute, node.ArgumentList.Arguments[0].Location, node.GetErrorDisplayName()); } } }
internal CSharpAttributeData GetAttribute(AttributeSyntax node, NamedTypeSymbol boundAttributeType, DiagnosticBag diagnostics) { var boundAttribute = new ExecutableCodeBinder(node, this.ContainingMemberOrLambda, this).BindAttribute(node, boundAttributeType, diagnostics); return GetAttribute(boundAttribute, diagnostics); }
/// <summary> /// Validate attribute usage target and duplicate attributes. /// </summary> /// <param name="attribute">Bound attribute</param> /// <param name="node">Syntax node for attribute specification</param> /// <param name="compilation">Compilation</param> /// <param name="symbolPart">Symbol part to which the attribute has been applied.</param> /// <param name="diagnostics">Diagnostics</param> /// <param name="uniqueAttributeTypes">Set of unique attribute types applied to the symbol</param> private bool ValidateAttributeUsage( CSharpAttributeData attribute, AttributeSyntax node, CSharpCompilation compilation, AttributeLocation symbolPart, DiagnosticBag diagnostics, HashSet<NamedTypeSymbol> uniqueAttributeTypes) { Debug.Assert(!attribute.HasErrors); NamedTypeSymbol attributeType = attribute.AttributeClass; AttributeUsageInfo attributeUsageInfo = attributeType.GetAttributeUsageInfo(); // Given attribute can't be specified more than once if AllowMultiple is false. if (!uniqueAttributeTypes.Add(attributeType) && !attributeUsageInfo.AllowMultiple) { diagnostics.Add(ErrorCode.ERR_DuplicateAttribute, node.Name.Location, node.Name); return false; } // Verify if the attribute type can be applied to given owner symbol. AttributeTargets attributeTarget; if (symbolPart == AttributeLocation.Return) { // attribute on return type Debug.Assert(this.Kind == SymbolKind.Method); attributeTarget = AttributeTargets.ReturnValue; } else { attributeTarget = this.GetAttributeTarget(); } if ((attributeTarget & attributeUsageInfo.ValidTargets) == 0) { // generate error diagnostics.Add(ErrorCode.ERR_AttributeOnBadSymbolType, node.Name.Location, node.Name, attributeUsageInfo.GetValidTargetsErrorArgument()); return false; } if (attribute.IsSecurityAttribute(compilation)) { switch (this.Kind) { case SymbolKind.Assembly: case SymbolKind.NamedType: case SymbolKind.Method: break; default: // CS7070: Security attribute '{0}' is not valid on this declaration type. Security attributes are only valid on assembly, type and method declarations. diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidTarget, node.Name.Location, node.GetErrorDisplayName()); return false; } } return true; }