コード例 #1
0
ファイル: TypeDecl.cs プロジェクト: Ashod/Phalanger
		internal void PreAnalyze(Analyzer/*!*/ analyzer, GenericParameter/*!*/ parameter)
		{
			this.parameter = parameter;

			PhpRoutine routine = parameter.DeclaringMember as PhpRoutine;
			PhpType type = (routine != null) ? routine.DeclaringType as PhpType : parameter.DeclaringPhpType;

			parameter.WriteUp(analyzer.ResolveType(defaultType, type, routine, position, false));
		}
コード例 #2
0
ファイル: TypeDecl.cs プロジェクト: Ashod/Phalanger
		/// <summary>
		/// Creates a <see cref="PhpRoutineSignature"/> partially initialized with the type parameters of this type signature. 
		/// Used by generic routines.
		/// </summary>
		internal PhpRoutineSignature/*!*/ ToPhpRoutineSignature(DMember/*!*/ declaringRoutine)
		{
			Debug.Assert(declaringRoutine != null);

			int mandatory_generic_param_count;
			GenericParameterDesc[] descs = this.ToGenericParameters(declaringRoutine, out mandatory_generic_param_count);

			GenericParameter[] types = new GenericParameter[descs.Length];
			for (int i = 0; i < descs.Length; i++)
				types[i] = descs[i].GenericParameter;

			return new PhpRoutineSignature(types, mandatory_generic_param_count);
		}
コード例 #3
0
 public abstract void Build(GameObject parent, GenericParameter parameter);
コード例 #4
0
 public override void Build(GameObject parent, GenericParameter parameter)
 {
     IntDropdownParam.Instantiate(parent, parameter, 0, "From:", textFromOptions);
     StringInputFieldParam.Instantiate(parent, parameter, 0, "From Variable:");
     StringInputFieldParam.Instantiate(parent, parameter, 1, "Custom Text:");
 }
コード例 #5
0
 public GenericParamDef(GenericParameter genericParameter, int index)
     : base(genericParameter, null, index)
 {
 }
