Example #1
0
 public OverrideInformation(MethodDefinition @base, MethodDefinition @override, ITryResolveMetadata resolver, InterfaceImplementation?matchingInterfaceImplementation = null)
 {
     Base     = @base;
     Override = @override;
     MatchingInterfaceImplementation = matchingInterfaceImplementation;
     this.resolver = resolver;
 }
        static string GetSignaturePart(TypeReference type, ITryResolveMetadata resolver)
        {
            var builder = new StringBuilder();

            DocumentationSignatureGenerator.PartVisitor.Instance.VisitTypeReference(type, builder, resolver);
            return(builder.ToString());
        }
Example #3
0
            public void VisitArrayType(ArrayType arrayType, StringBuilder builder, ITryResolveMetadata resolver)
            {
                VisitTypeReference(arrayType.ElementType, builder, resolver);

                // Rank-one arrays are displayed different than rectangular arrays
                if (arrayType.IsVector)
                {
                    builder.Append("[]");
                }
                else
                {
                    // C# arrays only support zero lower bounds
                    if (arrayType.Dimensions[0].LowerBound != 0)
                    {
                        throw new NotImplementedException();
                    }
                    builder.Append("[0:");
                    for (int i = 1; i < arrayType.Rank; i++)
                    {
                        if (arrayType.Dimensions[0].LowerBound != 0)
                        {
                            throw new NotImplementedException();
                        }
                        builder.Append(",0:");
                    }

                    builder.Append(']');
                }
            }
        public static IEnumerable <IMemberDefinition> GetMembersByDocumentationSignature(TypeDefinition type, string signature, ITryResolveMetadata resolver, bool acceptName = false)
        {
            int index       = 0;
            var results     = new List <IMemberDefinition> ();
            var nameBuilder = new StringBuilder();

            var(name, arity) = DocumentationSignatureParser.ParseTypeOrNamespaceName(signature, ref index, nameBuilder);
            DocumentationSignatureParser.GetMatchingMembers(signature, ref index, type.Module, type, name, arity, DocumentationSignatureParser.MemberType.All, results, resolver, acceptName);
            return(results);
        }
Example #5
0
            public void VisitMethodDefinition(MethodDefinition method, StringBuilder builder, ITryResolveMetadata resolver)
            {
                VisitTypeReference(method.DeclaringType, builder, resolver);
                builder.Append('.').Append(GetEscapedMetadataName(method));

                if (method.HasGenericParameters)
                {
                    builder.Append("``").Append(method.GenericParameters.Count);
                }

                if (method.HasParameters || (method.CallingConvention == MethodCallingConvention.VarArg))
                {
                    VisitParameters(method.Parameters, method.CallingConvention == MethodCallingConvention.VarArg, builder, resolver);
                }

                if (method.Name == "op_Implicit" || method.Name == "op_Explicit")
                {
                    builder.Append('~');
                    VisitTypeReference(method.ReturnType, builder, resolver);
                }
            }
Example #6
0
 public void VisitField(FieldDefinition field, StringBuilder builder, ITryResolveMetadata resolver)
 {
     VisitTypeReference(field.DeclaringType, builder, resolver);
     builder.Append('.').Append(field.Name);
 }
Example #7
0
 public void VisitByReferenceType(ByReferenceType byReferenceType, StringBuilder builder, ITryResolveMetadata resolver)
 {
     VisitTypeReference(byReferenceType.ElementType, builder, resolver);
     builder.Append('@');
 }
