Beispiel #1
0
        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));
 }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
 /// <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;
     }
 }
Beispiel #6
0
 internal void ReportDiagnosticsIfObsolete(DiagnosticBag diagnostics, Conversion conversion, SyntaxNodeOrToken node, bool hasBaseReceiver)
 {
     if (conversion.IsValid && (object)conversion.Method != null)
     {
         ReportDiagnosticsIfObsolete(diagnostics, conversion.Method, node, hasBaseReceiver);
     }
 }
Beispiel #7
0
 internal static void Error(DiagnosticBag diagnostics, ErrorCode code, SyntaxNodeOrToken syntax, params object[] args)
 {
     Error(diagnostics, code, syntax.GetLocation(), args);
 }
Beispiel #8
0
 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));
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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));
        }