コード例 #6
0
        private void AppendConstraints(StringBuilder buf, GenericParameter genArg)
        {
            if (MemberFormatterState == MemberFormatterState.WithinGenericTypeParameters)
            {
                // check to avoid such a code:
                // Public Class MyList(Of A As {Class, Generic.IList(Of B --->As {Class, A}<----), New}, B As {Class, A})
                return;
            }

            GenericParameterAttributes attrs       = genArg.Attributes;
            IList <TypeReference>      constraints = genArg.Constraints;

            if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 0)
            {
                return;
            }

            bool isref = (attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0;
            bool isvt  = (attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0;
            bool isnew = (attrs & GenericParameterAttributes.DefaultConstructorConstraint) != 0;
            bool comma = false;

            if (!isref && !isvt && !isnew && constraints.Count == 0)
            {
                return;
            }
            int constraintsCount = Convert.ToInt32(isref) + Convert.ToInt32(isvt) + Convert.ToInt32(isnew) + constraints.Count;

            buf.Append(" As ");

            if (constraintsCount > 1 && !isvt)
            {
                buf.Append("{");
            }
            if (isref)
            {
                buf.Append("Class");
                comma = true;
            }
            else if (isvt)
            {
                buf.Append("Structure");
                comma = true;
            }
            if (constraints.Count > 0 && !isvt)
            {
                if (comma)
                {
                    buf.Append(", ");
                }
                buf.Append(GetTypeName(constraints[0]));
                for (int i = 1; i < constraints.Count; ++i)
                {
                    buf.Append(", ").Append(GetTypeName(constraints[i]));
                }
            }
            if (isnew && !isvt)
            {
                if (comma)
                {
                    buf.Append(", ");
                }
                buf.Append("New");
            }
            if (constraintsCount > 1 && !isvt)
            {
                buf.Append("}");
            }
        }
コード例 #7
0
 static bool IsParameterCompatibleWith(GenericParameter a, GenericParameter b)
 {
     return(a.Position == b.Position);
 }
コード例 #8
0
ファイル: Methods.cs プロジェクト: tiaohai/Phalanger
		/// <summary>
		/// Creates a signature partially initialized with type parameters. 
		/// Rationale for partial initialization: 
		/// When analyzing a routine, the analyzer needs to know about type parameters prior to the analysis of actual parameters.
		/// </summary>
		public PhpRoutineSignature(GenericParameter[]/*!!*/ genericParams, int mandatoryGenericParamCount)
		{
			Debug.Assert(genericParams != null);
			Debug.Assert(mandatoryGenericParamCount >= 0 && mandatoryGenericParamCount <= genericParams.Length);

			this.genericParams = genericParams;
			this.mandatoryGenericParamCount = mandatoryGenericParamCount;
		}
コード例 #9
0
        static void CreateConvertMethodForComponentDataTypes(TypeDefinition authoringType, TypeDefinition componentDataType)
        {
            var moduleDefinition           = componentDataType.Module;
            var entityTypeReference        = moduleDefinition.ImportReference(typeof(Unity.Entities.Entity));
            var entityManagerTypeReference = moduleDefinition.ImportReference(typeof(Unity.Entities.EntityManager));
            var gameObjectTypeReference    = moduleDefinition.ImportReference(typeof(UnityEngine.GameObject));

            MethodDefinition convertMethod = CreateEmptyConvertMethod(moduleDefinition, authoringType);

            // Make a local variable which we'll populate with the values stored in the MonoBehaviour
            var variableDefinition = new VariableDefinition(componentDataType);

            convertMethod.Body.Variables.Add(variableDefinition);

            var ilProcessor = convertMethod.Body.GetILProcessor();

            // Initialize the local variable.  (we might not need this, but all c# compilers emit it, so let's play it safe for now)
            if (componentDataType.IsValueType())
            {
                ilProcessor.Emit(OpCodes.Ldloca, variableDefinition);
                ilProcessor.Emit(OpCodes.Initobj, componentDataType);
            }
            else
            {
                var componentDataConstructor = componentDataType.GetConstructors().FirstOrDefault(c => c.Parameters.Count == 0);
                if (componentDataConstructor == null)
                {
                    UserError.DC0030(componentDataType).Throw();
                }
                ilProcessor.Emit(OpCodes.Newobj, moduleDefinition.ImportReference(componentDataConstructor));
                ilProcessor.Emit(OpCodes.Stloc, variableDefinition);
            }

            var getPrimaryEntityGameObjectMethod = moduleDefinition.ImportReference(
                typeof(GameObjectConversionSystem).GetMethod("GetPrimaryEntity", new Type[] { typeof(UnityEngine.GameObject) }));
            var getPrimaryEntityComponentMethod = moduleDefinition.ImportReference(
                typeof(GameObjectConversionSystem).GetMethod("GetPrimaryEntity", new Type[] { typeof(UnityEngine.Component) }));
            var convertGameObjectsToEntitiesFieldMethod = moduleDefinition.ImportReference(
                typeof(GameObjectConversionUtility).GetMethod(nameof(GameObjectConversionUtility.ConvertGameObjectsToEntitiesField)));

            // Let's transfer every field in the MonoBehaviour over to the corresponding field in the IComponentData
            foreach (var field in authoringType.Fields)
            {
                var destinationField = componentDataType.Fields.Single(f => f.Name == field.Name);

                // Special case when destination field is a array of entities, we need to emit IL to create our destination array
                // and convert from array of GameObjects
                // https://sharplab.io/#v2:C4LglgNgNAJiDUAfAAgJgIwFgBQyAMABMugCwDcOOyAzEagQKIB2wYwAngQN4C+VtaAgHEAhgFsApgHkARgCsJAY2Dc+uAfWasOAWRFMRAcwkAnVfzrDx0+UuABhAPZMAbqYDOYZ8QI4uOAkCiWi02TiEJYAAFEzAxERN2UI4AClFJWQVlAkNHAEoAoP9sINKiAHYCJgBXCAgyIMLAtTULQQBJJzEAB2cJFgAREWARc3VLACVHEdZnAGVuiQkYAH0AMUcTBhFFAAsCEAJOxx6+weGRPybgggAzCEdhggmRGDB9dyjTOaVnGAoSkEaIwWGEANoAXQI/W0YAk7gBrXGxAAbJYABISCCLEzuK6AwLA1FEEgEJyuUzAdI2LLAdwAFUcyTh7g2JgAgtVgLtNmAmIY0tZMnZyW5cV4mD5FM4xZ5vOgoFYMrZlJCckKVXTFSYJLcQdp2GqYWwWQUCdxrqVjax4QQALxVCQAd314MMGtp7gAdAAZfqGbkQgFlIK3TYEFJ8lRgO14BpgAA81pZvv93Ia8HgYDNIZDyfhYLAUId0op4vlXoi0Vi8USyXYKXdys9hYheWDQTUpWuRPQaOQpPZMBg7JMJhE7Ckt2pwuU7nZ7gmutM/UUyxiupEMncgubdjVTZpdncip9YHcwATM81AD4CDrbiumGuYBvblv3DmipbQ5sJDt9hSFwEnVPdsj5UCjznL8Q2KXMygfJ8XzfD8vSHGBGw9Ox2x/Zpri7RpzV7ftB2HLpeiYGEhhGFJuXPV1dH0IxTAIGB4VYAxZiYPQDGMExFXraFQQ4RUphmCUFiWVY2W2PYCGlU5KJYGCLXNFpKGRegxOGCTFmWdZNlk3ZOW5Xl+XxUpgXuR4VBeN4Pi+EwflLf4e1oa9aSNYSWQ7QI3JJMkZUpFJBOtdgBOE9geOYsw2IvPkdOcaK+MVDyRSC8tJXQeSMrlLKzQASGKAqCu0rjJP0mSAPvaZEqYCrpMM6qHUol0yt0qSDK2ACUhw7ASpMWryr0xrur2L07PeJhPm+X4mBge1nleKaZqcubXPNUpMWxDwvVFSk0rnRlmXhNkTJ5WJ+RSUtZQlYhFXzE9711GrxPmEauqMr1Hr6krtpxb10PIs5gGokQUjiji6uS0wHsi7Uho6yqmr2X6kQKolSQGJQIASCQl0fHVn3XB8PxSM8LyvLDlDvRCieQ0nt0KuDc3+3b0NHcdJ2nam6QXAmkJJzdtxSR7tWXemhffJmAQK9TASAA===
                if (destinationField.FieldType.IsArray && destinationField.FieldType.GetElementType().TypeReferenceEquals(entityTypeReference))
                {
                    ilProcessor.Emit(OpCodes.Ldarg_3);
                    ilProcessor.Emit(OpCodes.Ldarg_0);
                    ilProcessor.Emit(OpCodes.Ldfld, field);
                    ilProcessor.Emit(OpCodes.Ldloc, variableDefinition);
                    ilProcessor.Emit(OpCodes.Ldflda, destinationField);
                    ilProcessor.Emit(OpCodes.Callvirt, convertGameObjectsToEntitiesFieldMethod);
                }
                else
                {
                    // Load the local iComponentData we are populating, so we can later write to it
                    ilProcessor.Emit(componentDataType.IsValueType() ? OpCodes.Ldloca : OpCodes.Ldloc, variableDefinition);

                    // Special case when destination is an entity and we our converting from a GameObject
                    if (destinationField.FieldType.TypeReferenceEquals(entityTypeReference))
                    {
                        ilProcessor.Emit(OpCodes.Ldarg_3);
                        ilProcessor.Emit(OpCodes.Ldarg_0);
                        ilProcessor.Emit(OpCodes.Ldfld, field);

                        var methodToCall = field.FieldType.TypeReferenceEquals(gameObjectTypeReference)
                            ? getPrimaryEntityGameObjectMethod
                            : getPrimaryEntityComponentMethod;
                        ilProcessor.Emit(OpCodes.Callvirt, methodToCall);
                    }
                    else
                    {
                        ilProcessor.Emit(OpCodes.Ldarg_0);
                        ilProcessor.Emit(OpCodes.Ldfld, field);
                    }

                    // Store it to the IComponentData we already placed on the stack
                    ilProcessor.Emit(OpCodes.Stfld, destinationField);
                }
            }

            // Now that our local IComponentData is properly setup, the only thing left for us is to call:
            // entityManager.AddComponentData(entity, myPopulatedIComponentData).
            // IL method arguments go on the stack from first to last so:
            ilProcessor.Emit(OpCodes.Ldarg_2); //entityManager
            ilProcessor.Emit(OpCodes.Ldarg_1); //entity
            ilProcessor.Emit(OpCodes.Ldloc_0); //myPopulatedIComponentData

            // Build a MethodReference to EntityManager.AddComponentData
            MethodReference addComponentDataMethodReference = null;

#if !UNITY_DISABLE_MANAGED_COMPONENTS
            // For managed components this is void EntityManagerManagedComponentExtensions.AddComponentData<T>(this EntityMananger mananger, Entity target, T payload);
            var entityManagerManagedComponentExtensionsTypeReference = moduleDefinition.ImportReference(typeof(Unity.Entities.EntityManagerManagedComponentExtensions));
            if (!componentDataType.IsValueType())
            {
                addComponentDataMethodReference =
                    new MethodReference("AddComponentData", moduleDefinition.TypeSystem.Void, entityManagerManagedComponentExtensionsTypeReference)
                {
                    Parameters =
                    {
                        new ParameterDefinition("manager", ParameterAttributes.None, entityManagerTypeReference),
                        new ParameterDefinition("entity",  ParameterAttributes.None, entityTypeReference),
                    },
                    ReturnType = moduleDefinition.TypeSystem.Void
                };
            }
#endif
            // For non-managed components this is EntityManager.AddComponentData<T>(Entity target, T payload);
            if (componentDataType.IsValueType())
            {
                addComponentDataMethodReference =
                    new MethodReference("AddComponentData", moduleDefinition.TypeSystem.Void, entityManagerTypeReference)
                {
                    HasThis    = true,
                    Parameters =
                    {
                        new ParameterDefinition("entity", ParameterAttributes.None, entityTypeReference),
                    },
                    ReturnType = moduleDefinition.TypeSystem.Boolean
                };
            }

            var genericParameter = new GenericParameter("T", addComponentDataMethodReference);
            addComponentDataMethodReference.GenericParameters.Add(genericParameter);
            addComponentDataMethodReference.Parameters.Add(new ParameterDefinition("payload", ParameterAttributes.None, genericParameter));

            // Since AddComponentData<T> is a generic method, we cannot call it super easily.
            // We have to wrap the generic method reference into a GenericInstanceMethod,
            // which let's us specify what we want to use for T for this specific invocation.
            // In our case T is the IComponentData we're operating on
            var genericInstanceMethod = new GenericInstanceMethod(addComponentDataMethodReference)
            {
                GenericArguments = { componentDataType },
            };
            ilProcessor.Emit(OpCodes.Callvirt, genericInstanceMethod);

            // Pop off return value since AddComponentData returns a bool (managed AddComponentData strangely does not however)
            if (componentDataType.IsValueType())
            {
                ilProcessor.Emit(OpCodes.Pop);
            }

            // We're done already!  Easy peasy.
            ilProcessor.Emit(OpCodes.Ret);
        }
コード例 #10
0
        /// <summary>
        /// Relink the given type reference.
        /// </summary>
        /// <param name="type">The reference to relink.</param>
        /// <param name="relinker">The relinker to use during the relinking process.</param>
        /// <param name="context">The generic context provided to relink generic references.</param>
        /// <returns>A relinked reference.</returns>
        public static TypeReference Relink(this TypeReference type, Relinker relinker, IGenericParameterProvider context)
        {
            if (type == null)
            {
                return(null);
            }

            if (type is TypeSpecification ts)
            {
                TypeReference relinkedElem = ts.ElementType.Relink(relinker, context);

                if (type.IsSentinel)
                {
                    return(new SentinelType(relinkedElem));
                }

                if (type.IsByReference)
                {
                    return(new ByReferenceType(relinkedElem));
                }

                if (type.IsPointer)
                {
                    return(new PointerType(relinkedElem));
                }

                if (type.IsPinned)
                {
                    return(new PinnedType(relinkedElem));
                }

                if (type.IsArray)
                {
                    ArrayType at = new ArrayType(relinkedElem, ((ArrayType)type).Rank);
                    for (int i = 0; i < at.Rank; i++)
                    {
                        // It's a struct.
                        at.Dimensions[i] = ((ArrayType)type).Dimensions[i];
                    }
                    return(at);
                }

                if (type.IsRequiredModifier)
                {
                    return(new RequiredModifierType(((RequiredModifierType)type).ModifierType.Relink(relinker, context), relinkedElem));
                }

                if (type.IsOptionalModifier)
                {
                    return(new OptionalModifierType(((OptionalModifierType)type).ModifierType.Relink(relinker, context), relinkedElem));
                }

                if (type.IsGenericInstance)
                {
                    GenericInstanceType git = new GenericInstanceType(relinkedElem);
                    foreach (TypeReference genArg in ((GenericInstanceType)type).GenericArguments)
                    {
                        git.GenericArguments.Add(genArg?.Relink(relinker, context));
                    }
                    return(git);
                }

                if (type.IsFunctionPointer)
                {
                    FunctionPointerType fp = (FunctionPointerType)type;
                    fp.ReturnType = fp.ReturnType.Relink(relinker, context);
                    for (int i = 0; i < fp.Parameters.Count; i++)
                    {
                        fp.Parameters[i].ParameterType = fp.Parameters[i].ParameterType.Relink(relinker, context);
                    }
                    return(fp);
                }

                throw new NotSupportedException($"MonoMod can't handle TypeSpecification: {type.FullName} ({type.GetType()})");
            }

            if (type.IsGenericParameter && context != null)
            {
                GenericParameter genParam = context.ResolveGenericParameter((GenericParameter)type);
                if (genParam == null)
                {
                    throw new RelinkTargetNotFoundException($"{RelinkTargetNotFoundException.DefaultMessage} {type.FullName} (context: {context})", type, context);
                }
                for (int i = 0; i < genParam.Constraints.Count; i++)
                {
                    if (!genParam.Constraints[i].GetConstraintType().IsGenericInstance) // That is somehow possible and causes a stack overflow.
                    {
                        genParam.Constraints[i] = genParam.Constraints[i].Relink(relinker, context);
                    }
                }
                return(genParam);
            }

            return((TypeReference)relinker(type, context));
        }
コード例 #11
0
        /// <summary>
        /// Resolve a given generic parameter in another context.
        /// </summary>
        /// <param name="provider">The new context.</param>
        /// <param name="orig">The original generic parameter.</param>
        /// <returns>A generic parameter provided by the given context which matches the original generic parameter.</returns>
        public static GenericParameter ResolveGenericParameter(this IGenericParameterProvider provider, GenericParameter orig)
        {
            // This can be true for T[,].Get in "Enter the Gungeon"
            if (provider is GenericParameter && ((GenericParameter)provider).Name == orig.Name)
            {
                return((GenericParameter)provider);
            }

            foreach (GenericParameter param in provider.GenericParameters)
            {
                if (param.Name == orig.Name)
                {
                    return(param);
                }
            }

            int index = orig.Position;

            if (provider is MethodReference && orig.DeclaringMethod != null)
            {
                if (index < provider.GenericParameters.Count)
                {
                    return(provider.GenericParameters[index]);
                }
                else
                {
                    return(new GenericParameter(orig.Name, provider).Update(index, GenericParameterType.Method));
                }
            }

            if (provider is TypeReference && orig.DeclaringType != null)
            {
                if (index < provider.GenericParameters.Count)
                {
                    return(provider.GenericParameters[index]);
                }
                else
                {
                    return(new GenericParameter(orig.Name, provider).Update(index, GenericParameterType.Type));
                }
            }

            return
                ((provider as TypeSpecification)?.ElementType.ResolveGenericParameter(orig) ??
                 (provider as MemberReference)?.DeclaringType?.ResolveGenericParameter(orig));
        }
コード例 #12
0
 /// <summary>
 /// Force-update a generic parameter's position and type.
 /// </summary>
 /// <param name="param">The generic parameter to update.</param>
 /// <param name="position">The new position.</param>
 /// <param name="type">The new type.</param>
 /// <returns>The updated generic parameter.</returns>
 public static GenericParameter Update(this GenericParameter param, int position, GenericParameterType type)
 {
     f_GenericParameter_position.SetValue(param, position);
     f_GenericParameter_type.SetValue(param, type);
     return(param);
 }
コード例 #13
0
 static GenericParameter CloneGenericParameter(GenericParameter gp)
 {
     return((GenericParameter)genericParameterConstructor.Invoke(new object[] { gp.Position, gp.Type, gp.Module }));
 }
コード例 #14
0
 /// <summary>
 /// Invokes the behavior.
 /// </summary>
 /// <param name="item">Item on which to invoke the behavior.</param>
 /// <returns>Result of the invocation.</returns>
 protected abstract TReturn InvokeForItem(GenericParameter item);
コード例 #15
0
        public void ProcessType(CecilSerializerContext context, TypeReference type, MethodDefinition updateMainMethod)
        {
            var typeDefinition = type.Resolve();

            // No need to process Enum
            if (typeDefinition.IsEnum)
            {
                return;
            }

            var updateCurrentMethod = updateMainMethod;
            ResolveGenericsVisitor replaceGenericsVisitor = null;

            if (typeDefinition.HasGenericParameters)
            {
                // Make a prepare method for just this object since it might need multiple instantiation
                updateCurrentMethod = new MethodDefinition(ComputeUpdateMethodName(typeDefinition), MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, context.Assembly.MainModule.TypeSystem.Void);
                var genericsMapping = new Dictionary <TypeReference, TypeReference>();
                foreach (var genericParameter in typeDefinition.GenericParameters)
                {
                    var genericParameterCopy = new GenericParameter(genericParameter.Name, updateCurrentMethod)
                    {
                        Attributes = genericParameter.Attributes,
                    };

                    foreach (var constraint in genericParameter.Constraints)
                    {
                        genericParameterCopy.Constraints.Add(
                            new GenericParameterConstraint(context.Assembly.MainModule.ImportReference(constraint.ConstraintType)));
                    }
                    updateCurrentMethod.GenericParameters.Add(genericParameterCopy);

                    genericsMapping[genericParameter] = genericParameterCopy;
                }

                replaceGenericsVisitor = new ResolveGenericsVisitor(genericsMapping);

                updateMainMethod.DeclaringType.Methods.Add(updateCurrentMethod);
            }

            var il = updateCurrentMethod.Body.GetILProcessor();
            var typeIsValueType            = type.IsResolvedValueType();
            var emptyObjectField           = typeIsValueType ? null : updateMainMethod.DeclaringType.Fields.FirstOrDefault(x => x.Name == "emptyObject");
            VariableDefinition emptyStruct = null;

            // Note: forcing fields and properties to be processed in all cases
            foreach (var serializableItem in ComplexSerializerRegistry.GetSerializableItems(type, ComplexTypeSerializerFlags.SerializePublicFields | ComplexTypeSerializerFlags.SerializePublicProperties | ComplexTypeSerializerFlags.Updatable))
            {
                if (serializableItem.MemberInfo is FieldReference fieldReference)
                {
                    var field = fieldReference.Resolve();

                    // First time it is needed. Let's create an empty object in the class (var emptyObject = new object())
                    // or empty local struct in the method
                    if (typeIsValueType)
                    {
                        if (emptyStruct is null)
                        {
                            emptyStruct = new VariableDefinition(type);
                            updateMainMethod.Body.Variables.Add(emptyStruct);
                        }
                    }
                    else
                    {
                        if (emptyObjectField is null)
                        {
                            emptyObjectField = new FieldDefinition("emptyObject", FieldAttributes.Static | FieldAttributes.Private, context.Assembly.MainModule.TypeSystem.Object);

                            // Create static ctor that will initialize this object
                            var staticConstructor = new MethodDefinition(".cctor",
                                                                         MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static |
                                                                         MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                                                                         context.Assembly.MainModule.TypeSystem.Void);
                            var staticConstructorIL = staticConstructor.Body.GetILProcessor();
                            staticConstructorIL.Emit(OpCodes.Newobj, context.Assembly.MainModule.ImportReference(
                                                         emptyObjectField.FieldType.Resolve().GetConstructors().Single(ctor => !ctor.IsStatic && !ctor.HasParameters)));
                            staticConstructorIL.Emit(OpCodes.Stsfld, emptyObjectField);
                            staticConstructorIL.Emit(OpCodes.Ret);

                            updateMainMethod.DeclaringType.Fields.Add(emptyObjectField);
                            updateMainMethod.DeclaringType.Methods.Add(staticConstructor);
                        }
                    }


                    il.Emit(OpCodes.Ldtoken, type);
                    il.Emit(OpCodes.Call, getTypeFromHandleMethod);
                    il.Emit(OpCodes.Ldstr, field.Name);

                    if (typeIsValueType)
                    {
                        il.Emit(OpCodes.Ldloca, emptyStruct);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldsfld, emptyObjectField);
                    }
                    il.Emit(OpCodes.Ldflda, context.Assembly.MainModule.ImportReference(fieldReference));
                    il.Emit(OpCodes.Conv_I);
                    if (typeIsValueType)
                    {
                        il.Emit(OpCodes.Ldloca, emptyStruct);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldsfld, emptyObjectField);
                    }
                    il.Emit(OpCodes.Conv_I);
                    il.Emit(OpCodes.Sub);
                    il.Emit(OpCodes.Conv_I4);

                    var fieldType = context.Assembly.MainModule.ImportReference(replaceGenericsVisitor != null ? replaceGenericsVisitor.VisitDynamic(field.FieldType) : field.FieldType);
                    il.Emit(OpCodes.Newobj, context.Assembly.MainModule.ImportReference(updatableFieldGenericCtor).MakeGeneric(fieldType));
                    il.Emit(OpCodes.Call, updateEngineRegisterMemberMethod);
                }

                if (serializableItem.MemberInfo is PropertyReference propertyReference)
                {
                    var property = propertyReference.Resolve();

                    var propertyGetMethod = context.Assembly.MainModule.ImportReference(property.GetMethod)
                                            .MakeGeneric(updateCurrentMethod.GenericParameters.ToArray());

                    il.Emit(OpCodes.Ldtoken, type);
                    il.Emit(OpCodes.Call, getTypeFromHandleMethod);
                    il.Emit(OpCodes.Ldstr, property.Name);

                    // If it's a virtual or interface call, we need to create a dispatcher using ldvirtftn
                    if (property.GetMethod.IsVirtual)
                    {
                        propertyGetMethod = CreateDispatcher(context.Assembly, propertyGetMethod);
                    }

                    il.Emit(OpCodes.Ldftn, propertyGetMethod);

                    // Set whether getter method uses a VirtualDispatch (static call) or instance call
                    il.Emit(property.GetMethod.IsVirtual ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);

                    // Only uses setter if it exists and it's public
                    if (property.SetMethod != null && property.SetMethod.IsPublic)
                    {
                        var propertySetMethod = context.Assembly.MainModule.ImportReference(property.SetMethod).MakeGeneric(updateCurrentMethod.GenericParameters.ToArray());
                        if (property.SetMethod.IsVirtual)
                        {
                            propertySetMethod = CreateDispatcher(context.Assembly, propertySetMethod);
                        }
                        il.Emit(OpCodes.Ldftn, propertySetMethod);
                    }
                    else
                    {
                        // 0 (native int)
                        il.Emit(OpCodes.Ldc_I4_0);
                        il.Emit(OpCodes.Conv_I);
                    }

                    // Set whether setter method uses a VirtualDispatch (static call) or instance call
                    il.Emit((property.SetMethod?.IsVirtual ?? false) ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);

                    var propertyType = context.Assembly.MainModule.ImportReference(replaceGenericsVisitor != null
                        ? replaceGenericsVisitor.VisitDynamic(property.PropertyType)
                        : property.PropertyType);

                    var updatablePropertyInflatedCtor = GetOrCreateUpdatablePropertyCtor(context.Assembly, propertyType);

                    il.Emit(OpCodes.Newobj, updatablePropertyInflatedCtor);
                    il.Emit(OpCodes.Call, updateEngineRegisterMemberMethod);
                }
            }

            if (updateCurrentMethod != updateMainMethod)
            {
                // If we have a local method, close it
                il.Emit(OpCodes.Ret);

                // Also call it from main method if it was a closed generic instantiation
                if (type is GenericInstanceType)
                {
                    il = updateMainMethod.Body.GetILProcessor();
                    il.Emit(OpCodes.Call, updateCurrentMethod.MakeGeneric(((GenericInstanceType)type).GenericArguments.Select(context.Assembly.MainModule.ImportReference).ToArray()));
                }
            }
        }
