예제 #1
0
 private void CheckForAttributeWithArrayArgument(Symbol symbol)
 {
     System.Diagnostics.Debug.Assert(IsTrue(GetDeclaredOrInheritedCompliance(symbol)), "Only call on compliant symbols");
     CheckForAttributeWithArrayArgumentInternal(symbol.GetAttributes());
     if (symbol.Kind == SymbolKind.Method)
     {
         CheckForAttributeWithArrayArgumentInternal(((MethodSymbol)symbol).GetReturnTypeAttributes());
     }
 }
예제 #2
0
파일: Binder.cs 프로젝트: khm1600/CJing
        internal static void ReportDiagnosticsIfObsolete(
            DiagnosticBag diagnostics,
            Symbol symbol,
            SyntaxNodeOrToken node,
            bool hasBaseReceiver,
            Symbol containingMember,
            NamedTypeSymbol containingType,
            BinderFlags location)
        {
            Debug.Assert((object)symbol != null);

            Debug.Assert(symbol.Kind == SymbolKind.NamedType ||
                         symbol.Kind == SymbolKind.Field ||
                         symbol.Kind == SymbolKind.Method ||
                         symbol.Kind == SymbolKind.Event ||
                         symbol.Kind == SymbolKind.Property);

            // Dev11 also reports on the unconstructed method.  It would be nice to report on
            // the constructed method, but then we wouldn't be able to walk the override chain.
            if (symbol.Kind == SymbolKind.Method)
            {
                symbol = ((MethodSymbol)symbol).ConstructedFrom;
            }

            // There are two reasons to walk up to the least-overridden member:
            //   1) That's the method to which we will actually emit a call.
            //   2) We don't know what virtual dispatch will do at runtime so an
            //      overriding member is basically a shot in the dark.  Better to
            //      just be consistent and always use the least-overridden member.
            Symbol leastOverriddenSymbol = symbol.GetLeastOverriddenMember(containingType);

            bool checkOverridingSymbol = hasBaseReceiver && !ReferenceEquals(symbol, leastOverriddenSymbol);

            if (checkOverridingSymbol)
            {
                // If we have a base receiver, we must be done with declaration binding, so it should
                // be safe to decode diagnostics.  We want to do this since reporting for the overriding
                // member is conditional on reporting for the overridden member (i.e. we need a definite
                // answer so we don't double-report).  You might think that double reporting just results
                // in cascading diagnostics, but it's possible that the second diagnostic is an error
                // while the first is merely a warning.
                leastOverriddenSymbol.GetAttributes();
            }

            var diagnosticKind = ReportDiagnosticsIfObsoleteInternal(diagnostics, leastOverriddenSymbol, node, containingMember, location);

            // CONSIDER: In place of hasBaseReceiver, dev11 also accepts cases where symbol.ContainingType is a "simple type" (e.g. int)
            // or a special by-ref type (e.g. ArgumentHandle).  These cases are probably more important for other checks performed by
            // ExpressionBinder::PostBindMethod, but they do appear to ObsoleteAttribute as well.  We're skipping them because they
            // don't make much sense for ObsoleteAttribute (e.g. this would seem to address the case where int.ToString has been made
            // obsolete but object.ToString has not).

            // If the overridden member was not definitely obsolete and this is a (non-virtual) base member
            // access, then check the overriding symbol as well.
            switch (diagnosticKind)
            {
            case ObsoleteDiagnosticKind.NotObsolete:
            case ObsoleteDiagnosticKind.Lazy:
                if (checkOverridingSymbol)
                {
                    Debug.Assert(diagnosticKind != ObsoleteDiagnosticKind.Lazy, "We forced attribute binding above.");
                    ReportDiagnosticsIfObsoleteInternal(diagnostics, symbol, node, containingMember, location);
                }
                break;
            }
        }
예제 #3
0
        /// <remarks>
        /// As in dev11, we ignore the fact that CLSCompliantAttribute is inherited (i.e. from the base type)
        /// (see CSemanticChecker::CheckSymForCLS).  This should only affect types where the syntactic parent
        /// and the inheritance parent disagree.
        /// </remarks>
        private bool? GetDeclaredCompliance(Symbol symbol, out Location attributeLocation)
        {
            attributeLocation = null;
            foreach (CSharpAttributeData data in symbol.GetAttributes())
            {
                // Check signature before HasErrors to avoid realizing symbols for other attributes.
                if (data.IsTargetAttribute(symbol, AttributeDescription.CLSCompliantAttribute))
                {
                    NamedTypeSymbol attributeClass = data.AttributeClass;
                    if ((object)attributeClass != null)
                    {
                        DiagnosticInfo info = attributeClass.GetUseSiteDiagnostic();
                        if (info != null)
                        {
                            Location location = symbol.Locations.IsEmpty ? NoLocation.Singleton : symbol.Locations[0];
                            _diagnostics.Enqueue(new CSDiagnostic(info, location));
                            if (info.Severity >= DiagnosticSeverity.Error)
                            {
                                continue;
                            }
                        }
                    }

                    if (!data.HasErrors)
                    {
                        if (!TryGetAttributeWarningLocation(data, out attributeLocation))
                        {
                            attributeLocation = null;
                        }

                        ImmutableArray<TypedConstant> args = data.CommonConstructorArguments;
                        System.Diagnostics.Debug.Assert(args.Length == 1, "We already checked the signature and HasErrors.");

                        // Duplicates are reported elsewhere - we only care about the first (error-free) occurrence.
                        return (bool)args[0].Value;
                    }
                }
            }

            return null;
        }