private Binder(Binder next, BinderFlags flags) { Debug.Assert(next != null); _next = next; this.Flags = flags; _compilation = next._compilation; }
public static void ReportDiagnosticsIfObsolete( DiagnosticBag diagnostics, Symbol symbol, SyntaxNodeOrToken node, bool hasBaseReceiver, Symbol containingMember, NamedTypeSymbol containingType, BinderFlags location) { Debug.Assert((object)symbol != null); // 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 is MemberSymbol memberSymbol) { symbol = 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.GetConstructedLeastOverriddenMember(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; } }
public Binder WithFlags(params BinderFlags[] flags) { BinderFlags union = FlagsObject.Union <BinderFlags>(flags); return(this.Flags == union ? this : new Binder(this, union)); }
public Binder(Binder next, Conversions conversions = null) { Debug.Assert(next != null); _next = next; this.Flags = next.Flags; _compilation = next._compilation; _lazyConversions = conversions; }
internal static ObsoleteDiagnosticKind ReportDiagnosticsIfObsoleteInternal(DiagnosticBag diagnostics, Symbol symbol, SyntaxNodeOrToken node, Symbol containingMember, BinderFlags location) { Debug.Assert(diagnostics != null); var kind = ObsoleteAttributeHelpers.GetObsoleteDiagnosticKind(symbol, containingMember); DiagnosticInfo info = null; switch (kind) { case ObsoleteDiagnosticKind.Diagnostic: info = ObsoleteAttributeHelpers.CreateObsoleteDiagnostic(symbol, location); break; case ObsoleteDiagnosticKind.Lazy: case ObsoleteDiagnosticKind.LazyPotentiallySuppressed: info = new LazyObsoleteDiagnosticInfo(symbol, containingMember, location); break; } if (info != null) { diagnostics.Add(info, node.GetLocation()); } return(kind); }
/// <summary> /// Used to create a root binder. /// </summary> public Binder(LanguageCompilation compilation) { Debug.Assert(compilation != null); this.Flags = compilation.Options.TopLevelBinderFlags; _compilation = compilation; }