public static MosaType ToArray(this MosaType type, MosaArrayInfo info) { MosaType array = type.TypeSystem.GetTypeByName(type.TypeSystem.CorLib, "System", "Array"); MosaType result = type.TypeSystem.Controller.CreateType(array); using (var arrayType = type.TypeSystem.Controller.MutateType(result)) { // See Partition II 14.2 Arrays arrayType.Module = type.Module; arrayType.DeclaringType = type.DeclaringType; arrayType.Namespace = type.Namespace; arrayType.Name = type.Name; arrayType.HasOpenGenericParams = type.HasOpenGenericParams; arrayType.BaseType = array; arrayType.ElementType = type; arrayType.TypeCode = MosaTypeCode.Array; arrayType.ArrayInfo = info; AddArrayMethods(type.TypeSystem, result, arrayType, info); return(result); } }
private static void AddArrayMethods(TypeSystem typeSystem, MosaType arrayType, MosaType.Mutator type, MosaArrayInfo info) { // Remove all methods & fields --> Since BaseType = System.Array, they're automatically inherited. type.Methods.Clear(); type.Fields.Clear(); // Add three array accessors as defined in standard (Get, Set, Address) // Also, constructor. uint rank = info.Rank; MosaMethod methodGet = typeSystem.Controller.CreateMethod(); using (var method = typeSystem.Controller.MutateMethod(methodGet)) { method.DeclaringType = arrayType; method.Name = "Get"; method.IsInternalCall = true; method.IsRTSpecialName = method.IsSpecialName = true; method.IsFinal = true; method.HasThis = true; List <MosaParameter> parameters = new List <MosaParameter>(); for (uint i = 0; i < rank; i++) { var indexParam = typeSystem.Controller.CreateParameter(); using (var mosaParameter = typeSystem.Controller.MutateParameter(indexParam)) { mosaParameter.Name = "index" + i; mosaParameter.ParameterAttributes = MosaParameterAttributes.In; mosaParameter.ParameterType = typeSystem.BuiltIn.I4; mosaParameter.DeclaringMethod = methodGet; } parameters.Add(indexParam); } method.Signature = new MosaMethodSignature(arrayType.ElementType, parameters); } type.Methods.Add(methodGet); MosaMethod methodSet = typeSystem.Controller.CreateMethod(); using (var method = typeSystem.Controller.MutateMethod(methodSet)) { method.DeclaringType = arrayType; method.Name = "Set"; method.IsInternalCall = true; method.IsRTSpecialName = method.IsSpecialName = true; method.IsFinal = true; method.HasThis = true; List <MosaParameter> parameters = new List <MosaParameter>(); for (uint i = 0; i < rank; i++) { var indexParam = typeSystem.Controller.CreateParameter(); using (var mosaParameter = typeSystem.Controller.MutateParameter(indexParam)) { mosaParameter.Name = "index" + i; mosaParameter.ParameterAttributes = MosaParameterAttributes.In; mosaParameter.ParameterType = typeSystem.BuiltIn.I4; mosaParameter.DeclaringMethod = methodSet; } parameters.Add(indexParam); } var valueParam = typeSystem.Controller.CreateParameter(); using (var mosaParameter = typeSystem.Controller.MutateParameter(valueParam)) { mosaParameter.Name = "value"; mosaParameter.ParameterAttributes = MosaParameterAttributes.In; mosaParameter.ParameterType = arrayType.ElementType; mosaParameter.DeclaringMethod = methodSet; } parameters.Add(valueParam); method.Signature = new MosaMethodSignature(typeSystem.BuiltIn.Void, parameters); } type.Methods.Add(methodSet); MosaMethod methodAdrOf = typeSystem.Controller.CreateMethod(); using (var method = typeSystem.Controller.MutateMethod(methodAdrOf)) { method.DeclaringType = arrayType; method.Name = "AddressOr"; method.IsInternalCall = true; method.IsRTSpecialName = method.IsSpecialName = true; method.IsFinal = true; method.HasThis = true; List <MosaParameter> parameters = new List <MosaParameter>(); for (uint i = 0; i < rank; i++) { var indexParam = typeSystem.Controller.CreateParameter(); using (var mosaParameter = typeSystem.Controller.MutateParameter(indexParam)) { mosaParameter.Name = "index" + i; mosaParameter.ParameterAttributes = MosaParameterAttributes.In; mosaParameter.ParameterType = typeSystem.BuiltIn.I4; mosaParameter.DeclaringMethod = methodAdrOf; } parameters.Add(indexParam); } method.Signature = new MosaMethodSignature(arrayType.ElementType.ToManagedPointer(), parameters); } type.Methods.Add(methodAdrOf); MosaMethod methodCtor = typeSystem.Controller.CreateMethod(); using (var method = typeSystem.Controller.MutateMethod(methodCtor)) { method.DeclaringType = arrayType; method.Name = ".ctor"; method.IsInternalCall = true; method.IsRTSpecialName = method.IsSpecialName = true; method.IsFinal = true; method.HasThis = true; List <MosaParameter> parameters = new List <MosaParameter>(); for (uint i = 0; i < rank; i++) { var lengthParam = typeSystem.Controller.CreateParameter(); using (var mosaParameter = typeSystem.Controller.MutateParameter(lengthParam)) { mosaParameter.Name = "length" + i; mosaParameter.ParameterAttributes = MosaParameterAttributes.In; mosaParameter.ParameterType = typeSystem.BuiltIn.I4; mosaParameter.DeclaringMethod = methodCtor; } parameters.Add(lengthParam); } method.Signature = new MosaMethodSignature(typeSystem.BuiltIn.Void, parameters); } type.Methods.Add(methodCtor); }