Example #8
0
            public void VisitTypeReference(TypeReference typeReference, StringBuilder builder, ITryResolveMetadata resolver)
            {
                switch (typeReference)
                {
                case ByReferenceType byReferenceType:
                    VisitByReferenceType(byReferenceType, builder, resolver);
                    return;

                case PointerType pointerType:
                    VisitPointerType(pointerType, builder, resolver);
                    return;

                case ArrayType arrayType:
                    VisitArrayType(arrayType, builder, resolver);
                    return;

                case GenericParameter genericParameter:
                    VisitGenericParameter(genericParameter, builder);
                    return;
                }

                if (typeReference.IsNested)
                {
                    Debug.Assert(typeReference is not SentinelType && typeReference is not PinnedType);
                    // GetInflatedDeclaringType may return null for generic parameters, byrefs, and pointers, but these
                    // are separately handled above.
                    VisitTypeReference(typeReference.GetInflatedDeclaringType(resolver) !, builder, resolver);
                    builder.Append('.');
                }

                if (!String.IsNullOrEmpty(typeReference.Namespace))
                {
                    builder.Append(typeReference.Namespace).Append('.');
                }

                // This includes '`n' for mangled generic types
                builder.Append(typeReference.Name);

                // For uninstantiated generic types (we already built the mangled name)
                // or non-generic types, we are done.
                if (typeReference.HasGenericParameters || typeReference is not GenericInstanceType genericInstance)
                {
                    return;
                }

                // Compute arity counting only the newly-introduced generic parameters
                var declaringType  = genericInstance.DeclaringType;
                var declaringArity = 0;

                if (declaringType != null && declaringType.HasGenericParameters)
                {
                    declaringArity = declaringType.GenericParameters.Count;
                }
                var totalArity = genericInstance.GenericArguments.Count;
                var arity      = totalArity - declaringArity;

                // Un-mangle the generic type name
                var suffixLength = arity.ToString().Length + 1;

                builder.Remove(builder.Length - suffixLength, suffixLength);

                // Append type arguments excluding arguments for re-declared parent generic parameters
                builder.Append('{');
                bool needsComma = false;

                for (int i = totalArity - arity; i < totalArity; ++i)
                {
                    if (needsComma)
                    {
                        builder.Append(',');
                    }
                    var typeArgument = genericInstance.GenericArguments[i];
                    VisitTypeReference(typeArgument, builder, resolver);
                    needsComma = true;
                }
                builder.Append('}');
            }
Example #9
0
            public void VisitProperty(PropertyDefinition property, StringBuilder builder, ITryResolveMetadata resolver)
            {
                VisitTypeReference(property.DeclaringType, builder, resolver);
                builder.Append('.').Append(GetEscapedMetadataName(property));

                if (property.Parameters.Count > 0)
                {
                    VisitParameters(property.Parameters, false, builder, resolver);
                }
            }
Example #10
0
 private static void VisitProperty(PropertyDefinition property, StringBuilder builder, ITryResolveMetadata resolver)
 {
     builder.Append(PropertyPrefix);
     PartVisitor.Instance.VisitProperty(property, builder, resolver);
 }
Example #11
0
        public static TypeReference GetInflatedDeclaringType(this TypeReference type, ITryResolveMetadata resolver)
        {
            if (type == null)
            {
                return(null);
            }

            if (type.IsGenericParameter || type.IsByReference || type.IsPointer)
            {
                return(null);
            }

            if (type is SentinelType sentinelType)
            {
                return(sentinelType.ElementType.GetInflatedDeclaringType(resolver));
            }

            if (type is PinnedType pinnedType)
            {
                return(pinnedType.ElementType.GetInflatedDeclaringType(resolver));
            }

            if (type is RequiredModifierType requiredModifierType)
            {
                return(requiredModifierType.ElementType.GetInflatedDeclaringType(resolver));
            }

            if (type is GenericInstanceType genericInstance)
            {
                var declaringType = genericInstance.DeclaringType;

                if (declaringType.HasGenericParameters)
                {
                    var result = new GenericInstanceType(declaringType);
                    for (var i = 0; i < declaringType.GenericParameters.Count; ++i)
                    {
                        result.GenericArguments.Add(genericInstance.GenericArguments[i]);
                    }

                    return(result);
                }

                return(declaringType);
            }

            var resolved = resolver.TryResolve(type);

            System.Diagnostics.Debug.Assert(resolved == type);
            return(resolved?.DeclaringType);
        }
        public static IEnumerable <(TypeReference InflatedInterface, InterfaceImplementation OriginalImpl)> GetInflatedInterfaces(this TypeReference typeRef, ITryResolveMetadata resolver)
        {
            var typeDef = resolver.TryResolve(typeRef);

            if (typeDef?.HasInterfaces != true)
            {
                yield break;
            }

            if (typeRef is GenericInstanceType genericInstance)
            {
                foreach (var interfaceImpl in typeDef.Interfaces)
                {
                    // InflateGenericType only returns null when inflating generic parameters (and the generic instance type doesn't resolve).
                    // Here we are not inflating a generic parameter but an interface type reference.
                    yield return((InflateGenericType(genericInstance, interfaceImpl.InterfaceType, resolver), interfaceImpl) !);
                }
            }
            else
            {
                foreach (var interfaceImpl in typeDef.Interfaces)
                {
                    yield return(interfaceImpl.InterfaceType, interfaceImpl);
                }
            }
        }
        static bool ParseDocumentationSignature(string id, ModuleDefinition module, List <IMemberDefinition> results, ITryResolveMetadata resolver)
        {
            if (id == null)
            {
                return(false);
            }

            if (id.Length < 2)
            {
                return(false);
            }

            int index = 0;

            results.Clear();
            ParseSignature(id, ref index, module, results, resolver);
            return(results.Count > 0);
        }
        static bool AllParametersMatch(Collection <ParameterDefinition> methodParameters, List <string> expectedParameters, ITryResolveMetadata resolver)
        {
            if (methodParameters.Count != expectedParameters.Count)
            {
                return(false);
            }

            for (int i = 0; i < expectedParameters.Count; i++)
            {
                if (GetSignaturePart(methodParameters[i].ParameterType, resolver) != expectedParameters[i])
                {
                    return(false);
                }
            }

            return(true);
        }
        static void GetMatchingProperties(string id, ref int index, TypeDefinition?type, string memberName, List <IMemberDefinition> results, ITryResolveMetadata resolver, bool acceptName = false)
        {
            if (type == null)
            {
                return;
            }

            int startIndex = index;
            int endIndex   = index;

            List <string>?parameters = null;

            // Unlike Roslyn, we don't need to decode property names because we are working
            // directly with IL.
            foreach (var property in type.Properties)
            {
                index = startIndex;
                if (property.Name != memberName)
                {
                    continue;
                }
                if (PeekNextChar(id, index) == '(')
                {
                    if (parameters == null)
                    {
                        parameters = new List <string> ();
                    }
                    else
                    {
                        parameters.Clear();
                    }
                    if (!ParseParameterList(id, ref index, property.DeclaringType, parameters))
                    {
                        continue;
                    }
                    if (!AllParametersMatch(property.Parameters, parameters, resolver))
                    {
                        continue;
                    }
                }
                else
                {
                    if (!acceptName && property.Parameters.Count != 0)
                    {
                        continue;
                    }
                }
                results.Add(property);
                endIndex = index;
            }

            index = endIndex;
        }