コード例 #16
0
        private static void GenerateArray(MethodDefinition method, TypeReference baseEnumerable, GenericParameter T, TypeReference TPredicate, TypeReference predicate)
        {
            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.None, baseEnumerable));
            method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.Out, new ByReferenceType(T)));
            method.Parameters.Add(new ParameterDefinition("TPredicate", ParameterAttributes.In, new ByReferenceType(TPredicate))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });

            var loopStart = Instruction.Create(OpCodes.Ldarg_0);
            var success   = Instruction.Create(OpCodes.Ldarg_1);
            var fail      = InstructionUtility.LoadConstant(false);

            var body = method.Body;

            body.InitLocals = true;
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.IntPtr));
            body.Variables.Add(new VariableDefinition(new ByReferenceType(T)));

            method.Body.GetILProcessor()
            .ArgumentNullCheck(0, Instruction.Create(OpCodes.Ldarg_0))
            .LdLen()
            .BrFalseS(fail)

            .LdArg(0)
            .LdLen()
            .StLoc(0)

            .Add(loopStart)
            .LdLoc(0)
            .LdC(1)
            .Sub()
            .Dup()
            .StLoc(0)
            .LdElemA(T)
            .StLoc(1)

            .LdArg(2)
            .LdLoc(1)
            .Constrained(TPredicate)
            .CallVirtual(predicate.FindMethod("Calc"))
            .BrTrueS(success)

            .LdLoc(0)

            .BrTrueS(loopStart)

            .Add(fail)
            .Ret()

            .Add(success)
            .LdLoc(1)
            .CpObj(T)

            .LdC(true)
            .Ret();
        }
