Example #1
0
            // This shouldn't be necessary, but CCI is putting a nonzero TypeDefId in the ExportedTypes table
            // for nested types if NamespaceAliasForType.AliasedType is set to an ITypeDefinition
            // so we make an ITypeReference copy as a workaround.
            private static INamedTypeReference ConvertDefinitionToReferenceIfTypeIsNested(INamedTypeDefinition typeDef, IMetadataHost host)
            {
                var nestedTypeDef = typeDef as INestedTypeDefinition;

                if (nestedTypeDef == null)
                {
                    return(typeDef);
                }

                var typeRef = new NestedTypeReference();

                typeRef.Copy(nestedTypeDef, host.InternFactory);
                return(typeRef);
            }
Example #2
0
            private MetadataTypeReference GetTypeReferenceForForwardedType(NameSpec fullName)
            {
                if (assemblyReferencesByForwardedType == null)
                {
                    assemblyReferencesByForwardedType = new Dictionary <NameSpec, AssemblyReferenceHandle>();

                    foreach (var handle in reader.ExportedTypes)
                    {
                        var exportedType = reader.GetExportedType(handle);
                        if (!exportedType.IsForwarder)
                        {
                            continue;
                        }

                        if (exportedType.Implementation.Kind != HandleKind.AssemblyReference)
                        {
                            throw new NotImplementedException(exportedType.Implementation.Kind.ToString());
                        }

                        assemblyReferencesByForwardedType.Add(
                            new NameSpec(
                                reader.GetString(exportedType.Namespace),
                                reader.GetString(exportedType.Name),
                                nestedNames: null),
                            (AssemblyReferenceHandle)exportedType.Implementation);
                    }
                }

                if (assemblyReferencesByForwardedType.TryGetValue(new NameSpec(fullName.Namespace, fullName.TopLevelName, null), out var assemblyReferenceHandle))
                {
                    var current = (MetadataTypeReference) new TopLevelTypeReference(
                        reader
                        .GetAssemblyReference(assemblyReferenceHandle)
                        .GetAssemblyName(reader),
                        fullName.Namespace,
                        fullName.TopLevelName);

                    if (fullName.NestedNames != null)
                    {
                        foreach (var nestedName in fullName.NestedNames)
                        {
                            current = new NestedTypeReference(current, nestedName);
                        }
                    }

                    return(current);
                }

                return(null);
            }
        static int AppendParameterizedTypeName(StringBuilder b, ITypeReference type, IList <ITypeReference> typeArguments, ITypeResolveContext context)
        {
            GetClassTypeReference gctr = type as GetClassTypeReference;

            if (gctr != null)
            {
                if (!string.IsNullOrEmpty(gctr.Namespace))
                {
                    b.Append(gctr.Namespace);
                    b.Append('.');
                }
                b.Append(gctr.Name);
                if (gctr.TypeParameterCount > 0)
                {
                    b.Append('{');
                    for (int i = 0; i < gctr.TypeParameterCount && i < typeArguments.Count; i++)
                    {
                        if (i > 0)
                        {
                            b.Append(',');
                        }
                        AppendTypeName(b, typeArguments[i], context);
                    }
                    b.Append('}');
                }
                return(gctr.TypeParameterCount);
            }
            else
            {
                NestedTypeReference ntr = (NestedTypeReference)type;
                int outerTpc            = AppendParameterizedTypeName(b, ntr.DeclaringTypeReference, typeArguments, context);
                b.Append('.');
                if (ntr.AdditionalTypeParameterCount > 0)
                {
                    b.Append('{');
                    for (int i = 0; i < ntr.AdditionalTypeParameterCount && i + outerTpc < typeArguments.Count; i++)
                    {
                        if (i > 0)
                        {
                            b.Append(',');
                        }
                        AppendTypeName(b, typeArguments[i + outerTpc], context);
                    }
                    b.Append('}');
                }
                return(outerTpc + ntr.AdditionalTypeParameterCount);
            }
        }
        private static MetadataTypeReference GetTypeFromTypeReferenceHandle(MetadataReader reader, TypeReferenceHandle handle)
        {
            var nestedTypeNames = new List <StringHandle>();

            var type = reader.GetTypeReference(handle);

            while (type.ResolutionScope.Kind == HandleKind.TypeReference)
            {
                nestedTypeNames.Add(type.Name);
                type = reader.GetTypeReference((TypeReferenceHandle)type.ResolutionScope);
            }

            MetadataAssemblyReference assemblyReference;

            switch (type.ResolutionScope.Kind)
            {
            case HandleKind.ModuleReference:
                assemblyReference = null;
                break;

            case HandleKind.AssemblyReference:
                assemblyReference = reader.GetAssemblyReference((AssemblyReferenceHandle)type.ResolutionScope)
                                    .GetAssemblyName(reader);
                break;

            default:
                throw new NotImplementedException();
            }

            MetadataTypeReference current = new TopLevelTypeReference(
                assemblyReference,
                reader.GetString(type.Namespace),
                reader.GetString(type.Name));

            for (var i = nestedTypeNames.Count - 1; i >= 0; i--)
            {
                current = new NestedTypeReference(current, reader.GetString(nestedTypeNames[i]));
            }

            return(current);
        }