Example #16
0
 private static void VisitField(FieldDefinition field, StringBuilder builder, ITryResolveMetadata resolver)
 {
     builder.Append(FieldPrefix);
     PartVisitor.Instance.VisitField(field, builder, resolver);
 }
Example #17
0
 private static void VisitEvent(EventDefinition evt, StringBuilder builder, ITryResolveMetadata resolver)
 {
     builder.Append(EventPrefix);
     PartVisitor.Instance.VisitEvent(evt, builder, resolver);
 }
Example #18
0
        public static IEnumerable <(TypeReference InflatedInterface, InterfaceImplementation OriginalImpl)> GetInflatedInterfaces(this TypeReference typeRef, ITryResolveMetadata resolver)
        {
            var typeDef = resolver.TryResolve(typeRef);

            if (typeDef?.HasInterfaces != true)
            {
                yield break;
            }

            if (typeRef is GenericInstanceType genericInstance)
            {
                foreach (var interfaceImpl in typeDef.Interfaces)
                {
                    yield return(InflateGenericType(genericInstance, interfaceImpl.InterfaceType, resolver), interfaceImpl);
                }
            }
            else
            {
                foreach (var interfaceImpl in typeDef.Interfaces)
                {
                    yield return(interfaceImpl.InterfaceType, interfaceImpl);
                }
            }
        }
Example #19
0
 private static void VisitTypeDefinition(TypeDefinition type, StringBuilder builder, ITryResolveMetadata resolver)
 {
     builder.Append(TypePrefix);
     PartVisitor.Instance.VisitTypeReference(type, builder, resolver);
 }