コード例 #17
0
 public void RemoveGenericConstraintMapping(GenericParameter generic_parameter)
 {
     GenericConstraints.Remove(generic_parameter.token.RID);
 }
コード例 #18
0
        bool Initialize(ref Rect position, ref bool displayLock, SerializedProperty property, GenericParameter asGeneric)
        {
            Type           targetType       = property.serializedObject.targetObject.GetType();
            SerializedType isTypeRestricted = null;

            var       path           = property.GetPath();
            FieldInfo paramFieldInfo = path.MaterializeToFieldInfo(targetType);

            var typeAttribute = paramFieldInfo.GetCustomAttribute <TypeRestricted>();

            if (typeAttribute != null)
            {
                switch (typeAttribute.Source)
                {
                case TypeRestricted.TypeSource.Value:
                {
                    isTypeRestricted = new SerializedType(typeAttribute.Type);
                    break;
                }

                case TypeRestricted.TypeSource.Field:
                {
                    var field = targetType.GetField(typeAttribute.SourceValue);
                    if (field != null)
                    {
                        var typeValue = field.GetValue(property.serializedObject.targetObject);
                        switch (typeValue)
                        {
                        case SerializedType asSerialized:
                        {
                            isTypeRestricted = asSerialized;
                            break;
                        }

                        case Type asSystem:
                        {
                            isTypeRestricted = new SerializedType(asSystem);
                            break;
                        }
                        }
                        break;
                    }

                    return(false);
                }

                default:
                    return(false);
                }
            }

            View.Target         = property.serializedObject.targetObject;
            View.AsParametrized = View.Target as IBaseObject;
            View.DataProvider   = View.AsParametrized?.GetProvider();

            if (isTypeRestricted != null && isTypeRestricted.Type != null)
            {
                displayLock     = true;
                View.Parameters = View.DataProvider.GetParameters(t =>
                {
                    if (string.IsNullOrEmpty(isTypeRestricted.Metadata))
                    {
                        return(isTypeRestricted.Type.IsAssignableFrom(t.HoldType.Type));
                    }
                    else
                    {
                        return(isTypeRestricted.Equals(t.HoldType));
                    }
                });
                View.Typename = KnownType.GetDisplayedName(isTypeRestricted.Type);
            }
            else
            {
                displayLock     = false;
                View.Parameters = View.DataProvider.GetParameters();
                View.Typename   = "Parameter";
            }

            if (asGeneric.HoldType != isTypeRestricted)
            {
                asGeneric.HoldType = isTypeRestricted;
            }

            if (View.Typename == null)
            {
                EditorGUI.HelpBox(position, string.Format("Type {0} is not a known type!", fieldInfo.FieldType), MessageType.Error);
                return(false);
            }

            if (!View.DataProvider.HasObject(View.Target))
            {
                EditorGUI.HelpBox(position, "Unable to edit this object!", MessageType.Error);
                return(false);
            }

            if (View.DataProvider == null)
            {
                EditorGUI.HelpBox(position, $"{property.name}: Unable to get instance of IDataSetProvider!", MessageType.Error);
                return(false);
            }

            return(true);
        }
