internal override DiagnosticInfo GetResolvedInfo() { if (lazyActualObsoleteDiagnostic == null) { // A symbol's Obsoleteness may not have been calculated yet if the symbol is coming // from a different compilation's source. In that case, force completion of attributes. symbol.ForceCompleteObsoleteAttribute(); if (symbol.ObsoleteState == ThreeState.True) { var inObsoleteContext = ObsoleteAttributeHelpers.GetObsoleteContextState(containingSymbol, forceComplete: true); Debug.Assert(inObsoleteContext != ThreeState.Unknown); if (inObsoleteContext == ThreeState.False) { DiagnosticInfo info = ObsoleteAttributeHelpers.CreateObsoleteDiagnostic(symbol, binderFlags); if (info != null) { Interlocked.CompareExchange(ref this.lazyActualObsoleteDiagnostic, info, null); return(lazyActualObsoleteDiagnostic); } } } // If this symbol is not obsolete or is in an obsolete context, we don't want to report any diagnostics. // Therefore make this a Void diagnostic. Interlocked.CompareExchange(ref this.lazyActualObsoleteDiagnostic, CSDiagnosticInfo.VoidDiagnosticInfo, null); } return(lazyActualObsoleteDiagnostic); }
/// <returns> /// True if the symbol is definitely obsolete. /// False if the symbol is definitely not obsolete. /// Unknown if the symbol may be obsolete. /// /// NOTE: The return value reflects obsolete-ness, not whether or not the diagnostic was reported. /// </returns> private static ThreeState ReportDiagnosticsIfObsoleteInternal(DiagnosticBag diagnostics, Symbol symbol, SyntaxNodeOrToken node, Symbol containingMember, BinderFlags location) { Debug.Assert(diagnostics != null); if (symbol.ObsoleteState == ThreeState.False) { return(ThreeState.False); } var data = symbol.ObsoleteAttributeData; if (data == null) { // Obsolete attribute has errors. return(ThreeState.False); } // If we haven't cracked attributes on the symbol at all or we haven't // cracked attribute arguments enough to be able to report diagnostics for // ObsoleteAttribute, store the symbol so that we can report diagnostics at a // later stage. if (symbol.ObsoleteState == ThreeState.Unknown) { diagnostics.Add(new LazyObsoleteDiagnosticInfo(symbol, containingMember, location), node.GetLocation()); return(ThreeState.Unknown); } // After this point, always return True. var inObsoleteContext = ObsoleteAttributeHelpers.GetObsoleteContextState(containingMember); // If we are in a context that is already obsolete, there is no point reporting // more obsolete diagnostics. if (inObsoleteContext == ThreeState.True) { return(ThreeState.True); } // If the context is unknown, then store the symbol so that we can do this check at a // later stage else if (inObsoleteContext == ThreeState.Unknown) { diagnostics.Add(new LazyObsoleteDiagnosticInfo(symbol, containingMember, location), node.GetLocation()); return(ThreeState.True); } // We have all the information we need to report diagnostics right now. So do it. var diagInfo = ObsoleteAttributeHelpers.CreateObsoleteDiagnostic(symbol, location); if (diagInfo != null) { diagnostics.Add(diagInfo, node.GetLocation()); return(ThreeState.True); } return(ThreeState.True); }