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;
 }
예제 #7
0
 public static glsl.QualifierSyntax Translate(this cs.AttributeSyntax node)
 {
     return(new glsl.QualifierSyntax()
     {
         Name = node.Name
     });
 }
예제 #8
0
        /// <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);
        }
예제 #13
0
        /// <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);
        }
예제 #14
0
        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);
        }
예제 #18
0
        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;
        }
예제 #19
0
        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);
            }
        }
예제 #20
0
        /// <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();
        }
예제 #21
0
        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;
        }
예제 #22
0
        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);
        }
예제 #23
0
 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);
     }
 }
예제 #28
0
        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);
 }
예제 #30
0
 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());
         }
     }
 }
예제 #31
0
        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);
        }
예제 #32
0
        /// <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;
        }