コード例 #19
0
 internal void GetConstraintInfoForGenericParam(
   GenericParameter genericParam,
   out uint genericParamConstraintRowIdStart,
   out uint genericParamConstraintRowIdEnd
 ) {
   uint constraintCount;
   genericParamConstraintRowIdStart = this.PEFileReader.GenericParamConstraintTable.FindConstraintForGenericParam(genericParam.GenericParameterRowId, out constraintCount);
   genericParamConstraintRowIdEnd = genericParamConstraintRowIdStart + constraintCount;
 }
コード例 #20
0
 private static TypeReference ResolveIfNeeded(IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, GenericParameter genericParameterElement) =>
 ((genericParameterElement.MetadataType != MetadataType.MVar) ? genericInstanceType.GenericArguments[genericParameterElement.Position] : ((genericInstanceMethod == null) ? genericParameterElement : genericInstanceMethod.GenericArguments[genericParameterElement.Position]));
コード例 #21
0
ファイル: TypeUtil.cs プロジェクト: wushian/JSIL
 public static bool IsPositionalGenericParameter(GenericParameter gp)
 {
     return(gp.Name[0] == '!');
 }
コード例 #22
0
 internal bool AreSame(GenericParameter a, GenericParameter b)
 {
     return(a.Position == b.Position);
 }
コード例 #23
0
 public void VisitGenericParameter(GenericParameter genparam)
 {
 }
コード例 #24
0
 private void FixReferences(GenericParameter definition)
 {
     FixReferences(definition.Constraints);
     FixReferences(definition.CustomAttributes);
 }
コード例 #25
0
        private static void GenerateGeneric(TypeDefinition @static, ModuleDefinition mainModule)
        {
            var method = new MethodDefinition("Aggregate", Helper.StaticMethodAttributes, mainModule.TypeSystem.Boolean)
            {
                DeclaringType      = @static,
                AggressiveInlining = true,
                CustomAttributes   = { Helper.ExtensionAttribute }
            };

            @static.Methods.Add(method);

            var genericParameters = method.GenericParameters;

            var(T, TEnumerator, TEnumerable) = method.Define3GenericParameters();

            var TAccumulate = new GenericParameter("TAccumulate", method);

            genericParameters.Add(TAccumulate);

            var TResult = new GenericParameter("TResult", method);

            genericParameters.Add(TResult);
            method.ReturnType = TResult;

            var TFunc = new GenericInstanceType(mainModule.GetType("UniNativeLinq", "RefAction`2"))
            {
                GenericArguments = { TAccumulate, T }
            };

            var TResultFunc = new GenericInstanceType(mainModule.GetType("UniNativeLinq", "RefFunc`2"))
            {
                GenericArguments = { TAccumulate, TResult }
            };

            method.Parameters.Add(new ParameterDefinition("@this", ParameterAttributes.In, new ByReferenceType(TEnumerable))
            {
                CustomAttributes = { Helper.GetSystemRuntimeCompilerServicesIsReadOnlyAttributeTypeReference() }
            });
            method.Parameters.Add(new ParameterDefinition("accumulate", ParameterAttributes.None, new ByReferenceType(TAccumulate)));
            method.Parameters.Add(new ParameterDefinition("func", ParameterAttributes.None, TFunc));
            method.Parameters.Add(new ParameterDefinition("resultFunc", ParameterAttributes.None, TResultFunc));

            var body = method.Body;

            var enumeratorVariable = new VariableDefinition(TEnumerator);

            body.Variables.Add(enumeratorVariable);
            body.Variables.Add(new VariableDefinition(method.Module.TypeSystem.Boolean));
            body.Variables.Add(new VariableDefinition(new ByReferenceType(T)));

            var loopStart = Instruction.Create(OpCodes.Ldarg_2);
            var condition = Instruction.Create(OpCodes.Ldloca_S, enumeratorVariable);

            body.GetILProcessor()
            .ArgumentNullCheck(2, 3, Instruction.Create(OpCodes.Ldarg_0))
            .GetEnumeratorEnumerable(TEnumerable)
            .StLoc(0)
            .BrS(condition)
            .Add(loopStart)
            .LdArg(1)
            .LdLoc(2)
            .CallVirtual(TFunc.FindMethod("Invoke"))
            .Add(condition)
            .LdLocA(1)
            .TryGetNextEnumerator(TEnumerator)
            .StLoc(2)
            .LdLoc(1)
            .BrTrueS(loopStart)
            .LdLocA(0)
            .DisposeEnumerator(TEnumerator)
            .LdArg(3)
            .LdArg(1)
            .CallVirtual(TResultFunc.FindMethod("Invoke"))
            .Ret();
        }
コード例 #26
0
 public MyGenericParameterInfo(GenericParameter genericParameter)
     : base()
 {
     this.name        = genericParameter.Name;
     this.constraints = CreateGenericConstraints(genericParameter);
 }
コード例 #27
0
 public abstract string ToString(GenericParameter parameter);