Example #5
0
        static ITypeReference ParseTypeName(string typeName, ref int pos)
        {
            string reflectionTypeName = typeName;

            if (pos == typeName.Length)
            {
                throw new ReflectionNameParseException(pos, "Unexpected end");
            }
            ITypeReference result;

            if (reflectionTypeName[pos] == '`')
            {
                // type parameter reference
                pos++;
                if (pos == reflectionTypeName.Length)
                {
                    throw new ReflectionNameParseException(pos, "Unexpected end");
                }
                if (reflectionTypeName[pos] == '`')
                {
                    // method type parameter reference
                    pos++;
                    int index = ReflectionHelper.ReadTypeParameterCount(reflectionTypeName, ref pos);
                    result = TypeParameterReference.Create(SymbolKind.Method, index);
                }
                else
                {
                    // class type parameter reference
                    int index = ReflectionHelper.ReadTypeParameterCount(reflectionTypeName, ref pos);
                    result = TypeParameterReference.Create(SymbolKind.TypeDefinition, index);
                }
            }
            else
            {
                // not a type parameter reference: read the actual type name
                List <ITypeReference> typeArguments = new List <ITypeReference>();
                int    typeParameterCount;
                string typeNameWithoutSuffix = ReadTypeName(typeName, ref pos, true, out typeParameterCount, typeArguments);
                result = new GetPotentiallyNestedClassTypeReference(typeNameWithoutSuffix, typeParameterCount);
                while (pos < typeName.Length && typeName[pos] == '.')
                {
                    pos++;
                    string nestedTypeName = ReadTypeName(typeName, ref pos, false, out typeParameterCount, typeArguments);
                    result = new NestedTypeReference(result, nestedTypeName, typeParameterCount);
                }
                if (typeArguments.Count > 0)
                {
                    result = new ParameterizedTypeReference(result, typeArguments);
                }
            }
            while (pos < typeName.Length)
            {
                switch (typeName[pos])
                {
                case '[':
                    int dimensions = 1;
                    do
                    {
                        pos++;
                        if (pos == typeName.Length)
                        {
                            throw new ReflectionNameParseException(pos, "Unexpected end");
                        }
                        if (typeName[pos] == ',')
                        {
                            dimensions++;
                        }
                    } while (typeName[pos] != ']');
                    result = new ArrayTypeReference(result, dimensions);
                    break;

                case '*':
                    result = new PointerTypeReference(result);
                    break;

                case '@':
                    result = new ByReferenceTypeReference(result);
                    break;

                default:
                    return(result);
                }
                pos++;
            }
            return(result);
        }
