public override IUnresolvedEntity VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration, object data) { DefaultUnresolvedField field = new DefaultUnresolvedField(currentTypeDefinition, enumMemberDeclaration.Name); field.Region = field.BodyRegion = MakeRegion(enumMemberDeclaration); ConvertAttributes(field.Attributes, enumMemberDeclaration.Attributes); if (currentTypeDefinition.TypeParameters.Count == 0) { field.ReturnType = currentTypeDefinition; } else { ITypeReference[] typeArgs = new ITypeReference[currentTypeDefinition.TypeParameters.Count]; for (int i = 0; i < typeArgs.Length; i++) { typeArgs[i] = new TypeParameterReference(EntityType.TypeDefinition, i); } field.ReturnType = new ParameterizedTypeReference(currentTypeDefinition, typeArgs); } field.Accessibility = Accessibility.Public; field.IsStatic = true; if (!enumMemberDeclaration.Initializer.IsNull) { field.ConstantValue = ConvertConstantValue(field.ReturnType, enumMemberDeclaration.Initializer); } else { DefaultUnresolvedField prevField = currentTypeDefinition.Members.LastOrDefault() as DefaultUnresolvedField; if (prevField == null || prevField.ConstantValue == null) { field.ConstantValue = ConvertConstantValue(field.ReturnType, new PrimitiveExpression(0)); } else { field.ConstantValue = new IncrementConstantValue(prevField.ConstantValue); } } currentTypeDefinition.Members.Add(field); if (interningProvider != null) { field.ApplyInterningProvider(interningProvider); } return field; }
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); }
/// <summary> /// Creates a reference to the specified type. /// </summary> /// <param name="type">The type to be converted.</param> /// <returns>Returns the type reference.</returns> /// <remarks> /// If the type is open (contains type parameters '`0' or '``0'), /// an <see cref="ITypeResolveContext"/> with the appropriate CurrentTypeDefinition/CurrentMember is required /// to resolve the type reference. /// For closed types, the root type resolve context for the compilation is sufficient. /// </remarks> public static ITypeReference ToTypeReference(this Type type) { if (type == null) { return(SpecialTypeSpec.UnknownType); } if (type.IsGenericType && !type.IsGenericTypeDefinition) { ITypeReference def = ToTypeReference(type.GetGenericTypeDefinition()); Type[] arguments = type.GetGenericArguments(); ITypeReference[] args = new ITypeReference[arguments.Length]; bool allUnbound = true; for (int i = 0; i < arguments.Length; i++) { args[i] = ToTypeReference(arguments[i]); allUnbound &= args[i].Equals(SpecialTypeSpec.UnboundTypeArgument); } if (allUnbound) { return(def); } else { return(new ParameterizedTypeReference(def, args)); } } else if (type.IsArray) { return(new ArrayTypeReference(ToTypeReference(type.GetElementType()), type.GetArrayRank())); } else if (type.IsPointer) { return(new PointerTypeReference(ToTypeReference(type.GetElementType()))); } else if (type.IsByRef) { return(new ByReferenceTypeReference(ToTypeReference(type.GetElementType()))); } else if (type.IsGenericParameter) { if (type.DeclaringMethod != null) { return(TypeParameterReference.Create(SymbolKind.Method, type.GenericParameterPosition)); } else { return(TypeParameterReference.Create(SymbolKind.TypeDefinition, type.GenericParameterPosition)); } } else if (type.DeclaringType != null) { if (type == typeof(Dynamic)) { return(SpecialTypeSpec.Dynamic); } else if (type == typeof(Null)) { return(SpecialTypeSpec.NullType); } else if (type == typeof(UnboundTypeArgument)) { return(SpecialTypeSpec.UnboundTypeArgument); } ITypeReference baseTypeRef = ToTypeReference(type.DeclaringType); int typeParameterCount; string name = SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount); return(new NestedTypeReference(baseTypeRef, name, typeParameterCount)); } else { IAssemblyReference assemblyReference = new AssemblyReferenceSpec(type.Assembly.FullName); int typeParameterCount; string name = SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount); return(new GetClassTypeReference(assemblyReference, type.Namespace, name, typeParameterCount)); } }
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); }