Example #1
0
        public static string GetMemberName(this IMethodSymbol method)
        {
            var nameOverride = method.GetAttributeValue <string>(Context.Instance.JsAttributeType, "Name");

            if (nameOverride != null)
            {
                return(nameOverride);
            }

            if (method.ReducedFrom != null)
            {
                method = method.ReducedFrom;
            }
            if (!Equals(method.ConstructedFrom, method))
            {
                method = method.ConstructedFrom;
            }

            var baseMethodName = method.MethodKind == MethodKind.Constructor ? "$ctor" : method.Name.Replace('.', '$');

            if (method.ContainingType.TypeKind == TypeKind.Interface)
            {
                baseMethodName = method.ContainingType.GetTypeName().MaskSpecialCharacters() + "$" + baseMethodName;
            }

            baseMethodName = baseMethodName.MaskSpecialCharacters();

            var overloads = method.MethodKind == MethodKind.Constructor ?
                            method.ContainingType.InstanceConstructors.ToList() :
                            method.ContainingType
                            .GetAllMembers(method.Name)
                            .OfType <IMethodSymbol>()
                            // De-dup overrides from overloads, since we only want one name for a given override chain.
                            .Where(x => x.OverriddenMethod == null).ToList();

            if (overloads.Count == 1 || (method.MethodKind == MethodKind.Constructor && !method.Parameters.Any()))
            {
                return(baseMethodName);
            }
            else
            {
                // Sort overloads based on a constant algorithm where overloads from base types
                overloads.Sort((x, y) =>
                {
                    var xIsExported = x.DeclaredAccessibility == Accessibility.Protected || x.DeclaredAccessibility == Accessibility.ProtectedAndInternal || x.DeclaredAccessibility == Accessibility.ProtectedOrInternal || x.DeclaredAccessibility == Accessibility.Public;
                    var yIsExported = y.DeclaredAccessibility == Accessibility.Protected || y.DeclaredAccessibility == Accessibility.ProtectedAndInternal || y.DeclaredAccessibility == Accessibility.ProtectedOrInternal || y.DeclaredAccessibility == Accessibility.Public;
                    if (xIsExported != yIsExported)
                    {
                        return(xIsExported ? -1 : 1);
                    }
                    else if (x.ContainingType.IsSubclassOf(y.ContainingType))
                    {
                        return(1);
                    }
                    else if (y.ContainingType.IsSubclassOf(x.ContainingType))
                    {
                        return(-1);
                    }
                    else
                    {
                        var xMethod = x;
                        var yMethod = y;
                        if (xMethod.TypeParameters.Count() > yMethod.TypeParameters.Count())
                        {
                            return(1);
                        }
                        else if (xMethod.TypeParameters.Count() < yMethod.TypeParameters.Count())
                        {
                            return(-1);
                        }
                        else
                        {
                            if (xMethod.Parameters.Count() > yMethod.Parameters.Count())
                            {
                                return(1);
                            }
                            else if (xMethod.Parameters.Count() < yMethod.Parameters.Count())
                            {
                                return(-1);
                            }
                            else
                            {
                                if (xMethod.ExplicitInterfaceImplementations.Count() > yMethod.ExplicitInterfaceImplementations.Count())
                                {
                                    return(1);
                                }
                                else if (xMethod.ExplicitInterfaceImplementations.Count() < yMethod.ExplicitInterfaceImplementations.Count())
                                {
                                    return(-1);
                                }
                                else
                                {
                                    for (var i = 0; i < xMethod.Parameters.Count(); i++)
                                    {
                                        var xParameter = xMethod.Parameters[i];
                                        var yParameter = yMethod.Parameters[i];
                                        var result     = string.Compare(xParameter.Type.ToString(), yParameter.Type.ToString(), StringComparison.Ordinal);
                                        if (result != 0)
                                        {
                                            return(result);
                                        }
                                    }
                                }
                            }
                        }
                        return(string.Compare(x.ContainingType.ToString(), y.ContainingType.ToString(), StringComparison.Ordinal));
                    }
                });
                var indexOf = overloads.IndexOf(method.GetRootOverride());
                if (indexOf == -1)
                {
                    throw new Exception();
                }
                if (indexOf == 0)
                {
                    return(baseMethodName);          // If a type starts out with only one method, it will not have any $ suffix.  That means the first instance of an overload/override will always be naked.
                }
                else
                {
                    return(baseMethodName + "$" + indexOf);
                }
            }
        }
Example #2
0
 public override object GetAttributeValue <TAttribute>(string valueName) =>
 Symbol.GetAttributeValue <TAttribute>(valueName);