コード例 #28
0
        private List <GenericConstraint> CreateGenericConstraints(GenericParameter genericParameter)
        {
            List <GenericConstraint> result = null;

            if ((genericParameter.Attributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint)
            {
                result = new List <GenericConstraint>();

                result.Add(new BuiltInGenericConstraint(BuiltInGenericConstraintsTypes.Class));
            }
            else if ((genericParameter.Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint)
            {
                result = new List <GenericConstraint>();

                result.Add(new BuiltInGenericConstraint(BuiltInGenericConstraintsTypes.Struct));
            }

            var baseOrInterfaceConstraints = genericParameter.Constraints;

            if (baseOrInterfaceConstraints != null)
            {
                if (result == null)
                {
                    result = new List <GenericConstraint>();
                }

                for (int i = 0; i < baseOrInterfaceConstraints.Count; i++)
                {
                    TypeReference baseTypeOrInterface = baseOrInterfaceConstraints[i];

                    if (baseTypeOrInterface.FullName == "System.ValueType")
                    {
                        continue;
                    }

                    if (Utils.IsGenericParameter(baseTypeOrInterface))
                    {
                        result.Add(new NakedTypeConstraint(baseTypeOrInterface.Name));
                    }
                    else
                    {
                        string[] readableForms = Tools.GetHumanReadableForms(baseTypeOrInterface);

                        result.Add(new TypeGenericConstraint(readableForms[0]));
                    }
                }
            }

            if ((genericParameter.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint &&
                (genericParameter.Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == 0)
            {
                if (result == null)
                {
                    result = new List <GenericConstraint>();
                }

                result.Add(new BuiltInGenericConstraint(BuiltInGenericConstraintsTypes.New));
            }

            return(result);
        }
コード例 #29
0
 public override string ToString(GenericParameter parameter)
 {
     return("'" + parameter.SafeString(0) + "'");
 }
コード例 #30
0
        public override TypeReference Visit(GenericParameter type)
        {
            if (type.Type == GenericParameterType.Method)
            {
                if (genericContextMethod != null && type.Position < genericContextMethod.GenericArguments.Count)
                {
                    // Look for generic parameter in both resolved and element method
                    var genericContext1   = genericContextMethod.ElementMethod;
                    var genericContext2   = genericContextMethod.Resolve();
                    var genericParameter1 = genericContext1.GenericParameters[type.Position];
                    var genericParameter2 = genericContext2.GenericParameters[type.Position];

                    if (resolveOnlyReferences)
                    {
                        if (genericParameter1.Name == type.Name)
                        {
                            return(genericParameter2);
                        }
                    }
                    else
                    {
                        if (genericParameter1.Name == type.Name)
                        {
                            return(genericContextMethod.GenericArguments[type.Position]);
                        }

                        if (genericParameter2.Name == type.Name)
                        {
                            return(genericContextMethod.GenericArguments[type.Position]);
                        }
                    }
                }
            }
            else
            {
                if (genericContextType != null && type.Position < genericContextType.GenericArguments.Count)
                {
                    // Look for generic parameter in both resolved and element method
                    var genericContext1   = genericContextType.ElementType;
                    var genericContext2   = genericContextType.Resolve();
                    var genericParameter1 = genericContext1.GenericParameters[type.Position];
                    var genericParameter2 = genericContext2.GenericParameters[type.Position];

                    if (resolveOnlyReferences)
                    {
                        if (genericParameter1.Name == type.Name)
                        {
                            return(genericParameter2);
                        }
                    }
                    else
                    {
                        if (genericParameter1.Name == type.Name)
                        {
                            return(genericContextType.GenericArguments[type.Position]);
                        }

                        if (genericParameter2.Name == type.Name)
                        {
                            return(genericContextType.GenericArguments[type.Position]);
                        }
                    }
                }
            }

            return(base.Visit(type));
        }
コード例 #31
0
ファイル: TypeDecl.cs プロジェクト: Ashod/Phalanger
		private GenericParameterDesc[]/*!!*/ ToGenericParameters(DMember/*!*/ declaringMember, out int mandatoryCount)
		{
			Debug.Assert(declaringMember != null);

			if (typeParams.Count == 0)
			{
				mandatoryCount = 0;
				return GenericParameterDesc.EmptyArray;
			}

			GenericParameterDesc[] result = new GenericParameterDesc[typeParams.Count];
			mandatoryCount = 0;
			for (int i = 0; i < typeParams.Count; i++)
			{
				result[i] = new GenericParameter(typeParams[i].Name, i, declaringMember).GenericParameterDesc;
				if (typeParams[i].DefaultType == null)
					mandatoryCount++;
			}
			return result;
		}
        private void UpdateParameterLeastType(ParameterReference parameter, IEnumerable <StackEntryUsageResult> usageResults)
        {
            int pIndex         = parameter.Index;
            int parameterDepth = GetActualTypeDepth(parameter.ParameterType);

            int                    currentLeastDepth = 0;
            TypeReference          currentLeastType  = null;
            List <MethodSignature> signatures        = null;

            //update the result array as in if (needUpdate) block below
            foreach (var usage in usageResults)
            {
                bool needUpdate = false;

                switch (usage.Instruction.OpCode.Code)
                {
                case Code.Newobj:
                case Code.Call:
                case Code.Callvirt:
                    MethodReference method = (MethodReference)usage.Instruction.Operand;

                    //potential generalization to object does not really make sense
                    //from a readability/maintainability point of view
                    if (IsSystemObjectMethod(method))
                    {
                        continue;
                    }
                    //we cannot really know if suggestion would work since the collection
                    //is non-generic thus we ignore it
                    TypeReference type = method.DeclaringType;
                    if (IsFromNonGenericCollectionNamespace(type.Namespace))
                    {
                        continue;
                    }

                    int pcount = method.HasParameters ? method.Parameters.Count : 0;
                    if (usage.StackOffset == pcount)
                    {
                        //argument is used as `this` in the call
                        if (signatures == null)
                        {
                            signatures = GetSignatures(usageResults);
                        }
                        currentLeastType = GetBaseImplementor(GetActualType(type), signatures);
                    }
                    else
                    {
                        //argument is also used as an argument in the call
                        currentLeastType = method.Parameters [pcount - usage.StackOffset - 1].ParameterType;

                        //if parameter type is a generic, find the 'real' constructed type
                        GenericParameter gp = (currentLeastType as GenericParameter);
                        if (gp != null)
                        {
                            currentLeastType = GetConstructedGenericType(method, gp);
                        }
                    }

                    //if the best we could find is object or non-generic collection, ignore this round
                    if (currentLeastType == null || IsIgnoredSuggestionType(currentLeastType))
                    {
                        continue;
                    }

                    needUpdate = true;
                    break;

                case Code.Stfld:
                case Code.Stsfld:
                    FieldReference field = (FieldReference)usage.Instruction.Operand;
                    currentLeastType = field.FieldType;

                    needUpdate = true;
                    break;
                }

                if (needUpdate)
                {
                    currentLeastDepth = GetActualTypeDepth(currentLeastType);
                    if (null == types_least [pIndex] || currentLeastDepth > depths_least [pIndex])
                    {
                        types_least [pIndex]  = currentLeastType;
                        depths_least [pIndex] = currentLeastDepth;
                    }
                    if (currentLeastDepth == parameterDepth)                     //no need to check further
                    {
                        return;
                    }
                }
            }
        }
コード例 #33
0
 static bool AreSame(GenericParameter a, GenericParameter b)
 {
     return a.Position == b.Position;
 }
        private static TypeReference GetConstructedGenericType(MemberReference method, GenericParameter parameter)
        {
            int position = parameter.Position;

            if (parameter.Owner is MethodReference)
            {
                GenericInstanceMethod gim = (method as GenericInstanceMethod);
                // 'gim' can be null in special cases, e.g. a generated Set method on a multidim array
                if (gim != null)
                {
                    return(gim.GenericArguments [position]);
                }
            }
            if (parameter.Owner is TypeReference)
            {
                GenericInstanceType git = (method.DeclaringType as GenericInstanceType);
                if (git != null)
                {
                    return(git.GenericArguments [position]);
                }
            }
            return(parameter.Owner.GenericParameters [position]);
        }
コード例 #35
0
 public bool TryGetGenericConstraintMapping(GenericParameter generic_parameter, out MetadataToken[] mapping)
 {
     return GenericConstraints.TryGetValue(generic_parameter.token.RID, out mapping);
 }
        internal GenericParameterDeclarationWithMonoCecil(AssemblyWithMonoCecil assembly, GenericParameter type)
        {
            this.type      = type;
            attributes     = new Lazy <Attributes>(() => new Attributes(assembly, type));
            typeConstraint = GetTypeConstraint(type);
            direction      = GetDirection(type);
            hasEmptyConstructorConstraint = type.HasDefaultConstructorConstraint && !type.HasNotNullableValueTypeConstraint;
            genericParameterConstraints   = new List <GenericParameterReferenceWithMonoCecil>();
            interfaceConstraints          = new List <InterfaceReferenceWithMonoCecil>();
            foreach (TypeReference constraintType in type.Constraints)
            {
                TypeDefinition constraintTypeDefinition = constraintType.Resolve();
                if (constraintType.IsGenericParameter)
                {
                    genericParameterConstraints.Add(new GenericParameterReferenceWithMonoCecil(constraintType));
                }
                else if (constraintTypeDefinition.IsInterface)
                {
                    interfaceConstraints.Add(new InterfaceReferenceWithMonoCecil(assembly, constraintType));
                }
                else if (constraintTypeDefinition.IsClass)
                {
                    if (baseClassConstraint != null)
                    {
                        throw new InvalidOperationException("GenericParameterDeclaration appears to have 2 base classes.");
                    }

                    if (constraintType.FullName != "System.ValueType")
                    {
                        baseClassConstraint = new ClassReferenceWithMonoCecil(assembly, constraintType);
                    }
                }
                else
                {
                    throw new InvalidOperationException("Unknown constraint type.");
                }
            }
        }
コード例 #37
0
ファイル: Methods.cs プロジェクト: tiaohai/Phalanger
		/// <summary>
		/// Returns a <see cref="PhpRoutineSignature"/> for the specified argfull <see cref="MethodInfo"/>.
		/// </summary>
		/// <exception cref="ReflectionException">Invalid argfull.</exception>
		public static PhpRoutineSignature/*!*/ FromArgfullInfo(PhpRoutine/*!*/ routine, MethodInfo/*!*/ argfull)
		{
			// determine aliasReturn
			bool alias_return = false;

			if (argfull.ReturnType != Types.Object[0])
			{
				if (argfull.ReturnType == Types.PhpReference[0]) alias_return = true;
				else throw new ReflectionException("TODO");
			}

			ParameterInfo[] parms = argfull.GetParameters();

			int parms_length = parms.Length;
			int parms_offset = 1;

			if (--parms_length < 0 || parms[0].ParameterType != Types.ScriptContext[0])
			{
				// TODO: resource
				throw new ReflectionException("Invalid static argfull signature of method " + routine.FullName);
			}

			// process pseudo-generic parameters:
			int j = parms_offset;
			while (j < parms.Length && parms[j].ParameterType == Types.DTypeDesc[0]) j++;
			int generic_param_count = j - parms_offset;

			int mandatory_generic_param_count = 0;
			GenericParameter[] generic_params = (generic_param_count > 0) ? new GenericParameter[generic_param_count] : GenericParameter.EmptyArray;

			for (int i = 0; i < generic_param_count; i++)
			{
				ParameterInfo pinfo = parms[i + parms_offset];
				generic_params[i] = new GenericParameter(new Name(pinfo.Name), i, routine);

				DTypeSpecAttribute default_type = DTypeSpecAttribute.Reflect(pinfo);
				if (default_type != null)
				{
					// TODO:
					// generic_params[i].WriteUp(default_type.TypeSpec.GetTypeDesc(null, null, null, null).Type);
				}
				else
				{
					generic_params[i].WriteUp(null);

					if (mandatory_generic_param_count < i)
					{
						// TODO: resource
						throw new ReflectionException("Invalid signature");
					}
					else
						mandatory_generic_param_count++;
				}
			}

			parms_offset += generic_param_count;
			parms_length -= generic_param_count;

			// set up genericParams, aliasMask, typeHints, and mandatoryParamCount:
			BitArray alias_mask = new BitArray(parms_length, false);
			DType[] type_hints = new DType[parms_length];
			int mandatory_param_count = 0;

			for (int i = 0; i < parms_length; i++)
			{
				ParameterInfo pinfo = parms[i + parms_offset];

				if (pinfo.ParameterType != Types.Object[0])
				{
					if (pinfo.ParameterType == Types.PhpReference[0])
						alias_mask[i] = true;
					else
						return null;
				}

				DTypeSpecAttribute type_hint = DTypeSpecAttribute.Reflect(pinfo);
				if (type_hint != null)
				{
					// TODO:
					// type_hints[i] = type_hint.TypeSpec.GetTypeDesc(null, null, null, null).Type;
				}

				if (!pinfo.IsOptional)
				{
					if (mandatory_param_count < i)
					{
						// invalid optional parameters
						throw new ReflectionException("Invalid signature");
					}
					else mandatory_param_count++;
				}
			}

			return new PhpRoutineSignature(generic_params, mandatory_generic_param_count).
			  WriteUp(alias_return, alias_mask, type_hints, mandatory_param_count);
		}
コード例 #38
0
        /// <summary>
        /// Create a panel for the specific parameter
        /// </summary>
        /// <param name="param">the parameter to create panel for</param>
        /// <param name="defaultValue">The default value for the parameter</param>
        /// <returns>the panel</returns>
        private static ParamInputPanel CreatePanelForParameter(ParameterInfo param, object defaultValue)
        {
            ParamInputPanel panel = new ParamInputPanel();

            panel.Height = 50;
            panel.Width  = 400;
            Point textBoxStart = new Point(100, 10);

            #region add the label for the parameter
            Label paramNameLabel = new Label();
            paramNameLabel.AutoSize = true;
            panel.Controls.Add(paramNameLabel);
            paramNameLabel.Location = new Point(10, textBoxStart.Y);
            #endregion

            if (param == null)
            { // a generic parameter
                GenericParameter p = defaultValue as GenericParameter;

                paramNameLabel.Text = "";

                String[] options = Array.ConvertAll <Type, String>(p.AvailableTypes, delegate(Type t) { return(t.Name); });
                ComboBox combo   = new ComboBox();
                panel.Controls.Add(combo);
                combo.Location = textBoxStart;
                combo.Items.AddRange(options);
                combo.SelectedIndex    = Array.FindIndex <String>(options, p.SelectedType.ToString().Equals);
                panel.GetParamFunction =
                    delegate()
                {
                    return
                        (new GenericParameter(
                             p.AvailableTypes[Array.FindIndex <String>(options, combo.Text.ToString().Equals)],
                             p.AvailableTypes));
                };
            }
            else
            {
                Type paramType = param.ParameterType;
                paramNameLabel.Text = String.Format("{0}:", ParseParameterName(param));

                if (paramType.IsEnum)
                {
                    ComboBox combo = new ComboBox();
                    panel.Controls.Add(combo);
                    combo.Location = textBoxStart;
                    combo.Items.AddRange(Enum.GetNames(paramType));
                    combo.SelectedIndex = 0;
                    combo.Width         = 240;

                    panel.GetParamFunction =
                        delegate
                    {
                        return(Enum.Parse(paramType, combo.SelectedItem.ToString(), true));
                    };
                }
                else if (paramType == typeof(bool))
                {
                    ComboBox combo = new ComboBox();
                    panel.Controls.Add(combo);
                    combo.Location = textBoxStart;
                    combo.Items.AddRange(new String[] { "True", "False" });
                    combo.SelectedIndex    = 0;
                    panel.GetParamFunction =
                        delegate()
                    {
                        return(combo.SelectedItem.ToString().Equals("True"));
                    };
                }
                else if (paramType == typeof(UInt64) || paramType == typeof(int) || paramType == typeof(double))
                {
                    //Create inpout box for the int paramater
                    TextBox inputTextBox = new TextBox();
                    panel.Controls.Add(inputTextBox);
                    inputTextBox.Location = textBoxStart;
                    inputTextBox.Text     = defaultValue == null ? "0" : defaultValue.ToString();

                    panel.GetParamFunction =
                        delegate()
                    {
                        return(Convert.ChangeType(inputTextBox.Text, paramType));
                    };
                }
                else if (paramType == typeof(MCvScalar))
                {
                    TextBox[] inputBoxes = new TextBox[4];
                    int       boxWidth   = 40;

                    //Create input boxes for the scalar value
                    for (int i = 0; i < inputBoxes.Length; i++)
                    {
                        inputBoxes[i] = new TextBox();
                        panel.Controls.Add(inputBoxes[i]);
                        inputBoxes[i].Location = new Point(textBoxStart.X + i * (boxWidth + 5), textBoxStart.Y);
                        inputBoxes[i].Width    = boxWidth;
                        inputBoxes[i].Text     = "0.0";
                    }
                    panel.GetParamFunction =
                        delegate()
                    {
                        double[] values = new double[4];
                        for (int i = 0; i < inputBoxes.Length; i++)
                        {
                            values[i] = Convert.ToDouble(inputBoxes[i].Text);
                        }
                        return(new MCvScalar(values[0], values[1], values[2], values[3]));
                    };
                }
                else if (paramType == typeof(PointF))
                {
                    TextBox[] inputBoxes = new TextBox[2];
                    int       boxWidth   = 40;

                    //Create input boxes for the scalar value
                    for (int i = 0; i < 2; i++)
                    {
                        inputBoxes[i] = new TextBox();
                        panel.Controls.Add(inputBoxes[i]);
                        inputBoxes[i].Location = new Point(textBoxStart.X + i * (boxWidth + 5), textBoxStart.Y);
                        inputBoxes[i].Width    = boxWidth;
                        inputBoxes[i].Text     = "0.0";
                    }
                    panel.GetParamFunction =
                        delegate()
                    {
                        float[] values = new float[inputBoxes.Length];
                        for (int i = 0; i < inputBoxes.Length; i++)
                        {
                            values[i] = Convert.ToSingle(inputBoxes[i].Text);
                        }
                        return(new PointF(values[0], values[1]));
                    };
                }
                else if (paramType.GetInterface("IColor") == typeof(IColor))
                {
                    IColor t = Activator.CreateInstance(paramType) as IColor;
                    //string[] channelNames = ReflectColorType.GetNamesOfChannels(t);
                    TextBox[] inputBoxes = new TextBox[t.Dimension];
                    int       boxWidth   = 40;

                    //Create input boxes for the scalar value
                    for (int i = 0; i < inputBoxes.Length; i++)
                    {
                        inputBoxes[i] = new TextBox();
                        panel.Controls.Add(inputBoxes[i]);
                        inputBoxes[i].Location = new Point(textBoxStart.X + i * (boxWidth + 5), textBoxStart.Y);
                        inputBoxes[i].Width    = boxWidth;
                        inputBoxes[i].Text     = "0.0";
                    }
                    panel.GetParamFunction =
                        delegate()
                    {
                        double[] values = new double[4];
                        for (int i = 0; i < inputBoxes.Length; i++)
                        {
                            values[i] = Convert.ToDouble(inputBoxes[i].Text);
                        }
                        IColor color = Activator.CreateInstance(paramType) as IColor;
                        color.MCvScalar = new MCvScalar(values[0], values[1], values[2], values[3]);
                        return(color);
                    };
                }
                else
                {
                    throw new NotSupportedException(String.Format(Properties.StringTable.ParameterTypeIsNotSupported, paramType.Name));
                }
            }
            return(panel);
        }
コード例 #39
0
 internal ITypeReference/*?*/ GetTypeReferenceForGenericConstraintRowId(
   GenericParameter genParam,
   uint interfaceRowId
 ) {
   uint constraintTypeToken = this.PEFileReader.GenericParamConstraintTable.GetConstraint(interfaceRowId);
   return this.GetTypeReferenceForToken(genParam, constraintTypeToken);
 }
コード例 #40
0
        protected void TypeReferenceInternal(GenericParameter gp, TypeReferenceContext context)
        {
            var ownerType   = gp.Owner as TypeReference;
            var ownerMethod = gp.Owner as MethodReference;

            if (context != null)
            {
                if (ownerType != null)
                {
                    if (TypeUtil.TypesAreAssignable(TypeInfo, ownerType, context.SignatureMethodType))
                    {
                        var resolved = JSIL.Internal.MethodSignature.ResolveGenericParameter(gp, context.SignatureMethodType);

                        if (resolved != null)
                        {
                            if (resolved != gp)
                            {
                                context.Push();
                                context.SignatureMethod = null;
                                try {
                                    TypeReference(resolved, context);
                                } finally {
                                    context.Pop();
                                }
                                return;
                            }
                            else
                            {
                                TypeIdentifier(resolved, context, false);
                                return;
                            }
                        }
                    }

                    if (TypeUtil.TypesAreEqual(ownerType, context.EnclosingMethodType))
                    {
                        TypeIdentifier(gp, context, false);
                        return;
                    }

                    if (TypeUtil.TypesAreEqual(ownerType, context.EnclosingType))
                    {
                        LocalOpenGenericParameter(gp);
                        return;
                    }

                    var ownerTypeResolved = ownerType.Resolve();
                    if (ownerTypeResolved != null)
                    {
                        // Is it a generic parameter of a compiler-generated class (i.e. enumerator function, delegate, etc)
                        //  nested inside our EnclosingType? If so, uhhhh, shit.
                        if (
                            TypeUtil.TypesAreEqual(context.EnclosingType, ownerTypeResolved.DeclaringType) &&
                            ownerTypeResolved.CustomAttributes.Any(
                                (ca) => ca.AttributeType.FullName == "System.Runtime.CompilerServices.CompilerGeneratedAttribute"
                                )
                            )
                        {
                            // FIXME: I HAVE NO IDEA WHAT I AM DOING
                            OpenGenericParameter(gp, Util.DemangleCecilTypeName(ownerTypeResolved.FullName));
                            return;
                        }
                    }

                    if (TypeUtil.TypesAreEqual(ownerType, context.AttributesMethodType))
                    {
                        LocalOpenGenericParameter(gp);
                        return;
                    }

                    if (TypeUtil.TypesAreEqual(ownerType, context.DefiningMethodType))
                    {
                        OpenGenericParameter(gp, Util.DemangleCecilTypeName(context.DefiningMethodType.FullName));
                        return;
                    }

                    if (TypeUtil.TypesAreEqual(ownerType, context.DefiningType))
                    {
                        OpenGenericParameter(gp, Util.DemangleCecilTypeName(context.DefiningType.FullName));
                        return;
                    }

                    throw new NotImplementedException(String.Format(
                                                          "Unimplemented form of generic type parameter: '{0}'.",
                                                          gp
                                                          ));
                }
                else if (ownerMethod != null)
                {
                    Func <MethodReference, int> getPosition = (mr) => {
                        for (var i = 0; i < mr.GenericParameters.Count; i++)
                        {
                            if (mr.GenericParameters[i].Name == gp.Name)
                            {
                                return(i);
                            }
                        }

                        throw new NotImplementedException(String.Format(
                                                              "Generic parameter '{0}' not found in method '{1}' parameter list",
                                                              gp, ownerMethod
                                                              ));
                    };

                    var ownerMethodIdentifier = new QualifiedMemberIdentifier(
                        new TypeIdentifier(ownerMethod.DeclaringType.Resolve()),
                        new MemberIdentifier(TypeInfo, ownerMethod)
                        );

                    if (ownerMethodIdentifier.Equals(ownerMethod, context.InvokingMethod, TypeInfo))
                    {
                        var gim = (GenericInstanceMethod)context.InvokingMethod;
                        TypeReference(gim.GenericArguments[getPosition(ownerMethod)], context);

                        return;
                    }

                    if (ownerMethodIdentifier.Equals(ownerMethod, context.EnclosingMethod, TypeInfo))
                    {
                        Identifier(gp.Name);

                        return;
                    }

                    if (
                        ownerMethodIdentifier.Equals(ownerMethod, context.DefiningMethod, TypeInfo) ||
                        ownerMethodIdentifier.Equals(ownerMethod, context.SignatureMethod, TypeInfo)
                        )
                    {
                        Value(String.Format("!!{0}", getPosition(ownerMethod)));

                        return;
                    }

                    throw new NotImplementedException(String.Format(
                                                          "Unimplemented form of generic method parameter: '{0}'.",
                                                          gp
                                                          ));
                }
            }
            else
            {
                throw new NotImplementedException("Cannot resolve generic parameter without a TypeReferenceContext.");
            }

            throw new NotImplementedException(String.Format(
                                                  "Unimplemented form of generic parameter: '{0}'.",
                                                  gp
                                                  ));
        }