Example #6
0
        static ITypeReference ParseReflectionName(string reflectionTypeName, ref int pos, IEntity entity)
        {
            if (pos == reflectionTypeName.Length)
            {
                throw new ReflectionNameParseException(pos, "Unexpected end");
            }
            if (reflectionTypeName[pos] == '`')
            {
                // type parameter reference
                pos++;
                if (pos == reflectionTypeName.Length)
                {
                    throw new ReflectionNameParseException(pos, "Unexpected end");
                }
                if (reflectionTypeName[pos] == '`')
                {
                    // method type parameter reference
                    pos++;
                    int     index  = ReadTypeParameterCount(reflectionTypeName, ref pos);
                    IMethod method = entity as IMethod;
                    if (method != null && index >= 0 && index < method.TypeParameters.Count)
                    {
                        return(method.TypeParameters[index]);
                    }
                    else
                    {
                        return(SharedTypes.UnknownType);
                    }
                }
                else
                {
                    // class type parameter reference
                    int             index = ReadTypeParameterCount(reflectionTypeName, ref pos);
                    ITypeDefinition c     = (entity as ITypeDefinition) ?? (entity != null ? entity.DeclaringTypeDefinition : null);
                    if (c != null && index >= 0 && index < c.TypeParameters.Count)
                    {
                        return(c.TypeParameters[index]);
                    }
                    else
                    {
                        return(SharedTypes.UnknownType);
                    }
                }
            }
            // not a type parameter reference: read the actual type name
            int            tpc;
            string         typeName  = ReadTypeName(reflectionTypeName, ref pos, out tpc);
            ITypeReference reference = new GetClassTypeReference(typeName, tpc);

            // read type suffixes
            while (pos < reflectionTypeName.Length)
            {
                switch (reflectionTypeName[pos++])
                {
                case '+':
                    typeName  = ReadTypeName(reflectionTypeName, ref pos, out tpc);
                    reference = new NestedTypeReference(reference, typeName, tpc);
                    break;

                case '*':
                    reference = new PointerTypeReference(reference);
                    break;

                case '&':
                    reference = new ByReferenceTypeReference(reference);
                    break;

                case '[':
                    // this might be an array or a generic type
                    if (pos == reflectionTypeName.Length)
                    {
                        throw new ReflectionNameParseException(pos, "Unexpected end");
                    }
                    if (reflectionTypeName[pos] == '[')
                    {
                        // it's a generic type
                        List <ITypeReference> typeArguments = new List <ITypeReference>(tpc);
                        pos++;
                        typeArguments.Add(ParseReflectionName(reflectionTypeName, ref pos, entity));
                        if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']')
                        {
                            pos++;
                        }
                        else
                        {
                            throw new ReflectionNameParseException(pos, "Expected end of type argument");
                        }

                        while (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ',')
                        {
                            pos++;
                            if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == '[')
                            {
                                pos++;
                            }
                            else
                            {
                                throw new ReflectionNameParseException(pos, "Expected another type argument");
                            }

                            typeArguments.Add(ParseReflectionName(reflectionTypeName, ref pos, entity));

                            if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']')
                            {
                                pos++;
                            }
                            else
                            {
                                throw new ReflectionNameParseException(pos, "Expected end of type argument");
                            }
                        }

                        if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']')
                        {
                            pos++;
                            reference = new ParameterizedTypeReference(reference, typeArguments);
                        }
                        else
                        {
                            throw new ReflectionNameParseException(pos, "Expected end of generic type");
                        }
                    }
                    else
                    {
                        // it's an array
                        int dimensions = 1;
                        while (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ',')
                        {
                            dimensions++;
                            pos++;
                        }
                        if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']')
                        {
                            pos++;                                     // end of array
                            reference = new ArrayTypeReference(reference, dimensions);
                        }
                        else
                        {
                            throw new ReflectionNameParseException(pos, "Invalid array modifier");
                        }
                    }
                    break;

                case ',':
                    // assembly qualified name, ignore everything up to the end/next ']'
                    while (pos < reflectionTypeName.Length && reflectionTypeName[pos] != ']')
                    {
                        pos++;
                    }
                    break;

                default:
                    pos--;                             // reset pos to the character we couldn't read
                    if (reflectionTypeName[pos] == ']')
                    {
                        return(reference);                                // return from a nested generic
                    }
                    else
                    {
                        throw new ReflectionNameParseException(pos, "Unexpected character: '" + reflectionTypeName[pos] + "'");
                    }
                }
            }
            return(reference);
        }