Example #20
0
        public static TypeReference InflateGenericType(GenericInstanceType genericInstanceProvider, TypeReference typeToInflate, ITryResolveMetadata resolver)
        {
            if (typeToInflate is ArrayType arrayType)
            {
                var inflatedElementType = InflateGenericType(genericInstanceProvider, arrayType.ElementType, resolver);

                if (inflatedElementType != arrayType.ElementType)
                {
                    return(new ArrayType(inflatedElementType, arrayType.Rank));
                }

                return(arrayType);
            }

            if (typeToInflate is GenericInstanceType genericInst)
            {
                return(MakeGenericType(genericInstanceProvider, genericInst, resolver));
            }

            if (typeToInflate is GenericParameter genericParameter)
            {
                if (genericParameter.Owner is MethodReference)
                {
                    return(genericParameter);
                }

                var elementType = resolver.TryResolve(genericInstanceProvider.ElementType);
                if (elementType == null)
                {
                    return(null);
                }
                var parameter = elementType.GenericParameters.Single(p => p == genericParameter);
                return(genericInstanceProvider.GenericArguments[parameter.Position]);
            }

            if (typeToInflate is FunctionPointerType functionPointerType)
            {
                var result = new FunctionPointerType {
                    ReturnType = InflateGenericType(genericInstanceProvider, functionPointerType.ReturnType, resolver)
                };

                for (int i = 0; i < functionPointerType.Parameters.Count; i++)
                {
                    var inflatedParameterType = InflateGenericType(genericInstanceProvider, functionPointerType.Parameters[i].ParameterType, resolver);
                    result.Parameters.Add(new ParameterDefinition(inflatedParameterType));
                }

                return(result);
            }

            if (typeToInflate is IModifierType modifierType)
            {
                var modifier    = InflateGenericType(genericInstanceProvider, modifierType.ModifierType, resolver);
                var elementType = InflateGenericType(genericInstanceProvider, modifierType.ElementType, resolver);

                if (modifierType is OptionalModifierType)
                {
                    return(new OptionalModifierType(modifier, elementType));
                }

                return(new RequiredModifierType(modifier, elementType));
            }

            if (typeToInflate is PinnedType pinnedType)
            {
                var elementType = InflateGenericType(genericInstanceProvider, pinnedType.ElementType, resolver);

                if (elementType != pinnedType.ElementType)
                {
                    return(new PinnedType(elementType));
                }

                return(pinnedType);
            }

            if (typeToInflate is PointerType pointerType)
            {
                var elementType = InflateGenericType(genericInstanceProvider, pointerType.ElementType, resolver);

                if (elementType != pointerType.ElementType)
                {
                    return(new PointerType(elementType));
                }

                return(pointerType);
            }

            if (typeToInflate is ByReferenceType byReferenceType)
            {
                var elementType = InflateGenericType(genericInstanceProvider, byReferenceType.ElementType, resolver);

                if (elementType != byReferenceType.ElementType)
                {
                    return(new ByReferenceType(elementType));
                }

                return(byReferenceType);
            }

            if (typeToInflate is SentinelType sentinelType)
            {
                var elementType = InflateGenericType(genericInstanceProvider, sentinelType.ElementType, resolver);

                if (elementType != sentinelType.ElementType)
                {
                    return(new SentinelType(elementType));
                }

                return(sentinelType);
            }

            return(typeToInflate);
        }
Example #21
0
 public void VisitEvent(EventDefinition evt, StringBuilder builder, ITryResolveMetadata resolver)
 {
     VisitTypeReference(evt.DeclaringType, builder, resolver);
     builder.Append('.').Append(GetEscapedMetadataName(evt));
 }
Example #22
0
        private static GenericInstanceType MakeGenericType(GenericInstanceType genericInstanceProvider, GenericInstanceType type, ITryResolveMetadata resolver)
        {
            var result = new GenericInstanceType(type.ElementType);

            for (var i = 0; i < type.GenericArguments.Count; ++i)
            {
                result.GenericArguments.Add(InflateGenericType(genericInstanceProvider, type.GenericArguments[i], resolver));
            }

            return(result);
        }
Example #23
0
 public void VisitPointerType(PointerType pointerType, StringBuilder builder, ITryResolveMetadata resolver)
 {
     VisitTypeReference(pointerType.ElementType, builder, resolver);
     builder.Append('*');
 }
Example #24
0
        public static IEnumerable <MethodReference> GetMethods(this TypeReference type, ITryResolveMetadata resolver)
        {
            TypeDefinition typeDef = resolver.TryResolve(type);

            if (typeDef?.HasMethods != true)
            {
                yield break;
            }

            if (type is GenericInstanceType genericInstanceType)
            {
                foreach (var methodDef in typeDef.Methods)
                {
                    yield return(MakeMethodReferenceForGenericInstanceType(genericInstanceType, methodDef));
                }
            }
            else
            {
                foreach (var method in typeDef.Methods)
                {
                    yield return(method);
                }
            }
        }
Example #25
0
        public static bool IsSubclassOf(this TypeReference type, string ns, string name, ITryResolveMetadata resolver)
        {
            TypeDefinition baseType = resolver.TryResolve(type);

            while (baseType != null)
            {
                if (baseType.IsTypeOf(ns, name))
                {
                    return(true);
                }
                baseType = resolver.TryResolve(baseType.BaseType);
            }

            return(false);
        }
