Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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);
        }