private List <SourceLabelSymbol> FindMatchingSwitchCaseLabels(ConstantValue constantValue, SyntaxNodeOrToken labelSyntax = default(SyntaxNodeOrToken)) { // SwitchLabelsMap: Dictionary for the switch case/default labels. // Case labels with a non-null constant value are indexed on their ConstantValue. // Invalid case labels with null constant value are indexed on the labelName. object key; if (constantValue != null) { key = constantValue; } else { key = labelSyntax.ToString(); } return(FindMatchingSwitchLabels(key)); }
/// <summary> /// Gets a list of all the diagnostics in either the sub tree that has the specified node as its root or /// associated with the token and its related trivia. /// </summary> /// <remarks> /// This method does not filter diagnostics based on <c>#pragma</c>s and compiler options /// like /nowarn, /warnaserror etc. /// </remarks> public override IEnumerable <Diagnostic> GetDiagnostics(SyntaxNodeOrToken nodeOrToken) { return(GetDiagnostics(nodeOrToken.UnderlyingNode, nodeOrToken.Position)); }
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(); } ThreeState reportedOnOverridden = 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. if (reportedOnOverridden != ThreeState.True && checkOverridingSymbol) { Debug.Assert(reportedOnOverridden != ThreeState.Unknown, "We forced attribute binding above."); ReportDiagnosticsIfObsoleteInternal(diagnostics, symbol, node, containingMember, location); } }
/// <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); }
/// <summary> /// Issue an error or warning for a symbol if it is Obsolete. If there is not enough /// information to report diagnostics, then store the symbols so that diagnostics /// can be reported at a later stage. /// </summary> internal void ReportDiagnosticsIfObsolete(DiagnosticBag diagnostics, Symbol symbol, SyntaxNodeOrToken node, bool hasBaseReceiver) { switch (symbol.Kind) { case SymbolKind.NamedType: case SymbolKind.Field: case SymbolKind.Method: case SymbolKind.Event: case SymbolKind.Property: ReportDiagnosticsIfObsolete(diagnostics, symbol, node, hasBaseReceiver, this.ContainingMemberOrLambda, this.ContainingType, this.Flags); break; } }
internal void ReportDiagnosticsIfObsolete(DiagnosticBag diagnostics, Conversion conversion, SyntaxNodeOrToken node, bool hasBaseReceiver) { if (conversion.IsValid && (object)conversion.Method != null) { ReportDiagnosticsIfObsolete(diagnostics, conversion.Method, node, hasBaseReceiver); } }
internal static void Error(DiagnosticBag diagnostics, ErrorCode code, SyntaxNodeOrToken syntax, params object[] args) { Error(diagnostics, code, syntax.GetLocation(), args); }
internal static void Error(DiagnosticBag diagnostics, ErrorCode code, SyntaxNodeOrToken syntax) { Error(diagnostics, code, syntax.GetLocation()); }
private static TextSpan CreateSpan(SyntaxTokenList startOpt, SyntaxNodeOrToken startFallbackOpt, SyntaxNodeOrToken endOpt) { Debug.Assert(startFallbackOpt != default(SyntaxNodeOrToken) || endOpt != default(SyntaxNodeOrToken)); int startPos; if (startOpt.Count > 0) { startPos = startOpt.First().SpanStart; } else if (startFallbackOpt != default(SyntaxNodeOrToken)) { startPos = startFallbackOpt.SpanStart; } else { startPos = endOpt.SpanStart; } int endPos; if (endOpt != default(SyntaxNodeOrToken)) { endPos = GetEndPosition(endOpt); } else { endPos = GetEndPosition(startFallbackOpt); } return(TextSpan.FromBounds(startPos, endPos)); }
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); }
public void TestAddInsertRemove() { var list = SyntaxFactory.NodeOrTokenList(SyntaxFactory.ParseToken("A "), SyntaxFactory.ParseToken("B "), SyntaxFactory.ParseToken("C ")); Assert.Equal(3, list.Count); Assert.Equal("A", list[0].ToString()); Assert.Equal("B", list[1].ToString()); Assert.Equal("C", list[2].ToString()); Assert.Equal("A B C ", list.ToFullString()); var elementA = list[0]; var elementB = list[1]; var elementC = list[2]; Assert.Equal(0, list.IndexOf(elementA)); Assert.Equal(1, list.IndexOf(elementB)); Assert.Equal(2, list.IndexOf(elementC)); SyntaxNodeOrToken tokenD = SyntaxFactory.ParseToken("D "); SyntaxNodeOrToken nameE = SyntaxFactory.ParseExpression("E "); var newList = list.Add(tokenD); Assert.Equal(4, newList.Count); Assert.Equal("A B C D ", newList.ToFullString()); newList = list.AddRange(new[] { tokenD, nameE }); Assert.Equal(5, newList.Count); Assert.Equal("A B C D E ", newList.ToFullString()); newList = list.Insert(0, tokenD); Assert.Equal(4, newList.Count); Assert.Equal("D A B C ", newList.ToFullString()); newList = list.Insert(1, tokenD); Assert.Equal(4, newList.Count); Assert.Equal("A D B C ", newList.ToFullString()); newList = list.Insert(2, tokenD); Assert.Equal(4, newList.Count); Assert.Equal("A B D C ", newList.ToFullString()); newList = list.Insert(3, tokenD); Assert.Equal(4, newList.Count); Assert.Equal("A B C D ", newList.ToFullString()); newList = list.InsertRange(0, new[] { tokenD, nameE }); Assert.Equal(5, newList.Count); Assert.Equal("D E A B C ", newList.ToFullString()); newList = list.InsertRange(1, new[] { tokenD, nameE }); Assert.Equal(5, newList.Count); Assert.Equal("A D E B C ", newList.ToFullString()); newList = list.InsertRange(2, new[] { tokenD, nameE }); Assert.Equal(5, newList.Count); Assert.Equal("A B D E C ", newList.ToFullString()); newList = list.InsertRange(3, new[] { tokenD, nameE }); Assert.Equal(5, newList.Count); Assert.Equal("A B C D E ", newList.ToFullString()); newList = list.RemoveAt(0); Assert.Equal(2, newList.Count); Assert.Equal("B C ", newList.ToFullString()); newList = list.RemoveAt(list.Count - 1); Assert.Equal(2, newList.Count); Assert.Equal("A B ", newList.ToFullString()); newList = list.Remove(elementA); Assert.Equal(2, newList.Count); Assert.Equal("B C ", newList.ToFullString()); newList = list.Remove(elementB); Assert.Equal(2, newList.Count); Assert.Equal("A C ", newList.ToFullString()); newList = list.Remove(elementC); Assert.Equal(2, newList.Count); Assert.Equal("A B ", newList.ToFullString()); newList = list.Replace(elementA, tokenD); Assert.Equal(3, newList.Count); Assert.Equal("D B C ", newList.ToFullString()); newList = list.Replace(elementB, tokenD); Assert.Equal(3, newList.Count); Assert.Equal("A D C ", newList.ToFullString()); newList = list.Replace(elementC, tokenD); Assert.Equal(3, newList.Count); Assert.Equal("A B D ", newList.ToFullString()); newList = list.ReplaceRange(elementA, new[] { tokenD, nameE }); Assert.Equal(4, newList.Count); Assert.Equal("D E B C ", newList.ToFullString()); newList = list.ReplaceRange(elementB, new[] { tokenD, nameE }); Assert.Equal(4, newList.Count); Assert.Equal("A D E C ", newList.ToFullString()); newList = list.ReplaceRange(elementC, new[] { tokenD, nameE }); Assert.Equal(4, newList.Count); Assert.Equal("A B D E ", newList.ToFullString()); newList = list.ReplaceRange(elementA, new SyntaxNodeOrToken[] { }); Assert.Equal(2, newList.Count); Assert.Equal("B C ", newList.ToFullString()); newList = list.ReplaceRange(elementB, new SyntaxNodeOrToken[] { }); Assert.Equal(2, newList.Count); Assert.Equal("A C ", newList.ToFullString()); newList = list.ReplaceRange(elementC, new SyntaxNodeOrToken[] { }); Assert.Equal(2, newList.Count); Assert.Equal("A B ", newList.ToFullString()); Assert.Equal(-1, list.IndexOf(tokenD)); Assert.Throws <ArgumentOutOfRangeException>(() => list.Insert(-1, tokenD)); Assert.Throws <ArgumentOutOfRangeException>(() => list.Insert(list.Count + 1, tokenD)); Assert.Throws <ArgumentOutOfRangeException>(() => list.InsertRange(-1, new[] { tokenD })); Assert.Throws <ArgumentOutOfRangeException>(() => list.InsertRange(list.Count + 1, new[] { tokenD })); Assert.Throws <ArgumentOutOfRangeException>(() => list.RemoveAt(-1)); Assert.Throws <ArgumentOutOfRangeException>(() => list.RemoveAt(list.Count)); Assert.Throws <ArgumentException>(() => list.Replace(tokenD, nameE)); Assert.Throws <ArgumentException>(() => list.ReplaceRange(tokenD, new[] { nameE })); Assert.Throws <ArgumentException>(() => list.Add(default(SyntaxNodeOrToken))); Assert.Throws <ArgumentException>(() => list.Insert(0, default(SyntaxNodeOrToken))); Assert.Throws <ArgumentNullException>(() => list.AddRange((IEnumerable <SyntaxNodeOrToken>)null)); Assert.Throws <ArgumentNullException>(() => list.InsertRange(0, (IEnumerable <SyntaxNodeOrToken>)null)); Assert.Throws <ArgumentNullException>(() => list.ReplaceRange(elementA, (IEnumerable <SyntaxNodeOrToken>)null)); }