Example #26
0
        public static void VisitMember(IMemberDefinition member, StringBuilder builder, ITryResolveMetadata resolver)
        {
            switch (member.MetadataToken.TokenType)
            {
            case TokenType.TypeDef:
                VisitTypeDefinition((TypeDefinition)member, builder, resolver);
                break;

            case TokenType.Method:
                VisitMethod((MethodDefinition)member, builder, resolver);
                break;

            case TokenType.Property:
                VisitProperty((PropertyDefinition)member, builder, resolver);
                break;

            case TokenType.Field:
                VisitField((FieldDefinition)member, builder, resolver);
                break;

            case TokenType.Event:
                VisitEvent((EventDefinition)member, builder, resolver);
                break;

            default:
                break;
            }
        }
Example #27
0
            private void VisitParameters(IEnumerable <ParameterDefinition> parameters, bool isVararg, StringBuilder builder, ITryResolveMetadata resolver)
            {
                builder.Append('(');
                bool needsComma = false;

                foreach (var parameter in parameters)
                {
                    if (needsComma)
                    {
                        builder.Append(',');
                    }

                    // byrefs are tracked on the parameter type, not the parameter,
                    // so we don't have VisitParameter that Roslyn uses.
                    VisitTypeReference(parameter.ParameterType, builder, resolver);
                    needsComma = true;
                }

                // note: the C# doc comment generator outputs an extra comma for varargs
                // methods that also have fixed parameters
                if (isVararg && needsComma)
                {
                    builder.Append(',');
                }

                builder.Append(')');
            }
Example #28
0
 private static void VisitMethod(MethodDefinition method, StringBuilder builder, ITryResolveMetadata resolver)
 {
     builder.Append(MethodPrefix);
     PartVisitor.Instance.VisitMethodDefinition(method, builder, resolver);
 }
Example #29
0
        public static TypeDefinition?ResolveType(this ModuleDefinition module, string typeFullName, ITryResolveMetadata resolver)
        {
            var type = module.GetType(typeFullName);

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

            if (!module.HasExportedTypes)
            {
                return(null);
            }

            // When resolving a forwarded type from a string, typeFullName should be a simple type name.
            int idx = typeFullName.LastIndexOf('.');

            (string typeNamespace, string typeName) = idx > 0 ? (typeFullName.Substring(0, idx), typeFullName.Substring(idx + 1)) :
                                                      (string.Empty, typeFullName);

            TypeReference typeReference = new TypeReference(typeNamespace, typeName, module, module);

            return(resolver.TryResolve(typeReference));
        }
        static void GetMatchingMethods(string id, ref int index, TypeDefinition?type, string memberName, int arity, List <IMemberDefinition> results, ITryResolveMetadata resolver, bool acceptName = false)
        {
            if (type == null)
            {
                return;
            }

            var parameters = new List <string> ();
            var startIndex = index;
            var endIndex   = index;

            foreach (var method in type.Methods)
            {
                index = startIndex;
                if (method.Name != memberName)
                {
                    continue;
                }

                var methodArity = method.HasGenericParameters ? method.GenericParameters.Count : 0;
                if (methodArity != arity)
                {
                    continue;
                }

                parameters.Clear();
                bool isNameOnly = true;
                if (PeekNextChar(id, index) == '(')
                {
                    isNameOnly = false;
                    // if the parameters cannot be identified (some error), then the symbol cannot match, try next method symbol
                    if (!ParseParameterList(id, ref index, method, parameters))
                    {
                        continue;
                    }
                }

                // note: this allows extra characters at the end

                if (PeekNextChar(id, index) == '~')
                {
                    isNameOnly = false;
                    index++;
                    string?returnType = ParseTypeSymbol(id, ref index, method);
                    if (returnType == null)
                    {
                        continue;
                    }

                    // if return type is specified, then it must match
                    if (GetSignaturePart(method.ReturnType, resolver) != returnType)
                    {
                        continue;
                    }
                }

                if (!isNameOnly || !acceptName)
                {
                    // check parameters unless we are matching a name only
                    if (!AllParametersMatch(method.Parameters, parameters, resolver))
                    {
                        continue;
                    }
                }

                results.Add(method);
                endIndex = index;
            }
            index = endIndex;
        }