FsAutoComplete icon indicating copy to clipboard operation
FsAutoComplete copied to clipboard

Go-to-definition decompiler puts `throw null` in bodies of all members/properties for refs libraries.

Open Krzysztof-Cieslak opened this issue 4 years ago • 4 comments

This happens on .Net Core / .Net Standard for any symbol which definition is added through reference library (for example netstandard.dll or System.Runtime).

Sample for float:

using System.Globalization;

namespace System
{
    public struct Double : IComparable, IComparable<double>, IConvertible, IEquatable<double>, IFormattable
    {
        public const double Epsilon = 4.94065645841247E-324;

        public const double MaxValue = 1.7976931348623157E+308;

        public const double MinValue = -1.7976931348623157E+308;

        public const double NaN = 0.0 / 0.0;

        public const double NegativeInfinity = -1.0 / 0.0;

        public const double PositiveInfinity = 1.0 / 0.0;

        public int CompareTo(double value)
        {
            throw null;
        }

        public int CompareTo(object value)
        {
            throw null;
        }

        public bool Equals(double obj)
        {
            throw null;
        }

        public override bool Equals(object obj)
        {
            throw null;
        }

        public override int GetHashCode()
        {
            throw null;
        }

        public TypeCode GetTypeCode()
        {
            throw null;
        }

        public static bool IsInfinity(double d)
        {
            throw null;
        }

        public static bool IsNaN(double d)
        {
            throw null;
        }

        public static bool IsNegativeInfinity(double d)
        {
            throw null;
        }

        public static bool IsPositiveInfinity(double d)
        {
            throw null;
        }

        public static bool operator ==(double left, double right)
        {
            throw null;
        }

        public static bool operator >(double left, double right)
        {
            throw null;
        }

        public static bool operator >=(double left, double right)
        {
            throw null;
        }

        public static bool operator !=(double left, double right)
        {
            throw null;
        }

        public static bool operator <(double left, double right)
        {
            throw null;
        }

        public static bool operator <=(double left, double right)
        {
            throw null;
        }

        public static double Parse(string s)
        {
            throw null;
        }

        public static double Parse(string s, NumberStyles style)
        {
            throw null;
        }

        public static double Parse(string s, NumberStyles style, IFormatProvider provider)
        {
            throw null;
        }

        public static double Parse(string s, IFormatProvider provider)
        {
            throw null;
        }

        bool IConvertible.ToBoolean(IFormatProvider provider)
        {
            throw null;
        }

        byte IConvertible.ToByte(IFormatProvider provider)
        {
            throw null;
        }

        char IConvertible.ToChar(IFormatProvider provider)
        {
            throw null;
        }

        DateTime IConvertible.ToDateTime(IFormatProvider provider)
        {
            throw null;
        }

        decimal IConvertible.ToDecimal(IFormatProvider provider)
        {
            throw null;
        }

        double IConvertible.ToDouble(IFormatProvider provider)
        {
            throw null;
        }

        short IConvertible.ToInt16(IFormatProvider provider)
        {
            throw null;
        }

        int IConvertible.ToInt32(IFormatProvider provider)
        {
            throw null;
        }

        long IConvertible.ToInt64(IFormatProvider provider)
        {
            throw null;
        }

        sbyte IConvertible.ToSByte(IFormatProvider provider)
        {
            throw null;
        }

        float IConvertible.ToSingle(IFormatProvider provider)
        {
            throw null;
        }

        object IConvertible.ToType(Type type, IFormatProvider provider)
        {
            throw null;
        }

        ushort IConvertible.ToUInt16(IFormatProvider provider)
        {
            throw null;
        }

        uint IConvertible.ToUInt32(IFormatProvider provider)
        {
            throw null;
        }

        ulong IConvertible.ToUInt64(IFormatProvider provider)
        {
            throw null;
        }

        public override string ToString()
        {
            throw null;
        }

        public string ToString(IFormatProvider provider)
        {
            throw null;
        }

        public string ToString(string format)
        {
            throw null;
        }

        public string ToString(string format, IFormatProvider provider)
        {
            throw null;
        }

        public static bool TryParse(string s, out double result)
        {
            result = 0.0;
            throw null;
        }

        public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out double result)
        {
            result = 0.0;
            throw null;
        }
    }
}

Krzysztof-Cieslak avatar Oct 18 '19 15:10 Krzysztof-Cieslak

Confirmed, if you decompile System.Private.Corelib you can see the actual definitions for those members^

baronfel avatar Oct 18 '19 15:10 baronfel

This is because we find the ref assembly instead of the actual implementation assembly. I don't know of any mechanism to find an implementation assembly given a ref assembly, at least not without doing more path probing....

baronfel avatar Nov 10 '19 01:11 baronfel

A potential solution to this might be using the new signature-file metadata view coming in FCS 40 for these lookups instead of the ICSharpCode decompiler. We may want to make that an option anyway.

baronfel avatar May 08 '21 16:05 baronfel

Roslyn has logic for handling this here.

baronfel avatar Jul 12 '22 20:07 baronfel