Example #7
0
            // This shouldn't be necessary, but CCI is putting a nonzero TypeDefId in the ExportedTypes table
            // for nested types if NamespaceAliasForType.AliasedType is set to an ITypeDefinition
            // so we make an ITypeReference copy as a workaround.
            private static INamedTypeReference ConvertDefinitionToReferenceIfTypeIsNested(INamedTypeDefinition typeDef, IMetadataHost host)
            {
                var nestedTypeDef = typeDef as INestedTypeDefinition;
                if (nestedTypeDef == null)
                    return typeDef;

                var typeRef = new NestedTypeReference();
                typeRef.Copy(nestedTypeDef, host.InternFactory);
                return typeRef;
            }
Example #8
0
        static ITypeReference ParseReflectionName(string reflectionTypeName, ref int pos)
        {
            if (pos == reflectionTypeName.Length)
            {
                throw new ReflectionNameParseException(pos, "Unexpected end");
            }
            ITypeReference reference;

            if (reflectionTypeName[pos] == '`')
            {
                // type parameter reference
                pos++;
                if (pos == reflectionTypeName.Length)
                {
                    throw new ReflectionNameParseException(pos, "Unexpected end");
                }
                if (reflectionTypeName[pos] == '`')
                {
                    // method type parameter reference
                    pos++;
                    int index = ReadTypeParameterCount(reflectionTypeName, ref pos);
                    reference = TypeParameterReference.Create(SymbolKind.Method, index);
                }
                else
                {
                    // class type parameter reference
                    int index = ReadTypeParameterCount(reflectionTypeName, ref pos);
                    reference = TypeParameterReference.Create(SymbolKind.TypeDefinition, index);
                }
            }
            else
            {
                // not a type parameter reference: read the actual type name
                int    tpc;
                string typeName     = ReadTypeName(reflectionTypeName, ref pos, out tpc);
                string assemblyName = SkipAheadAndReadAssemblyName(reflectionTypeName, pos);
                reference = CreateGetClassTypeReference(assemblyName, typeName, tpc);
            }
            // read type suffixes
            while (pos < reflectionTypeName.Length)
            {
                switch (reflectionTypeName[pos++])
                {
                case '+':
                    int    tpc;
                    string typeName = ReadTypeName(reflectionTypeName, ref pos, out tpc);
                    reference = new NestedTypeReference(reference, typeName, tpc);
                    break;

                case '*':
                    reference = new PointerTypeReference(reference);
                    break;

                case '&':
                    reference = new ByReferenceTypeReference(reference);
                    break;

                case '[':
                    // this might be an array or a generic type
                    if (pos == reflectionTypeName.Length)
                    {
                        throw new ReflectionNameParseException(pos, "Unexpected end");
                    }
                    if (reflectionTypeName[pos] == '[')
                    {
                        // it's a generic type
                        List <ITypeReference> typeArguments = new List <ITypeReference>();
                        pos++;
                        typeArguments.Add(ParseReflectionName(reflectionTypeName, ref pos));
                        if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']')
                        {
                            pos++;
                        }
                        else
                        {
                            throw new ReflectionNameParseException(pos, "Expected end of type argument");
                        }

                        while (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ',')
                        {
                            pos++;
                            if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == '[')
                            {
                                pos++;
                            }
                            else
                            {
                                throw new ReflectionNameParseException(pos, "Expected another type argument");
                            }

                            typeArguments.Add(ParseReflectionName(reflectionTypeName, ref pos));

                            if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']')
                            {
                                pos++;
                            }
                            else
                            {
                                throw new ReflectionNameParseException(pos, "Expected end of type argument");
                            }
                        }

                        if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']')
                        {
                            pos++;
                            reference = new ParameterizedTypeReference(reference, typeArguments);
                        }
                        else
                        {
                            throw new ReflectionNameParseException(pos, "Expected end of generic type");
                        }
                    }
                    else
                    {
                        // it's an array
                        int dimensions = 1;
                        while (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ',')
                        {
                            dimensions++;
                            pos++;
                        }
                        if (pos < reflectionTypeName.Length && reflectionTypeName[pos] == ']')
                        {
                            pos++;                                     // end of array
                            reference = new ArrayTypeReference(reference, dimensions);
                        }
                        else
                        {
                            throw new ReflectionNameParseException(pos, "Invalid array modifier");
                        }
                    }
                    break;

                case ',':
                    // assembly qualified name, ignore everything up to the end/next ']'
                    while (pos < reflectionTypeName.Length && reflectionTypeName[pos] != ']')
                    {
                        pos++;
                    }
                    break;

                default:
                    pos--;                             // reset pos to the character we couldn't read
                    if (reflectionTypeName[pos] == ']')
                    {
                        return(reference);                                // return from a nested generic
                    }
                    else
                    {
                        throw new ReflectionNameParseException(pos, "Unexpected character: '" + reflectionTypeName[pos] + "'");
                    }
                }
            }
            return(reference);
        }
        static void AppendTypeName(StringBuilder b, ITypeReference type, ITypeResolveContext context)
        {
            IType resolvedType = type as IType;

            if (resolvedType != null)
            {
                AppendTypeName(b, resolvedType);
                return;
            }
            GetClassTypeReference gctr = type as GetClassTypeReference;

            if (gctr != null)
            {
                if (!string.IsNullOrEmpty(gctr.Namespace))
                {
                    b.Append(gctr.Namespace);
                    b.Append('.');
                }
                b.Append(gctr.Name);
                if (gctr.TypeParameterCount > 0)
                {
                    b.Append('`');
                    b.Append(gctr.TypeParameterCount);
                }
                return;
            }
            NestedTypeReference ntr = type as NestedTypeReference;

            if (ntr != null)
            {
                AppendTypeName(b, ntr.DeclaringTypeReference, context);
                b.Append('.');
                b.Append(ntr.Name);
                if (ntr.AdditionalTypeParameterCount > 0)
                {
                    b.Append('`');
                    b.Append(ntr.AdditionalTypeParameterCount);
                }
                return;
            }
            ParameterizedTypeReference pt = type as ParameterizedTypeReference;

            if (pt != null && IsGetClassTypeReference(pt.GenericType))
            {
                AppendParameterizedTypeName(b, pt.GenericType, pt.TypeArguments, context);
                return;
            }
            ArrayTypeReference array = type as ArrayTypeReference;

            if (array != null)
            {
                AppendTypeName(b, array.ElementType, context);
                b.Append('[');
                if (array.Dimensions > 1)
                {
                    for (int i = 0; i < array.Dimensions; i++)
                    {
                        if (i > 0)
                        {
                            b.Append(',');
                        }
                        b.Append("0:");
                    }
                }
                b.Append(']');
                return;
            }
            PointerTypeReference ptr = type as PointerTypeReference;

            if (ptr != null)
            {
                AppendTypeName(b, ptr.ElementType, context);
                b.Append('*');
                return;
            }
            ByReferenceTypeReference brtr = type as ByReferenceTypeReference;

            if (brtr != null)
            {
                AppendTypeName(b, brtr.ElementType, context);
                b.Append('@');
                return;
            }
            if (context == null)
            {
                b.Append('?');
            }
            else
            {
                AppendTypeName(b, type.Resolve(context));
            }
        }
Example #10
0
 public ImmutableNode <string> Visit(NestedTypeReference nestedTypeReference)
 {
     return(new ImmutableNode <string>(nestedTypeReference.DeclaringType.Accept(this), ".", BuildNameWithArity(nestedTypeReference.Name)));
 }