Exemple #1
0
        /// <summary>
        /// Emits deserializing (SerializiationInfo, StreamingContext) constructor.
        /// </summary>
        private static void EmitDeserializingConstructor(PhpType /*!*/ phpType)
        {
            // (SerializationInfo, StreamingContext) constructor
            ConstructorBuilder ctor_builder = phpType.DeserializingConstructorBuilder;

            if (ctor_builder != null)
            {
                ILEmitter cil = new ILEmitter(ctor_builder);

                if (phpType.Base == null)
                {
                    EmitInvokePhpObjectDeserializingConstructor(cil);
                }
                else
                {
                    phpType.Base.EmitInvokeDeserializationConstructor(cil, phpType, null);
                }

                // [ __InitializeStaticFields(context) ]
                cil.Emit(OpCodes.Call, Methods.ScriptContext.GetCurrentContext);

                cil.EmitCall(OpCodes.Call, phpType.StaticFieldInitMethodInfo, null);
                cil.Emit(OpCodes.Ret);
            }
        }
Exemple #2
0
        /// <summary>
        /// Emit the PhpType finalizer. The finalizer is emitted only if there is __destruct() function
        /// and there is no finalizer in any base class already. The finalizer calls this.Dispose() which
        /// calls __destruct() function directly.
        /// </summary>
        /// <param name="phpType"></param>
        private static void EmitFinalizer(PhpType /*!*/ phpType)
        {
            // only if __destruct was now defined in some base class, no need to override existing definition on Finalize
            DRoutine     basedestruct;
            DRoutineDesc destruct;

            if ((destruct = phpType.TypeDesc.GetMethod(DObject.SpecialMethodNames.Destruct)) != null && (phpType.Base == null ||
                                                                                                         phpType.Base.GetMethod(DObject.SpecialMethodNames.Destruct, phpType, out basedestruct) == GetMemberResult.NotFound))
            {
                MethodBuilder finalizer_builder = phpType.RealTypeBuilder.DefineMethod("Finalize", MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Family, typeof(void), Type.EmptyTypes);

                ILEmitter dil = new ILEmitter(finalizer_builder);

                // exact Finalize() method pattern follows:

                // try
                dil.BeginExceptionBlock();

                // this.Dispose(false)
                dil.Emit(OpCodes.Ldarg_0);
                dil.Emit(OpCodes.Ldc_I4_0);
                dil.Emit(OpCodes.Callvirt, PHP.Core.Emit.Methods.DObject_Dispose);

                // finally
                dil.BeginFinallyBlock();

                // Object.Finalize()
                dil.Emit(OpCodes.Ldarg_0);
                dil.Emit(OpCodes.Call, PHP.Core.Emit.Methods.Object_Finalize);

                dil.EndExceptionBlock();

                dil.Emit(OpCodes.Ret);
            }
        }
Exemple #3
0
        /// <summary>
        /// Defines CLR-friendly constructors based on a PHP &quot;constructor&quot; method.
        /// </summary>
        public static void DefineExportedConstructors(PhpType /*!*/ phpType)
        {
            phpType.Builder.ClrConstructorStubs = new List <StubInfo>();
            PhpMethod ctor = phpType.GetConstructor() as PhpMethod;

            if (ctor == null)
            {
                // the class defines (nor inherits) no constructor -> create a parameter-less CLR constructor
                ConstructorBuilder ctor_builder =
                    phpType.RealTypeBuilder.DefineConstructor(
                        DefaultConstructorAttributes,
                        CallingConventions.Standard,
                        Type.EmptyTypes);

                phpType.ClrConstructorInfos = new ConstructorInfo[] { ctor_builder };

                phpType.Builder.ClrConstructorStubs.Add(
                    new StubInfo(ctor_builder, new ParameterInfo[0], StubInfo.EmptyGenericParameters, null));
            }
            else if (!ctor.IsAbstract)
            {
                Debug.Assert(!ctor.IsStatic && ctor.Signature.GenericParamCount == 0);

                if (ctor.Builder == null)
                {
                    // contructor not defined in this class
                    phpType.ClrConstructorInfos = new ConstructorInfo[0];
                    return;
                }

                // infer constructor visibility
                List <ConstructorInfo> ctor_infos = new List <ConstructorInfo>();

                MethodAttributes attr = Reflection.Enums.ToMethodAttributes(ctor.RoutineDesc.MemberAttributes);

                foreach (StubInfo info in ClrStubBuilder.DefineMethodExportStubs(
                             ctor,
                             attr,
                             true,
                             delegate(string[] genericParamNames, object[] parameterTypes, object returnType)
                {
                    // accept all overloads
                    return(true);
                }))
                {
                    phpType.Builder.ClrConstructorStubs.Add(info);

                    // infos are returned in ascending order w.r.t. parameter count
                    ctor_infos.Add(info.ConstructorBuilder);
                }

                phpType.ClrConstructorInfos = ctor_infos.ToArray();
            }
        }
        /// <summary>
        /// Emits init field helpers (<c>__lastContext</c> field, <c>&lt;InitializeInstanceFields&gt;</c>
        /// method and <c>__InitializeStaticFields</c> into a class.
        /// </summary>
        internal static void EmitInitFieldHelpers(PhpType phpType)
        {
            //
            // <InitializeInstanceFields>
            //

            // <InitializeInstanceFields> method - will contain instance field initialization
            phpType.Builder.InstanceFieldInit = phpType.RealTypeBuilder.DefineMethod(
                InstanceFieldInitMethodName,
#if SILVERLIGHT
                MethodAttributes.Public | MethodAttributes.HideBySig,
#else
                MethodAttributes.Private | MethodAttributes.HideBySig,
#endif
                CallingConventions.Standard,
                Types.Void,
                Types.ScriptContext);
            phpType.Builder.InstanceFieldInitEmitter = new ILEmitter(phpType.Builder.InstanceFieldInit);

            //
            // <InitializeStaticFields>
            //

            // <InitializeStaticFields> method has already been defined during the analysis phase - will contain (thread)
            // static field initialization
            ILEmitter cil = new ILEmitter(phpType.StaticFieldInitMethodBuilder);

            if (phpType.Builder.HasThreadStaticFields)
            {
                // __lastContext thread-static field - will contain the last SC that inited static fields for this thread
                FieldBuilder last_context = phpType.RealTypeBuilder.DefineField(
                    "<lastScriptContext>",
                    Types.ScriptContext[0],
                    FieldAttributes.Private | FieldAttributes.Static);

                // SILVERLIGHT: Not sure what this does & what would be the right behavior...
#if !SILVERLIGHT
                last_context.SetCustomAttribute(AttributeBuilders.ThreadStatic);
#endif
                //
                Label init_needed_label = cil.DefineLabel();
                // [ if (arg0 == __lastContext) ret ]
                cil.Emit(OpCodes.Ldarg_0);
                cil.Emit(OpCodes.Ldsfld, last_context);
                cil.Emit(OpCodes.Bne_Un_S, init_needed_label);
                cil.Emit(OpCodes.Ret);
                // [ __lastContext = arg0 ]
                cil.MarkLabel(init_needed_label);
                cil.Emit(OpCodes.Ldarg_0);
                cil.Emit(OpCodes.Stsfld, last_context);

                // the rest of the method is created when fields are emitted
            }
        }
Exemple #5
0
        private static void EmitExportedConstructors(PhpType /*!*/ phpType)
        {
            PhpMethod ctor = phpType.GetConstructor() as PhpMethod;

            foreach (StubInfo info in phpType.Builder.ClrConstructorStubs)
            {
                EmitExportedConstructor(
                    phpType,
                    info.ConstructorBuilder,
                    ctor,
                    info.Parameters);
            }
        }
Exemple #6
0
        internal override PhpTypeCode EmitReadFieldOfThisInInstanceMethod(CodeGenerator codeGenerator, bool wantRef)
        {
            PhpType   type = codeGenerator.LocationStack.PeekMethodDecl().Type;
            DProperty property;

            if (type.GetProperty(VarName, type, out property) == GetMemberResult.OK && !property.IsStatic)
            {
                // ask the DProperty to emit code that reads the field
                return(property.EmitGet(codeGenerator, IndexedPlace.ThisArg, wantRef, null, false));
            }
            else
            {
                return(base.EmitReadFieldOfThisInInstanceMethod(codeGenerator, wantRef));
            }
        }
Exemple #7
0
        internal override AssignmentCallback EmitWriteFieldOfThisInInstanceMethod(CodeGenerator /*!*/ codeGenerator, bool writeRef)
        {
            PhpType   type = codeGenerator.LocationStack.PeekMethodDecl().Type;
            DProperty property;

            if (type.GetProperty(VarName, type, out property) == GetMemberResult.OK && !property.IsStatic)
            {
                // ask the DProperty to emit code that writes the field
                return(property.EmitSet(codeGenerator, IndexedPlace.ThisArg, writeRef, null, false));
            }
            else
            {
                return(base.EmitWriteFieldOfThisInInstanceMethod(codeGenerator, writeRef));
            }
        }
Exemple #8
0
        /// <summary>
        /// Emits constructors into a class.
        /// </summary>
        internal static void EmitClassConstructors(PhpType /*!*/ phpType)
        {
#if !SILVERLIGHT
            EmitDeserializingConstructor(phpType);
#endif
            EmitShortConstructor(phpType);
            EmitLongConstructor(phpType);

            EmitFinalizer(phpType);

            // emit CLR-friendly constructors based on the PHP constructor method effective for the type
            if (phpType.IsExported)
            {
                EmitExportedConstructors(phpType);
            }
        }
Exemple #9
0
        /// <summary>
        /// Used by CLR modules and PHP pure modules.
        /// </summary>
        internal static void ReflectTypes(Assembly /*!*/ realAssembly, Dictionary <string, DTypeDesc> /*!*/ types)
        {
            // types:
            foreach (Type type in realAssembly.GetTypes())
            {
                if (type.IsVisible)
                {
                    // skip PHP types that were declared conditionally:
                    if (PhpType.IsPhpRealType(type) && PhpType.IsRealConditionalDefinition(type))
                    {
                        continue;
                    }

                    // converts CLR namespaces and nested types to PHP namespaces:
                    string full_name = ClrNotationUtils.FromClrNotation(type.FullName, true).ToString();

                    DTypeDesc existing;
                    if (types.TryGetValue(full_name, out existing))
                    {
                        ClrTypeDesc existing_clr = existing as ClrTypeDesc;
                        if (existing_clr != null && (existing_clr.GenericOverloads.Count > 0 || type.IsGenericTypeDefinition))
                        {
                            ClrTypeDesc new_clr = DTypeDesc.Create(type) as ClrTypeDesc;
                            if (new_clr != null)
                            {
                                // type is overloaded by the number of generic parameters:
                                existing_clr.AddGenericOverload(new_clr);
                            }
                            else
                            {
                                // do not add, just mark existing with the flag:
                                existing.MemberAttributes |= PhpMemberAttributes.Ambiguous;
                            }
                        }
                        else
                        {
                            // do not add, just mark existing with the flag:
                            existing.MemberAttributes |= PhpMemberAttributes.Ambiguous;
                        }
                    }
                    else
                    {
                        types[full_name] = DTypeDesc.Create(type);
                    }
                }
            }
        }
Exemple #10
0
        private static void EmitExportedConstructor(PhpType /*!*/ phpType, ConstructorBuilder /*!*/ ctorStubBuilder,
                                                    PhpMethod phpCtor, ParameterInfo[] /*!*/ parameters)
        {
            // set parameter names and attributes
            if (phpCtor != null)
            {
                ClrStubBuilder.DefineStubParameters(
                    ctorStubBuilder,
                    phpCtor.Builder.Signature.FormalParams,
                    parameters);
            }

            // emit ctor body
            ILEmitter cil = new ILEmitter(ctorStubBuilder);

            // [ this(ScriptContext.CurrentContext ]
            cil.Ldarg(FunctionBuilder.ArgThis);
            cil.EmitCall(OpCodes.Call, Methods.ScriptContext.GetCurrentContext, null);

            LocalBuilder sc_local = cil.DeclareLocal(Types.ScriptContext[0]);

            cil.Stloc(sc_local);
            cil.Ldloc(sc_local);

            cil.LdcI4(1);
            cil.Emit(OpCodes.Call, phpType.ShortConstructorInfo);

            if (phpCtor != null)
            {
                // invoke the PHP ctor method
                ClrStubBuilder.EmitMethodStubBody(
                    cil,
                    new Place(sc_local),
                    parameters,
                    new GenericTypeParameterBuilder[0],
                    Types.Void,
                    phpCtor,
                    phpCtor.DeclaringType);
            }
            else
            {
                cil.Emit(OpCodes.Ret);
            }
        }
Exemple #11
0
        /// <summary>
        /// Traces the calling stack to discover current PHP class context.
        /// </summary>
        /// <returns><see cref="Type"/> of the PHP class that represents current class context for this thread or
        /// <B>null</B> if this thread is executing in a function or startup Main context.</returns>
        public static DTypeDesc GetClassContext()
        {
            // SILVERLIGHT: Todo Todo .. ? what to do here ?
#if !SILVERLIGHT
            StackTrace stack_trace = new StackTrace(1);
            int        frame_count = stack_trace.FrameCount;

            for (int i = 0; i < frame_count; i++)
            {
                StackFrame stack_frame = stack_trace.GetFrame(i);

                MethodBase method = stack_frame.GetMethod();
                Type       type   = method.DeclaringType;
                if (type != null)
                {
                    if (PhpType.IsPhpRealType(type))
                    {
                        return(DTypeDesc.Create(type));
                    }

                    MethodInfo minfo = method as MethodInfo;
                    if (minfo != null)
                    {
                        ParameterInfo[] parameters = minfo.GetParameters();
                        if (!PhpFunctionUtils.IsArglessStub(minfo, parameters) &&
                            PhpScript.IsScriptType(minfo.DeclaringType) && !PhpScript.IsMainHelper(minfo, parameters))
                        {
                            return(null);
                        }
                        // if the method is a helper method (Main, an arg-less overload, a constructor, etc.),
                        // continue with the trace
                    }
                }
            }
#endif
            return(null);
        }
Exemple #12
0
        /// <summary>
        /// Reflect argfull function, PHP types and constants from given <c>type</c>.
        /// </summary>
        /// <param name="types">Dictionary of types where newly discovered PHP types will be placed. (Types having [ImplementsType] attribute.)</param>
        /// <param name="functions">Dictionary of reflected functions.</param>
        /// <param name="constants">Dictionary of reflected constants.</param>
        /// <param name="type">The type to reflect functions from.</param>
        /// <param name="full">Whether to perform full function reflect.</param>
        private void ReflectArgfulls(
            Dictionary <string, DTypeDesc> /*!*/ types,
            Dictionary <string, DRoutineDesc> /*!*/ functions,
            DualDictionary <string, DConstantDesc> /*!*/ constants,
            Type /*!*/ type, bool full)
        {
            // skip generic types:
            if (type.IsGenericTypeDefinition)
            {
                return;
            }

            if (PhpType.IsPhpRealType(type))
            {
                var dtype = PhpTypeDesc.Create(type);
                types[dtype.MakeSimpleName()] = dtype;
            }

            // reflect even if it is PhpType to find global functions [ImplementsFunction] and constants [ImplementsConstant]
            if (IsLibraryType(type))
            {
                ReflectLibraryType(functions, constants, type, full);
            }
        }
Exemple #13
0
        /// <summary>
        /// Generates a <c>&lt;PopulateTypeDesc&gt;</c> method that populates a <see cref="DTypeDesc"/>
        /// at runtime (instead of reflecting the class).
        /// </summary>
        /// <param name="phpType">The class representation used in the compiler.</param>
        internal static void GenerateTypeDescPopulation(PhpType phpType)
        {
            MethodBuilder populator = DefinePopulateTypeDescMethod(phpType.RealTypeBuilder);
            ILEmitter     il        = new ILEmitter(populator);

            // methods
            foreach (KeyValuePair <Name, DRoutineDesc> pair in phpType.TypeDesc.Methods)
            {
                if (!pair.Value.IsAbstract)
                {
                    EmitAddMethod(il, pair.Key.ToString(), pair.Value.MemberAttributes,
                                  pair.Value.PhpMethod.ArgLessInfo);
                }
            }

            // fields
            foreach (KeyValuePair <VariableName, DPropertyDesc> pair in phpType.TypeDesc.Properties)
            {
                PhpField field = pair.Value.PhpField;

                // determine whether we need to add this field
                if (field.Implementor == field.DeclaringPhpType || field.UpgradesVisibility)
                {
                    EmitAddProperty(il, phpType.Builder.RealOpenType, pair.Key.ToString(),
                                    pair.Value.MemberAttributes, field.RealField);
                }
            }

            // constants
            foreach (KeyValuePair <VariableName, DConstantDesc> pair in phpType.TypeDesc.Constants)
            {
                EmitAddConstant(il, pair.Key.ToString(), pair.Value.ClassConstant);
            }

            il.Emit(OpCodes.Ret);
        }
Exemple #14
0
        /// <summary>
        /// Reflect PHP classes declared statically in the given script <c>type</c>.
        /// </summary>
        /// <param name="scriptType">Script type to reflect.</param>
        /// <param name="types">List of types to reflect to.</param>
        private static void ReflectScriptTypeClasses(Type scriptType,
                                                     Dictionary <string, DTypeDesc> /*!*/ types)
        {
            ScriptDeclaresAttribute script_declares = ScriptDeclaresAttribute.Reflect(scriptType);

            if (script_declares == null)
            {
                return;
            }

            var module = scriptType.Module;

            foreach (var typeToken in script_declares.DeclaredTypes)
            {
                Type type = module.ResolveType(typeToken);

                // reflect PHP class, skip PHP types that were declared conditionally
                if (PhpType.IsPhpRealType(type) && !PhpType.IsRealConditionalDefinition(type))
                {
                    // converts CLR namespaces and nested types to PHP namespaces:
                    string full_name = QualifiedName.FromClrNotation(type.FullName, true).ToString();

                    // Creating PhpTypeDesc with cache lookup since this type can be in the cache already:
                    // Also force PHP type, because we already checked PhpType.IsPhpRealType(type)
                    PhpTypeDesc phpType = (PhpTypeDesc)DTypeDesc.Create(type.TypeHandle);

                    DTypeDesc existing;
                    if (types.TryGetValue(full_name, out existing))
                    {
                        // TODO (TP): can be generic overload!!
                        existing.MemberAttributes |= PhpMemberAttributes.Ambiguous;
                    }
                    types.Add(full_name, phpType);
                }
            }
        }
Exemple #15
0
		/// <summary>
		/// Emits stubs for all overloads of one overridden or implemented method.
		/// </summary>
		/// <param name="stubs">Already generated stubs.</param>
		/// <param name="target">The overriding/implementing method.</param>
		/// <param name="targetType">The type (perhaps constructed) that declared <paramref name="target"/>.</param>
		/// <param name="declaringType">The type where the stubs should be emitted.</param>
		/// <param name="template">The method being overridden/implemented.</param>
		/// <param name="newSlot"><B>True</B> if the stub should be assigned a new vtable slot,
		/// <B>false</B> otherwise.</param>
		private void EmitOverrideStubs(IDictionary<string, MethodBuilder>/*!*/ stubs, PhpMethod/*!*/ target,
			DType/*!*/ targetType, PhpType/*!*/ declaringType, DMemberRef/*!*/ template, bool newSlot)
		{
			ClrMethod clr_template = template.Member as ClrMethod;
			if (clr_template == null)
			{
                if (!target.IsStatic)
				    EmitOverrideStubsForPhpTemplate(stubs, target, targetType, declaringType, template, newSlot);

				return;
			}

            //
            // following code emits stubs in case of CLR base method
            //

			ConstructedType constructed_type = template.Type as ConstructedType;
			TypeBuilder type_builder = declaringType.RealTypeBuilder;

			// override all virtual non-final overloads
			foreach (ClrMethod.Overload overload in clr_template.Overloads)
			{
				if (overload.Method.IsVirtual && !overload.Method.IsFinal)
				{
					// map generic type parameters according to the constructed type
					Type constructed_return_type;
					ParameterInfo[] constructed_params = overload.MakeConstructed(constructed_type, out constructed_return_type);

					// check whether we have not generated this signature before
					string clr_sig = ClrMethod.Overload.ClrSignatureToString(
						overload.GenericParamCount,
						constructed_params,
						constructed_return_type);

					if (stubs.ContainsKey(clr_sig)) continue;

					Type[] param_types = new Type[constructed_params.Length];

					for (int j = 0; j < param_types.Length; j++)
					{
						param_types[j] = constructed_params[j].ParameterType;
					}

					// determine the stub attributes
					MethodAttributes attr;
					string name;

					name = overload.Method.Name;
					attr = Reflection.Enums.ToMethodAttributes(target.MemberDesc.MemberAttributes);
					attr |= (MethodAttributes.Virtual | MethodAttributes.HideBySig);

					if (newSlot) attr |= MethodAttributes.NewSlot;

					MethodBuilder overload_builder = type_builder.DefineMethod(name, attr);

					if (overload.MandatoryGenericParamCount > 0)
					{
						// define the same generic parameters that are defined for the overridden method
						// (the same constraints but possibly having different names)
						ClrStubBuilder.DefineStubGenericParameters(
							overload_builder,
							overload.GenericParameters,
							target.Signature,
							param_types);
					}

					overload_builder.SetReturnType(constructed_return_type);
					overload_builder.SetParameters(param_types);

					// set parameter names and attributes
					ClrStubBuilder.DefineStubParameters(overload_builder,
						target.Builder.Signature.FormalParams, constructed_params);

					if (!overload_builder.IsAbstract)
					{
						EmissionContext emission_context = SetupStubPlaces(target.DeclaringPhpType, false);

						try
						{
							// convert parameters and invoke the target
							ClrStubBuilder.EmitMethodStubBody(
								new ILEmitter(overload_builder),
								ScriptContextPlace,
								constructed_params,
								overload.GenericParameters,
								constructed_return_type,
								target,
								targetType);
						}
						finally
						{
							RestorePlaces(emission_context);
						}
					}

					stubs.Add(clr_sig, overload_builder);
				}
			}
		}
Exemple #16
0
		/// <summary>
		/// Emits property stubs for a overriden or implemented CLR property.
		/// </summary>
		/// <param name="stubs">Already generated stubs.</param>
		/// <param name="target">The overriding/implementing field.</param>
		/// <param name="declaringType">The type where the stubs should be emitted.</param>
		/// <param name="template">The property being overriden/implemented.</param>
		/// <param name="newSlot"><B>True</B> if the stub should be assigned a new vtable slot,
		/// <B>false</B> otherwise.</param>
		private void EmitOverrideStubs(IDictionary<Type, PropertyBuilder>/*!*/ stubs, PhpField/*!*/ target,
			PhpType/*!*/ declaringType, DMemberRef/*!*/ template, bool newSlot)
		{
			ClrProperty clr_template = template.Member as ClrProperty;
			if (clr_template == null) return;

			MethodInfo getter = clr_template.Getter;
			MethodInfo setter = clr_template.Setter;

			// we're only interested in non-final virtual getters/setters
			if (getter != null && (!getter.IsVirtual || getter.IsFinal)) getter = null;
			if (setter != null && (!setter.IsVirtual || setter.IsFinal)) setter = null;

			ConstructedType constructed_type = template.Type as ConstructedType;

			// map property type according to constructed type
			Type property_type = clr_template.RealProperty.PropertyType;
			if (constructed_type != null) property_type = constructed_type.MapRealType(property_type);

			// do we already have getter/setter of this type?
			PropertyBuilder prop_builder;
			if (stubs.TryGetValue(property_type, out prop_builder))
			{
				if (prop_builder.GetGetMethod(true) != null) getter = null;
				if (prop_builder.GetSetMethod(true) != null) setter = null;
			}

			if (getter != null || setter != null)
			{
				if (prop_builder == null)
				{
					// the property might already exist - we could be just adding an accessor
					TypeBuilder type_builder = declaringType.RealTypeBuilder;

					prop_builder = type_builder.DefineProperty(
						clr_template.Name.ToString(),
						Reflection.Enums.ToPropertyAttributes(target.MemberDesc.MemberAttributes),
						property_type,
						Type.EmptyTypes);

					stubs.Add(property_type, prop_builder);
				}

				if (getter != null)
				{
					// add getter
					MethodBuilder getter_builder = DefineOverrideAccessor(
						declaringType,
						target,
						getter,
						newSlot,
						property_type,
						Type.EmptyTypes);

					prop_builder.SetGetMethod(getter_builder);

					EmitFieldExportGetter(target, prop_builder, getter_builder);
				}

				if (setter != null)
				{
					// add setter
					MethodBuilder setter_builder = DefineOverrideAccessor(
						declaringType,
						target,
						setter,
						newSlot,
						Types.Void,
						new Type[] { property_type });

					prop_builder.SetSetMethod(setter_builder);

					EmitFieldExportSetter(target, prop_builder, setter_builder);
				}
			}
		}
Exemple #17
0
		private EmissionContext SetupStubPlaces(PhpType/*!*/ type, bool stubIsStatic)
		{
			EmissionContext context = new EmissionContext(ScriptContextPlace, SelfPlace, il);

			ScriptContextPlace = new LazyLoadSCPlace();
			if (stubIsStatic)
			{
				SelfPlace = LiteralPlace.Null;
			}
			else
			{
				if (type.ProxyFieldInfo != null)
				{
					// the real this is not a DObject
					SelfPlace = new Place(IndexedPlace.ThisArg, type.ProxyFieldInfo);
				}
				else
				{
					// the real this is a DObject
					SelfPlace = IndexedPlace.ThisArg;
				}
			}

			return context;
		}
Exemple #18
0
		/// <summary>
		/// Enumerates all export overloads for the given target PHP method.
		/// </summary>
		public static IEnumerable<StubInfo> DefineMethodExportStubs(
			PhpRoutine/*!*/ target, PhpType/*!*/ declaringType,
			MethodAttributes attributes,
			bool defineConstructors,
			StubSignatureFilter/*!*/ signatureFilter)
		{
            Debug.Assert(target.Builder != null);

            Type return_type = Types.Object[0];

            PhpRoutineSignature signature = target.Signature;
			AST.FormalParam[] formal_params = target.Builder.Signature.FormalParams;
			AST.FormalTypeParam[] formal_type_params = target.Builder.TypeSignature.TypeParams;

			int gen_sig_count = signature.GenericParamCount - signature.MandatoryGenericParamCount + 1;
			int arg_sig_count = signature.ParamCount - signature.MandatoryParamCount + 1;

			// TODO: return type hints
			// HACK: change return type to void for methods that are apparently event handlers
			if (signature.GenericParamCount == 0 && arg_sig_count == 1 && signature.ParamCount == 2 &&
				(signature.TypeHints[0] == null || signature.TypeHints[0].RealType == Types.Object[0]) &&
				(signature.TypeHints[1] != null && typeof(EventArgs).IsAssignableFrom(signature.TypeHints[1].RealType)))
			{
				return_type = Types.Void;
			}

			for (int gen_sig = 0; gen_sig < gen_sig_count; gen_sig++)
			{
				for (int arg_sig = 0; arg_sig < arg_sig_count; arg_sig++)
				{
					// determine parameter types (except for method mandatory generic parameters)
					object[] parameter_types = GetStubParameterTypes(
						arg_sig + signature.MandatoryParamCount,
						gen_sig + signature.MandatoryGenericParamCount,
						signature,
						formal_type_params);

					// determine generic parameter names
					string[] generic_param_names = new string[target.Signature.MandatoryGenericParamCount + gen_sig];
					for (int i = 0; i < generic_param_names.Length; i++)
					{
						generic_param_names[i] = formal_type_params[i].Name.ToString();
					}

					// are we allowed to generate this signature?
					if (!signatureFilter(generic_param_names, parameter_types, return_type)) continue;

					GenericTypeParameterBuilder[] generic_params = StubInfo.EmptyGenericParameters;
					MethodBase method_base = null;
					MethodBuilder method = null;

					if (!defineConstructors)
					{
                        method = declaringType.RealTypeBuilder.DefineMethod(target.FullName, attributes);

						// determine generic parameters
						if (generic_param_names.Length > 0) generic_params = method.DefineGenericParameters(generic_param_names);

						method_base = method;
					}

					ParameterInfo[] parameters = new ParameterInfo[parameter_types.Length];

					// fill in parameter infos
					Type[] real_parameter_types = new Type[parameters.Length];
					for (int i = 0; i < parameters.Length; i++)
					{
						Type type = parameter_types[i] as Type;

						// generic method parameter fixup
						if (type == null)
						{
							int index = (int)parameter_types[i];
							if (index < 0) type = generic_params[-(index + 1)].MakeByRefType();
							else type = generic_params[index];
						}

						string param_name;
						ParameterAttributes param_attrs;
						if (i < formal_params.Length)
						{
							param_name = formal_params[i].Name.ToString();
							param_attrs = (formal_params[i].IsOut ? ParameterAttributes.Out : ParameterAttributes.None);
						}
						else
						{
							param_name = "args" + (i + 1);
							param_attrs = ParameterAttributes.None;
						}

						parameters[i] = new StubParameterInfo(i, type, param_attrs, param_name);
						real_parameter_types[i] = type;
					}

					if (method != null)
					{
						method.SetParameters(real_parameter_types);
						method.SetReturnType(return_type);

						method.SetCustomAttribute(AttributeBuilders.DebuggerHidden);
					}
					else
					{
						// constructor is never a generic method
						attributes |= MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
						attributes &= ~MethodAttributes.Virtual;

                        ConstructorBuilder constructor = declaringType.RealTypeBuilder.DefineConstructor(
							attributes, CallingConventions.Standard, real_parameter_types);
						constructor.SetCustomAttribute(AttributeBuilders.DebuggerHidden);

						method_base = constructor;
					}

					yield return new StubInfo(method_base, parameters, generic_params, return_type);
				}
			}
		}
Exemple #19
0
 /// <summary>
 /// Change current class context. Remember the previous ones.
 /// </summary>
 /// <param name="classContextPlace">New class context place.</param>
 /// <param name="classContext">New class context type.</param>
 internal void PushClassContext(IPlace classContextPlace, PhpType classContext)
 {
     this.classContextPlaces.Push(classContextPlace);
     this.classContexts.Push(classContext);
 }
Exemple #20
0
        /// <summary>
        /// Resolves type based on provided <paramref name="typeName"/>.
        /// </summary>
        /// <param name="typeName">Either <see cref="GenericQualifiedName"/> or <see cref="PrimitiveTypeName"/> or <c>null</c> reference.</param>
        /// <param name="referringType"></param>
        /// <param name="referringRoutine"></param>
        /// <param name="position"></param>
        /// <param name="mustResolve"></param>
        /// <returns></returns>
        internal DType ResolveType(object typeName, PhpType referringType, PhpRoutine referringRoutine,
				Position position, bool mustResolve)
		{
			DType result = null;

            if (typeName != null)
            {
                if (typeName.GetType() == typeof(GenericQualifiedName))
                {
                    result = ResolveTypeName((GenericQualifiedName)typeName,
                        referringType, referringRoutine, position, mustResolve);
                }
                else if (typeName.GetType() == typeof(PrimitiveTypeName))
                {
                    result = PrimitiveType.GetByName((PrimitiveTypeName)typeName);
                }
                else
                {
                    throw new ArgumentException("typeName");
                }
            }

            return result;
		}
Exemple #21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ClassCouplingVisitor" /> class.
 /// </summary>
 /// <param name="type"></param>
 public ClassCouplingVisitor(PhpType type)
 {
     currentType = type;
 }
Exemple #22
0
		private GenericParameter ResolveTypeParameterName(Name name, PhpType referringType, PhpRoutine referringRoutine)
		{
			GenericParameter result = null;

			if (referringRoutine != null)
			{
				result = referringRoutine.Signature.GetGenericParameter(name);
				if (result != null)
					return result;
			}

			if (referringType != null)
			{
				result = referringType.GetGenericParameter(name);
				if (result != null)
					return result;
			}

			return result;
		}
Exemple #23
0
		public DType/*!*/ ResolveTypeName(QualifiedName qualifiedName, PhpType referringType,
			PhpRoutine referringRoutine, Position position, bool mustResolve)
		{
			DType result;

			if (qualifiedName.IsSelfClassName)
			{
				if (referringType != null)
				{
					result = referringType;
				}
				else
				{
					// we are sure the self is used incorrectly in function:
					if (referringRoutine != null)
						ErrorSink.Add(Errors.SelfUsedOutOfClass, SourceUnit, position);

					// global code can be included to the method:
					result = UnknownType.UnknownSelf;
				}
			}
            else if (qualifiedName.IsStaticClassName)
            {
                if (referringType != null)
                {
                    if (referringType.IsFinal)
                    {
                        // we are sure the 'static' == 'self'
                        result = referringType;
                    }
                    else
                    {
                        if (referringRoutine != null)
                            referringRoutine.Properties |= RoutineProperties.LateStaticBinding;

                        result = StaticType.Singleton;
                    }
                }
                else
                {
                    // we are sure the static is used incorrectly in function:
                    //if (referringRoutine != null) // do not allow 'static' in global code:
                        ErrorSink.Add(Errors.StaticUsedOutOfClass, SourceUnit, position);

                    // global code can be included to the method:
                    result = UnknownType.UnknownStatic;
                }
            }
            else if (qualifiedName.IsParentClassName)
            {
                if (referringType != null)
                {
                    if (referringType.IsInterface)
                    {
                        ErrorSink.Add(Errors.ParentUsedOutOfClass, SourceUnit, position);
                        result = UnknownType.UnknownParent;
                    }
                    else
                    {
                        DType base_type = referringType.Base;
                        if (base_type == null)
                        {
                            ErrorSink.Add(Errors.ClassHasNoParent, SourceUnit, position, referringType.FullName);
                            result = UnknownType.UnknownParent;
                        }
                        else
                        {
                            result = base_type;
                        }
                    }
                }
                else
                {
                    // we are sure the self is used incorrectly when we are in a function:
                    if (referringRoutine != null)
                        ErrorSink.Add(Errors.ParentUsedOutOfClass, SourceUnit, position);

                    // global code can be included to the method:
                    result = UnknownType.UnknownParent;
                }
            }
            else
            {
                // try resolve the name as a type parameter name:
                if (qualifiedName.IsSimpleName)
                {
                    result = ResolveTypeParameterName(qualifiedName.Name, referringType, referringRoutine);
                    if (result != null)
                        return result;
                }

                Scope referring_scope = GetReferringScope(referringType, referringRoutine);
                QualifiedName? alias;
                result = sourceUnit.ResolveTypeName(qualifiedName, referring_scope, out alias, ErrorSink, position, mustResolve);

                ReportUnknownType(result, alias, position);
            }

			return result;
		}
Exemple #24
0
		public DType ResolveType(object typeNameOrPrimitiveType, PhpType referringType, PhpRoutine referringRoutine,
				Position position, bool mustResolve)
		{
			Debug.Assert(typeNameOrPrimitiveType == null || typeNameOrPrimitiveType is PrimitiveType
			  || typeNameOrPrimitiveType is GenericQualifiedName);

			DType result = typeNameOrPrimitiveType as PrimitiveType;
			if (result != null)
				return result;

			if (typeNameOrPrimitiveType != null)
			{
				return ResolveTypeName((GenericQualifiedName)typeNameOrPrimitiveType, referringType,
							referringRoutine, position, mustResolve);
			}

			return null;
		}
Exemple #25
0
		private Scope GetReferringScope(PhpType referringType, PhpRoutine referringRoutine)
		{
			if (referringType != null) return referringType.Declaration.Scope;
            if (referringRoutine is PhpFunction) return ((PhpFunction)referringRoutine).Declaration.Scope;
            //if (referringRoutine is PhpLambdaFunction) ...

			// used for global statements during full analysis:
			Debug.Assert(currentScope.IsValid, "Scope is available only during full analysis.");
			return currentScope;
		}
Exemple #26
0
        /// <summary>
        /// Emits (ScriptContext, DTypeDesc) constructor.
        /// </summary>
        private static void EmitLongConstructor(PhpType /*!*/ phpType)
        {
            // (ScriptContext, DTypeDesc) constructor
            ConstructorBuilder ctor_builder = phpType.LongConstructorBuilder;

            ctor_builder.DefineParameter(1, ParameterAttributes.None, "context");
            ctor_builder.DefineParameter(2, ParameterAttributes.None, "caller");

            // [ this(arg1,true) ]
            ILEmitter cil = new ILEmitter(ctor_builder);

            cil.Ldarg(FunctionBuilder.ArgThis);
            cil.Ldarg(FunctionBuilder.ArgContextInstance);
            cil.LdcI4(1);
            cil.Emit(OpCodes.Call, phpType.ShortConstructorInfo);

            if (phpType.ProxyFieldInfo != null)
            {
                // [ <proxy>.InvokeConstructor(args) ]
                cil.Ldarg(FunctionBuilder.ArgThis);
                cil.Emit(OpCodes.Ldfld, phpType.ProxyFieldInfo);
                cil.Ldarg(1);
                cil.Ldarg(2);
                cil.Emit(OpCodes.Call, Methods.DObject_InvokeConstructor);
            }
            else
            {
                // try to find constructor method and call it directly
                // if it is publically visible without any reason to throw a warning in runtime

                DRoutineDesc construct        = null; // = found constructor; if not null, can be called statically without runtime checks
                bool         constructorFound = false;

                // try to find constructor
                for (DTypeDesc type_desc = phpType.TypeDesc; type_desc != null; type_desc = type_desc.Base)
                {
                    construct = type_desc.GetMethod(DObject.SpecialMethodNames.Construct);
                    if (construct == null)
                    {
                        construct = type_desc.GetMethod(new Name(type_desc.MakeSimpleName()));
                    }

                    if (construct != null)
                    {
                        constructorFound = true;

                        if (!construct.IsPublic || construct.IsStatic || construct.PhpRoutine == null || construct.PhpRoutine.ArgLessInfo == null)
                        {
                            construct = null; // invalid constructor found, fall back to dynamic behavior
                        }
                        break;
                    }
                }

                // emit constructor call
                if (construct != null)
                {
                    // publically visible not static constructor, can be called statically anywhere

                    // [ __construct( this, context.Stack ) ]
                    cil.Ldarg(FunctionBuilder.ArgThis);                         // this
                    cil.Ldarg(1);
                    cil.Emit(OpCodes.Ldfld, Emit.Fields.ScriptContext_Stack);   // context.Stack
                    cil.Emit(OpCodes.Call, construct.PhpRoutine.ArgLessInfo);   // __construct
                    cil.Emit(OpCodes.Pop);
                }
                else if (!constructorFound)  // there is no ctor at all
                {
                    // [ context.Stack.RemoveFrame() ]
                    cil.Ldarg(1);
                    cil.Emit(OpCodes.Ldfld, Emit.Fields.ScriptContext_Stack);       // context.Stack
                    cil.Emit(OpCodes.Callvirt, Emit.Methods.PhpStack.RemoveFrame);  // .RemoveFrame
                }
                else
                {
                    // constructor should be checked in runtime (various visibility cases)
                    // warnings can be displayed

                    // [ InvokeConstructor(arg2) ]
                    cil.Ldarg(FunctionBuilder.ArgThis);
                    cil.Ldarg(1);
                    cil.Ldarg(2);
                    cil.Emit(OpCodes.Call, Methods.DObject_InvokeConstructor);
                }
            }

            cil.Emit(OpCodes.Ret);
        }
Exemple #27
0
		private void PreAnalyzePartialDeclaration(Analyzer/*!*/ analyzer, TypeDecl/*!*/ aggregate,
			ref DTypeDesc aggregateBase, List<DTypeDesc>/*!*/ aggregateInterfaces)
		{
            //
            // little hack, change the sourceUnit in order to match the current partial class declaration with the right file and imported namespaces
            //
            var current_sourceUnit = analyzer.SourceUnit;
            analyzer.SourceUnit = this.type.Declaration.SourceUnit;
            //
            //
            //

            try
            {
                bool valid = true;

                if (type.IsInterface != aggregate.type.IsInterface)
                {
                    analyzer.ErrorSink.Add(Errors.IncompatiblePartialDeclarations, type.Declaration.SourceUnit, type.Declaration.Position, type.FullName);
                    analyzer.ErrorSink.Add(Errors.RelatedLocation, aggregate.type.Declaration.SourceUnit, aggregate.type.Declaration.Position);
                    valid = false;
                }

                if (type.Visibility != aggregate.type.Visibility)
                {
                    analyzer.ErrorSink.Add(Errors.ConflictingPartialVisibility, type.Declaration.SourceUnit, type.Declaration.Position, type.FullName);
                    analyzer.ErrorSink.Add(Errors.RelatedLocation, aggregate.type.Declaration.SourceUnit, aggregate.type.Declaration.Position);
                    valid = false;
                }

                // merge base types:
                DTypeDesc base_type = ResolveBaseType(analyzer);
                if (base_type != null)
                {
                    if (aggregateBase != null)
                    {
                        if (!base_type.Type.Equals(aggregateBase.Type)) //Edited by Ðonny Jan 07 2009 - missing "!"?
                        {
                            analyzer.ErrorSink.Add(Errors.PartialDeclarationsDifferInBase, type.Declaration.SourceUnit, type.Declaration.Position, type.FullName);
                            analyzer.ErrorSink.Add(Errors.RelatedLocation, aggregate.type.Declaration.SourceUnit, aggregate.type.Declaration.Position);
                            valid = false;
                        }
                    }
                    else
                    {
                        aggregateBase = base_type;
                    }
                }

                typeSignature.PreAnalyze(analyzer, type);

                // merge generic parameters:
                valid &= aggregate.typeSignature.Merge(analyzer.ErrorSink, this.type, typeSignature);

                // move members to the aggregate:
                members.ForEach(member => member.sourceUnit = analyzer.SourceUnit); // override SourceUnit of the members to match the debug information and imported namespaces properly furing the analysis
                aggregate.members.AddRange(members);
                members = null;

                // move attributes to the aggregate:
                aggregate.attributes.Merge(attributes);

                // merge interfaces:
                ResolveBaseInterfaces(analyzer, aggregateInterfaces);

                // next partial declaration;
                // (if the declaration is erroneous, stop analysis before reporting more messy errors):
                if (valid && type.Version.Next != null)
                {
                    ((TypeDecl)type.Version.Next.Declaration.Node).PreAnalyzePartialDeclaration(analyzer, aggregate,
                        ref aggregateBase, aggregateInterfaces);
                }
            }
            finally
            {
                // cut the AST off the tables:
                type.Declaration.Node = null;
                type = null;

                //
                // change the sourceUnit back
                //
                analyzer.SourceUnit = current_sourceUnit;
            }
		}
Exemple #28
0
		/// <summary>
		/// Called when a <see cref="PHP.Core.AST.TypeDecl"/> AST node is entered during the emit phase.
		/// </summary>
		public void EnterTypeDeclaration(PhpType/*!*/ type)
		{
			CompilerLocationStack.TypeDeclContext cd_context = new CompilerLocationStack.TypeDeclContext();
			cd_context.Type = type;

			cd_context.TypeContextPlace = TypeContextPlace;
			TypeContextPlace = new Place(null, type.TypeDescFieldInfo);

            // CallSites
            cd_context.CallSites = callSites;
            this.callSites = new CallSitesBuilder(
                sourceUnit.CompilationUnit.Module.GlobalType.RealModuleBuilder,
                type.QualifiedName.ToString(),
                TypeContextPlace, /*class_context = TypeContextPlace, can be used in .cctor of call sites container*/
                type);

            //
            locationStack.PushTypeDecl(cd_context);
		}
Exemple #29
0
		/// <summary>
		/// Used by full reflection.
		/// </summary>
		public PhpField(VariableName name, DPropertyDesc/*!*/ fieldDesc, FieldInfo/*!*/ fieldInfo,
			PropertyInfo exportedProperty)
			: base(fieldDesc, name)
		{
			Debug.Assert(fieldDesc is DPhpFieldDesc);

			this.realField = fieldInfo;
			this.exportedProperty = exportedProperty;
			this.hasInitialValue = realField.IsDefined(typeof(PhpHasInitValueAttribute), false);
			this.builder = null;

			this.implementor = DeclaringPhpType;
		}
Exemple #30
0
		public DType/*!*/ ResolveTypeName(GenericQualifiedName genericName, PhpType referringType,
			PhpRoutine referringRoutine, Position position, bool mustResolve)
		{
			DType type = ResolveTypeName(genericName.QualifiedName, referringType, referringRoutine, position, mustResolve);

			DTypeDesc[] arguments = (genericName.GenericParams.Length > 0) ? new DTypeDesc[genericName.GenericParams.Length] : DTypeDesc.EmptyArray;

			for (int i = 0; i < arguments.Length; i++)
			{
				arguments[i] = ResolveType(genericName.GenericParams[i], referringType, referringRoutine, position, mustResolve).TypeDesc;
			}

			return type.MakeConstructedType(this, arguments, position);
		}
Exemple #31
0
		internal void ReportAbstractNotImplemented(ErrorSink/*!*/ errors, PhpType/*!*/ referringType)
		{
			member.ReportAbstractNotImplemented(errors, type, referringType);
		}
Exemple #32
0
        /// <summary>
        /// Resolves a method of given <see cref="DType"/> by its name.
        /// </summary>
        /// <param name="type">The type of routine being resolved.</param>
        /// <param name="methodName">The name of routine to be resolved.</param>
        /// <param name="position">Position of method call used for error reporting.</param>
        /// <param name="referringType">The type where the seached routine is being called. Can be <c>null</c>.</param>
        /// <param name="referringRoutine">The routine where the searched routine is being called. Can be <c>null</c>.</param>
        /// <param name="calledStatically">True if the searched routine is called statically - if it uses static method call syntax.
        /// This affects the __call or __callStatic method lookup.
        /// It affects also the error reporting, where for instance method calls, the bad visibility error is
        /// ignored and falls back to return <see cref="UnknownMethod"/>.</param>
        /// <param name="checkVisibilityAtRuntime">Will determine if the routine call must be checked for visibility at runtime.</param>
        /// <param name="isCallMethod">Will determine if __call or __callStatic magic methods were found instead.</param>
        /// <returns>The resolved routine. Cannot return <c>null</c>.</returns>
		public DRoutine/*!*/ ResolveMethod(DType/*!*/ type, Name methodName, Position position,
			PhpType referringType, PhpRoutine referringRoutine, bool calledStatically,
            out bool checkVisibilityAtRuntime, out bool isCallMethod)
		{
			checkVisibilityAtRuntime = false;
            isCallMethod = false;

			// we cannot resolve a method unless we know the inherited members:
			if (type.IsDefinite)
			{
				KnownType known;

				// the method is a constructor:
				if (methodName.IsConstructName || (known = type as KnownType) != null && methodName.Equals(known.QualifiedName.Name))
					return ResolveConstructor(type, position, referringType, referringRoutine, out checkVisibilityAtRuntime);

				DRoutine routine;
				GetMemberResult member_result;

				member_result = type.GetMethod(methodName, referringType, out routine);

                // Look for __call or __callStatic magic methods if no method was found:
                // Note: __call when looking for instance method is disabled, since there can be the searched method in some future override.
                if (member_result == GetMemberResult.NotFound && calledStatically)
                {
                    // in PHP, it is possible to call instance methods statically if we are in instance method context.
                    // In such case we have to look for __call instead of __callStatic:
                    
                    // determine the proper call method:
                    // use __call for instance method invocation, including static method invocation within the current type (e.g. A::foo(), parent::foo(), ...)
                    // use __callStatic for static method invocation
                    Name callMethodName =
                        (!calledStatically ||   // just to have complete condition here, always false
                        (referringRoutine != null && referringType != null && !referringRoutine.IsStatic &&  // in non-static method
                        type.TypeDesc.IsAssignableFrom(referringType.TypeDesc)) // {CurrentType} is inherited from or equal {type}
                        ) ? DObject.SpecialMethodNames.Call : DObject.SpecialMethodNames.CallStatic;

                    member_result = type.GetMethod(callMethodName, referringType, out routine);

                    if (member_result != GetMemberResult.NotFound)
                        isCallMethod = true;
                }

				switch (member_result)
				{
					case GetMemberResult.OK:
						return routine;

					case GetMemberResult.NotFound:
                        if (calledStatically) // throw an error only in we are looking for static method, instance method can be defined in some future inherited class
                            ErrorSink.Add(Errors.UnknownMethodCalled, SourceUnit, position, type.FullName, methodName);
						return new UnknownMethod(type, methodName.Value);

					case GetMemberResult.BadVisibility:
						{
                            if (!calledStatically)    // instance method will check the routine dynamically, there can be some override later
                                return new UnknownMethod(type, methodName.Value);

							if (referringType == null && referringRoutine == null)
							{
								// visibility must be checked at run-time:
								checkVisibilityAtRuntime = true;
								return routine;
							}
							else
							{
								// definitive error:
								if (routine.IsPrivate)
								{
									ErrorSink.Add(Errors.PrivateMethodCalled, SourceUnit, position, type.FullName, methodName.Value,
										referringType.FullName);
								}
								else
								{
									ErrorSink.Add(Errors.ProtectedMethodCalled, SourceUnit, position, type.FullName, methodName.Value,
					  referringType.FullName);
								}

								return new UnknownMethod(type, methodName.Value);
							}
						}

					default:
						Debug.Fail();
						return null;
				}
			}
			else
			{
				// warning (if any) reported by the type resolver:
				return new UnknownMethod(type, methodName.Value);
			}
		}
Exemple #33
0
		/// <summary>
		/// Resolves constructor of the specified type within the current context (location).
		/// </summary>
		public DRoutine/*!*/ ResolveConstructor(DType/*!*/ type, Position position, PhpType referringType,
			PhpRoutine referringRoutine, out bool checkVisibilityAtRuntime)
		{
			checkVisibilityAtRuntime = false;
			KnownRoutine ctor;

			// Do resolve ctor despite of the indefiniteness of the type to make error reporting consistent
			// when accessing the constructors thru the new operator.

			switch (type.GetConstructor(referringType, out ctor))
			{
				case GetMemberResult.OK:
					return ctor;

				case GetMemberResult.NotFound:
					// default ctor to be used:
					return new UnknownMethod(type);

				case GetMemberResult.BadVisibility:
					if (referringType == null && referringRoutine == null)
					{
						// visibility must be checked at run-time:
						checkVisibilityAtRuntime = true;
						return ctor;
					}
					else
					{
						// definitive error:
						if (ctor.IsPrivate)
						{
							ErrorSink.Add(Errors.PrivateCtorCalled, SourceUnit, position, type.FullName,
								ctor.FullName, referringType.FullName);
						}
						else
						{
							ErrorSink.Add(Errors.ProtectedCtorCalled, SourceUnit, position, type.FullName,
								ctor.FullName, referringType.FullName);
						}

						return new UnknownMethod(type);
					}

				default:
					Debug.Fail();
					return null;
			}
		}
Exemple #34
0
		/// <summary>
		/// Resolves static properties.
		/// </summary>
		public DProperty/*!*/ ResolveProperty(DType/*!*/ type, VariableName propertyName, Position position, bool staticOnly,
			PhpType referringType, PhpRoutine referringRoutine, out bool checkVisibilityAtRuntime)
		{
			Debug.Assert(type != null);

			checkVisibilityAtRuntime = false;

			// we cannot resolve a property unless we know the inherited members:
			if (type.IsDefinite)
			{
				DProperty property;
				GetMemberResult member_result = type.GetProperty(propertyName, referringType, out property);

				switch (member_result)
				{
					case GetMemberResult.OK:
						if (staticOnly && !property.IsStatic) goto case GetMemberResult.NotFound;
						return property;

					case GetMemberResult.NotFound:
						ErrorSink.Add(Errors.UnknownPropertyAccessed, SourceUnit, position, type.FullName, propertyName);
						return new UnknownProperty(type, propertyName.Value);

					case GetMemberResult.BadVisibility:
						if (referringType == null && referringRoutine == null)
						{
							// visibility must be checked at run-time:
							checkVisibilityAtRuntime = true;
							return property;
						}
						else
						{
							// definitive error:
							if (property.IsPrivate)
							{
								ErrorSink.Add(Errors.PrivatePropertyAccessed, SourceUnit, position, type.FullName, propertyName.Value,
									referringType.FullName);
							}
							else
							{
								ErrorSink.Add(Errors.ProtectedPropertyAccessed, SourceUnit, position, type.FullName, propertyName.Value,
									referringType.FullName);
							}

							return new UnknownProperty(type, propertyName.Value);
						}

					default:
						Debug.Fail();
						throw null;
				}
			}
			else
			{
				// warning (if any) reported by the type resolver:
				return new UnknownProperty(type, propertyName.Value);
			}
		}
Exemple #35
0
        /// <summary>
        /// Create new call sites builder.
        /// </summary>
        /// <param name="moduleBuilder">Module to contain call sites container.</param>
        /// <param name="userFriendlyName">User friendly name used to identify the call sites container by user.</param>
        /// <param name="classContextPlace">If known and if it can be emitted in static .cctor, defines the place where the class context can be loaded. Otherwise <c>null</c> if the class context will be determined in run time.</param>
        /// <param name="classContext">Current PHP type context.</param>
        public CallSitesBuilder(ModuleBuilder /*!*/ moduleBuilder, string /*!*/ userFriendlyName, IPlace classContextPlace, PhpType classContext)
        {
            Debug.Assert(moduleBuilder != null && userFriendlyName != null);

            this.userFriendlyName = userFriendlyName;
            this.moduleBuilder    = moduleBuilder;
            this.PushClassContext(classContextPlace, classContext);
            this.delegateBuilder = new DelegateBuilder(moduleBuilder);
        }
Exemple #36
0
		internal DConstant ResolveClassConstantName(DType/*!*/ type, VariableName constantName,
			Position position, PhpType referringType, PhpRoutine referringRoutine, out bool checkVisibilityAtRuntime)
		{
			checkVisibilityAtRuntime = false;

			// we cannot resolve a class constant unless we know the inherited members:
			if (type.IsDefinite)
			{
				ClassConstant constant;
				GetMemberResult member_result = type.GetConstant(constantName, referringType, out constant);

				switch (member_result)
				{
					case GetMemberResult.OK:
						return constant;

					case GetMemberResult.NotFound:
						ErrorSink.Add(Errors.UnknownClassConstantAccessed, SourceUnit, position, type.FullName, constantName);
						return new UnknownClassConstant(type, constantName.Value);

					case GetMemberResult.BadVisibility:
						if (referringType == null && referringRoutine == null)
						{
							// visibility must be checked at run-time:
							checkVisibilityAtRuntime = true;
							return constant;
						}
						else
						{
							// definitive error:
							if (constant.IsPrivate)
							{
								ErrorSink.Add(Errors.PrivateConstantAccessed, SourceUnit, position, type.FullName, constantName.Value,
				  referringType.FullName);
							}
							else
							{
								ErrorSink.Add(Errors.ProtectedConstantAccessed, SourceUnit, position, type.FullName, constantName.Value,
				  referringType.FullName);
							}

							return new UnknownClassConstant(type, constantName.Value);
						}

					default:
						Debug.Fail();
						throw null;
				}
			}
			else
			{
				// warning (if any) reported by the type resolver:
				return new UnknownClassConstant(type, constantName.Value);
			}
		}
Exemple #37
0
        private void Bake()
        {
            if (types != null)
            {
                bakedTypes = new KeyValuePair <string, PhpTypeDesc> [types.Count];

                int i = 0;
                foreach (Declaration declaration in types.Values)
                {
                    PhpType type = (PhpType)declaration.Declaree;

                    // store full name before calling Bake() as it nulls the PhpType:
                    string      full_name = type.FullName;
                    PhpTypeDesc baked     = type.Bake();

                    // baked is null if the type is indefinite
                    // (its base class may be evaluated when the module's main method is executed):
                    if (baked != null && !declaration.IsConditional)
                    {
                        bakedTypes[i++] = new KeyValuePair <string, PhpTypeDesc>(full_name, baked);
                    }
                }

                // trim:
                Array.Resize(ref bakedTypes, i);

                types = null;
            }

            if (functions != null)
            {
                bakedFunctions = new KeyValuePair <string, PhpRoutineDesc> [functions.Count];

                int i = 0;
                foreach (Declaration declaration in functions.Values)
                {
                    PhpFunction function = (PhpFunction)declaration.Declaree;

                    string         full_name = function.FullName;
                    PhpRoutineDesc baked     = function.Bake();

                    if (!declaration.IsConditional)
                    {
                        bakedFunctions[i++] = new KeyValuePair <string, PhpRoutineDesc>(full_name, baked);
                    }
                }

                // trim:
                Array.Resize(ref bakedFunctions, i);

                functions = null;
            }

            if (constants != null)
            {
                bakedConstants = new KeyValuePair <string, DConstantDesc> [constants.Count];

                int i = 0;
                foreach (Declaration declaration in constants.Values)
                {
                    GlobalConstant constant = (GlobalConstant)declaration.Declaree;

                    string        full_name = constant.FullName;
                    DConstantDesc baked     = constant.Bake();

                    if (!declaration.IsConditional)
                    {
                        bakedConstants[i++] = new KeyValuePair <string, DConstantDesc>(full_name, baked);
                    }
                }

                // trim:
                Array.Resize(ref bakedConstants, i);

                constants = null;
            }
        }
Exemple #38
0
 internal virtual void ReportMethodNotCompatible(ErrorSink /*!*/ errors, DType /*!*/ declaringType, PhpType /*!*/ referringType)
 {
     // to be implemented by methods and properties
     Debug.Fail();
     throw null;
 }
Exemple #39
0
		/// <summary>
		/// Emits ghost stubs for methods and properties that are declared by a <paramref name="type"/>'s
		/// base type but need to be adapted to a particular CLR signature because of implementing an
		/// interface by the <paramref name="type"/>.
		/// </summary>
		/// <param name="type">The <see cref="PhpType"/> that possibly released ghosts by implementing an interface.
		/// </param>
		public void EmitGhostStubs(PhpType/*!*/ type)
		{
			List<KeyValuePair<DMemberRef, DMemberRef>> ghosts = type.Builder.GhostImplementations;
			if (ghosts != null)
			{
				Dictionary<string, MethodBuilder> m_stubs = new Dictionary<string, MethodBuilder>();
				Dictionary<Type, PropertyBuilder> f_stubs = new Dictionary<Type, PropertyBuilder>();

				for (int i = 0; i < ghosts.Count; i++)
				{
					PhpMethod impl_method;
					PhpField impl_field;

					if ((impl_method = ghosts[i].Value.Member as PhpMethod) != null)
					{
						// emit ghost method stub
						EmitOverrideStubs(m_stubs, impl_method, ghosts[i].Value.Type, type, ghosts[i].Key, true);
					}
					else if ((impl_field = ghosts[i].Value.Member as PhpField) != null)
					{
						// emit ghost property stub
						EmitOverrideStubs(f_stubs, impl_field, type, ghosts[i].Key, true);
					}
				}
			}
		}
Exemple #40
0
        /// <summary>
        /// Emits (ScriptContext, bool) constructor.
        /// </summary>
        private static void EmitShortConstructor(PhpType /*!*/ phpType)
        {
            // (ScriptContext,bool) constructor
            ConstructorBuilder ctor_builder = phpType.ShortConstructorBuilder;

            ctor_builder.DefineParameter(1, ParameterAttributes.None, "context");
            ctor_builder.DefineParameter(2, ParameterAttributes.None, "newInstance");
            ILEmitter cil = new ILEmitter(ctor_builder);

            // invoke base constructor
            if (phpType.Base == null)
            {
                EmitInvokePhpObjectConstructor(cil);
            }
            else
            {
                phpType.Base.EmitInvokeConstructor(cil, phpType, null);
            }

            // perform fast DObject.<typeDesc> init if we are in its subclass
            if (phpType.Root is PhpType)
            {
                // [ if (GetType() == typeof(self)) this.typeDesc = self.<typeDesc> ]
                cil.Ldarg(FunctionBuilder.ArgThis);
                cil.Emit(OpCodes.Call, Methods.Object_GetType);
                cil.Emit(OpCodes.Ldtoken, phpType.RealTypeBuilder);
                cil.Emit(OpCodes.Call, Methods.GetTypeFromHandle);

                Label label = cil.DefineLabel();
                cil.Emit(OpCodes.Bne_Un_S, label);
                if (true)
                {
                    cil.Ldarg(FunctionBuilder.ArgThis);
                    cil.Emit(OpCodes.Ldsfld, phpType.TypeDescFieldInfo);
                    cil.Emit(OpCodes.Stfld, Fields.DObject_TypeDesc);
                    cil.MarkLabel(label);
                }
            }

            // register this instance for finalization if it introduced the __destruct method
            DRoutine destruct;

            if (phpType.TypeDesc.GetMethod(DObject.SpecialMethodNames.Destruct) != null && (phpType.Base == null ||
                                                                                            phpType.Base.GetMethod(DObject.SpecialMethodNames.Destruct, phpType, out destruct) == GetMemberResult.NotFound))
            {
                cil.Ldarg(FunctionBuilder.ArgContextInstance);
                cil.Ldarg(FunctionBuilder.ArgThis);

                if (phpType.ProxyFieldInfo != null)
                {
                    cil.Emit(OpCodes.Ldfld, phpType.ProxyFieldInfo);
                }

                cil.Emit(OpCodes.Call, Methods.ScriptContext.RegisterDObjectForFinalization);
            }

            // [ <InitializeInstanceFields>(arg1) ]
            cil.Ldarg(FunctionBuilder.ArgThis);
            cil.Ldarg(FunctionBuilder.ArgContextInstance);
            cil.EmitCall(OpCodes.Call, phpType.Builder.InstanceFieldInit, null);

            // [ __InitializeStaticFields(arg1) ]
            cil.Ldarg(FunctionBuilder.ArgContextInstance);
            cil.EmitCall(OpCodes.Call, phpType.StaticFieldInitMethodInfo, null);

            cil.Emit(OpCodes.Ret);
        }
Exemple #41
0
		/// <summary>
		/// Defines a property accessor method and installs an explicit override if necessary.
		/// </summary>
		private MethodBuilder/*!*/ DefineOverrideAccessor(PhpType/*!*/ declaringType, PhpField/*!*/ target,
			MethodInfo/*!*/ template, bool newSlot, Type/*!*/ returnType, Type[]/*!!*/ paramTypes)
		{
			bool changed;
			string name = ClrStubBuilder.GetNonConflictingMethodName(declaringType.TypeDesc, template.Name, out changed);

			MethodAttributes attr;

			if (changed) attr = MethodAttributes.PrivateScope;
			else attr = Reflection.Enums.ToMethodAttributes(target.MemberDesc.MemberAttributes);

			attr |= (MethodAttributes.Virtual | MethodAttributes.HideBySig);
			if (newSlot) attr |= MethodAttributes.NewSlot;

			MethodBuilder method_builder = declaringType.RealTypeBuilder.DefineMethod(
				name,
				attr,
				returnType,
				paramTypes);

			if (changed)
			{
				declaringType.RealTypeBuilder.DefineMethodOverride(
					method_builder,
					template);
			}

			return method_builder;
		}
Exemple #42
0
		/// <summary>
		/// Used by the compiler.
		/// </summary>
		internal PhpMethod(PhpType/*!*/ declaringType, Name name, PhpMemberAttributes memberAttributes, bool hasBody,
	  Signature astSignature, TypeSignature astTypeSignature, SourceUnit/*!*/ sourceUnit, Position position)
			: base(new PhpRoutineDesc(declaringType.TypeDesc, memberAttributes), astSignature, astTypeSignature)
		{
			Debug.Assert(declaringType != null && sourceUnit != null && position.IsValid);

			this.name = name;
			this.position = position;
			this.hasBody = hasBody;
			this.sourceUnit = sourceUnit;
		}
Exemple #43
0
		/// <summary>
		/// Emits stubs for one overridden or implemented PHP method.
		/// </summary>
		/// <param name="stubs">Already generated stubs.</param>
		/// <param name="target">The overriding/implementing method.</param>
		/// <param name="targetType">The type (perhaps constructed) that declared <paramref name="target"/>.</param>
		/// <param name="declaringType">The type where the stubs should be emitted.</param>
		/// <param name="template">The method being overridden/implemented (surely PHP).</param>
		/// <param name="newSlot"><B>True</B> if the stub should be assigned a new vtable slot,
		/// <B>false</B> otherwise.</param>
		/// <remarks>
		/// This method handles situations where method overriding/implementing does not work by itself because of
		/// the fact that method names in PHP are case insensitive.
		/// </remarks>
		private void EmitOverrideStubsForPhpTemplate(IDictionary<string, MethodBuilder>/*!*/ stubs,
			PhpMethod/*!*/ target, DType/*!*/ targetType, PhpType/*!*/ declaringType, DMemberRef/*!*/ template,
			bool newSlot)
		{
            PhpMethod php_template = (PhpMethod)template.Member;

            // Emit method stub if needed here ... (resolve .NET incompatibility of base method and overriding method)
            // 
            // Until now, several possible cases or their combination are known:
            // - base and overriding methods match, but their name letter-casing don't (need to define override explicitly to properly Bake the type)
            // - base and overriding methods name match exactly, but overriding methods has additional arguments (with default values) (in PHP it is allowed) (stub needed)
            // - ghost stub, where B extends A implements I, where A contains definition of method in I and casing does not match
            //
            // if signatures don't match, virtual sealed stub must be created, it only calls the target method
            // if signatures match, only explicit override must be stated

            if (target.Name.ToString() != php_template.Name.ToString() ||           // the names differ (perhaps only in casing)
                target.Signature.ParamCount != php_template.Signature.ParamCount || // signature was extended (additional arguments added, with implicit value only)
                target.Signature.AliasReturn != php_template.Signature.AliasReturn  // returns PhpReference instead of Object
                )
			{
				MethodInfo target_argfull = DType.MakeConstructed(target.ArgFullInfo, targetType as ConstructedType);
				TypeBuilder type_builder = declaringType.RealTypeBuilder;

				// we have to generate a pass-thru override stub that overrides the template based on
				// name since it is impossible to install an explicit override of a method declared by
				// a generic type in v2.0 SRE (feedback ID=97425)
				bool sre_bug_workaround = (template.Type is ConstructedType);

                if (target.DeclaringType == declaringType && !sre_bug_workaround &&
                    target.Signature.ParamCount == php_template.Signature.ParamCount &&
                    target.Signature.AliasReturn == php_template.Signature.AliasReturn)
				{
                    // signatures match, just install an explicit override if possible
					type_builder.DefineMethodOverride(target_argfull,
						DType.MakeConstructed(php_template.ArgFullInfo, template.Type as ConstructedType));
				}
				else
				{
					string stubs_key = null;
					MethodAttributes attrs;

                    if (sre_bug_workaround)
                    {
                        // check whether we have generated a stub having the template name before
                        if (stubs.ContainsKey(stubs_key = "," + php_template.ArgFullInfo.Name)) return;

                        attrs = php_template.ArgFullInfo.Attributes & ~MethodAttributes.Abstract;
                    }
                    else
                    {
                        attrs = MethodAttributes.PrivateScope | MethodAttributes.Virtual;
                    }

                    if (newSlot) attrs |= MethodAttributes.NewSlot; 
					else attrs &= ~MethodAttributes.NewSlot;

					// determine stub return and parameters type
					Type return_type;
					Type[] param_types = php_template.Signature.ToArgfullSignature(1, out return_type);
                    param_types[0] = Types.ScriptContext[0];

					MethodBuilder override_stub = type_builder.DefineMethod(
                        (sre_bug_workaround ? php_template.ArgFullInfo.Name : "<Override>"),
						attrs, return_type, param_types);

					ILEmitter il = new ILEmitter(override_stub);

                    //
                    // return target( [arg1, ...[, default, ...]] );
                    //

					// pass-thru all arguments, including this (arg0)
                    int pass_args = Math.Min(param_types.Length, target.Signature.ParamCount + 1);
					for (int i = 0; i <= pass_args; ++i) il.Ldarg(i);  // this, param1, ....
                    for (int i = pass_args; i <= target.Signature.ParamCount; ++i)
                    {
                        // ... // PhpException.MissingArgument(i, target.FullName); // but in some override it can be optional argument 
                        il.Emit(OpCodes.Ldsfld, PHP.Core.Emit.Fields.Arg_Default);  // paramN
                    }
                    il.Emit(OpCodes.Callvirt, target_argfull);

                    // return
                    if (target.Signature.AliasReturn != php_template.Signature.AliasReturn)
                        il.Emit(OpCodes.Call, target.Signature.AliasReturn
                            ? Methods.PhpVariable.Dereference       // PhpVariable.Deference(obj)                   
                            : Methods.PhpVariable.MakeReference);   // PhpVariable.MakeReference(obj)
                    il.Emit(OpCodes.Ret);

					if (sre_bug_workaround)
					{
						stubs.Add(stubs_key, override_stub);
					}
					else
					{
                        if (!php_template.ArgFullInfo.IsVirtual)
                            throw new InvalidOperationException(string.Format("Cannot override non-virtual method '{0}'!", php_template.ArgFullInfo.Name));

						type_builder.DefineMethodOverride(override_stub,
							DType.MakeConstructed(php_template.ArgFullInfo, template.Type as ConstructedType));
					}
				}
			}
		}
Exemple #44
0
        internal override void ReportMethodNotCompatible(ErrorSink errors, DType declaringType, PhpType referringType)
        {
            errors.Add(Errors.MethodNotCompatible, referringType.Declaration.SourceUnit,
                referringType.Declaration.Position,
                referringType.FullName, this.FullName, declaringType.MakeFullGenericName(), this.FullName);

            //ReportError(errors, Errors.RelatedLocation);
        }
Exemple #45
0
		internal override void ReportAbstractNotImplemented(ErrorSink/*!*/ errors, DType/*!*/ declaringType, PhpType/*!*/ referringType)
		{
			errors.Add(Errors.AbstractPropertyNotImplemented, referringType.Declaration.SourceUnit,
				referringType.Declaration.Position, referringType.FullName, declaringType.MakeFullGenericName(), this.FullName);

			ReportError(errors, Errors.RelatedLocation);
		}
Exemple #46
0
        /// <summary>
        /// Enumerates all export overloads for the given target PHP method.
        /// </summary>
        public static IEnumerable <StubInfo> DefineMethodExportStubs(
            PhpRoutine /*!*/ target, PhpType /*!*/ declaringType,
            MethodAttributes attributes,
            bool defineConstructors,
            StubSignatureFilter /*!*/ signatureFilter)
        {
            Debug.Assert(target.Builder != null);

            Type return_type = Types.Object[0];

            PhpRoutineSignature signature = target.Signature;

            AST.FormalParam[]     formal_params      = target.Builder.Signature.FormalParams;
            AST.FormalTypeParam[] formal_type_params = target.Builder.TypeSignature.TypeParams;

            int gen_sig_count = signature.GenericParamCount - signature.MandatoryGenericParamCount + 1;
            int arg_sig_count = signature.ParamCount - signature.MandatoryParamCount + 1;

            // TODO: return type hints
            // HACK: change return type to void for methods that are apparently event handlers
            if (signature.GenericParamCount == 0 && arg_sig_count == 1 && signature.ParamCount == 2 &&
                (signature.TypeHints[0] == null || signature.TypeHints[0].RealType == Types.Object[0]) &&
                (signature.TypeHints[1] != null && typeof(EventArgs).IsAssignableFrom(signature.TypeHints[1].RealType)))
            {
                return_type = Types.Void;
            }

            for (int gen_sig = 0; gen_sig < gen_sig_count; gen_sig++)
            {
                for (int arg_sig = 0; arg_sig < arg_sig_count; arg_sig++)
                {
                    // determine parameter types (except for method mandatory generic parameters)
                    object[] parameter_types = GetStubParameterTypes(
                        arg_sig + signature.MandatoryParamCount,
                        gen_sig + signature.MandatoryGenericParamCount,
                        signature,
                        formal_type_params);

                    // determine generic parameter names
                    string[] generic_param_names = new string[target.Signature.MandatoryGenericParamCount + gen_sig];
                    for (int i = 0; i < generic_param_names.Length; i++)
                    {
                        generic_param_names[i] = formal_type_params[i].Name.ToString();
                    }

                    // are we allowed to generate this signature?
                    if (!signatureFilter(generic_param_names, parameter_types, return_type))
                    {
                        continue;
                    }

                    GenericTypeParameterBuilder[] generic_params = StubInfo.EmptyGenericParameters;
                    MethodBase    method_base = null;
                    MethodBuilder method      = null;

                    if (!defineConstructors)
                    {
                        method = declaringType.RealTypeBuilder.DefineMethod(target.FullName, attributes);

                        // determine generic parameters
                        if (generic_param_names.Length > 0)
                        {
                            generic_params = method.DefineGenericParameters(generic_param_names);
                        }

                        method_base = method;
                    }

                    ParameterInfo[] parameters = new ParameterInfo[parameter_types.Length];

                    // fill in parameter infos
                    Type[] real_parameter_types = new Type[parameters.Length];
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        Type type = parameter_types[i] as Type;

                        // generic method parameter fixup
                        if (type == null)
                        {
                            int index = (int)parameter_types[i];
                            if (index < 0)
                            {
                                type = generic_params[-(index + 1)].MakeByRefType();
                            }
                            else
                            {
                                type = generic_params[index];
                            }
                        }

                        string param_name;
                        ParameterAttributes param_attrs;
                        if (i < formal_params.Length)
                        {
                            param_name  = formal_params[i].Name.ToString();
                            param_attrs = (formal_params[i].IsOut ? ParameterAttributes.Out : ParameterAttributes.None);
                        }
                        else
                        {
                            param_name  = "args" + (i + 1);
                            param_attrs = ParameterAttributes.None;
                        }

                        parameters[i]           = new StubParameterInfo(i, type, param_attrs, param_name);
                        real_parameter_types[i] = type;
                    }

                    if (method != null)
                    {
                        method.SetParameters(real_parameter_types);
                        method.SetReturnType(return_type);

                        method.SetCustomAttribute(AttributeBuilders.DebuggerHidden);
                    }
                    else
                    {
                        // constructor is never a generic method
                        attributes |= MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
                        attributes &= ~MethodAttributes.Virtual;

                        ConstructorBuilder constructor = declaringType.RealTypeBuilder.DefineConstructor(
                            attributes, CallingConventions.Standard, real_parameter_types);
                        constructor.SetCustomAttribute(AttributeBuilders.DebuggerHidden);

                        method_base = constructor;
                    }

                    yield return(new StubInfo(method_base, parameters, generic_params, return_type));
                }
            }
        }
Exemple #47
0
		/// <summary>
		/// Used by full reflection for fields that are not implemented by their declaring type.
		/// <seealso cref="PhpPublicFieldAttribute"/>
		/// </summary>
		public PhpField(VariableName name, DPropertyDesc/*!*/ fieldDesc, DPropertyDesc/*!*/ implementingFieldDesc,
			bool hasInitialValue, PropertyInfo exportedProperty)
			: base(fieldDesc, name)
		{
			Debug.Assert(fieldDesc is DPhpFieldDesc);

			this.realField = implementingFieldDesc.PhpField.RealField;
			this.exportedProperty = exportedProperty;
			this.hasInitialValue = hasInitialValue;
			this.builder = null;

			this.implementor = implementingFieldDesc.DeclaringType.PhpType;
			this.upgradesVisibility = (IsPublic && implementingFieldDesc.IsProtected);
		}
Exemple #48
0
 /// <summary>
 /// Change current class context. Remember the previous ones.
 /// </summary>
 /// <param name="classContextPlace">New class context place.</param>
 /// <param name="classContext">New class context type.</param>
 internal void PushClassContext(IPlace classContextPlace, PhpType classContext)
 {
     this.classContextPlaces.Push(classContextPlace);
     this.classContexts.Push(classContext);
 }
Exemple #49
0
 internal virtual void ReportMethodNotCompatible(ErrorSink/*!*/ errors, DType/*!*/ declaringType, PhpType/*!*/ referringType)
 {
     // to be implemented by methods and properties
     Debug.Fail();
     throw null;
 }
Exemple #50
0
        /// <summary>
        /// Create new call sites builder.
        /// </summary>
        /// <param name="moduleBuilder">Module to contain call sites container.</param>
        /// <param name="userFriendlyName">User friendly name used to identify the call sites container by user.</param>
        /// <param name="classContextPlace">If known and if it can be emitted in static .cctor, defines the place where the class context can be loaded. Otherwise <c>null</c> if the class context will be determined in run time.</param>
        /// <param name="classContext">Current PHP type context.</param>
        public CallSitesBuilder(ModuleBuilder/*!*/moduleBuilder, string/*!*/userFriendlyName, IPlace classContextPlace, PhpType classContext)
        {
            Debug.Assert(moduleBuilder != null && userFriendlyName != null);

            this.userFriendlyName = userFriendlyName;
            this.moduleBuilder = moduleBuilder;
            this.PushClassContext(classContextPlace, classContext);
            this.delegateBuilder = new DelegateBuilder(moduleBuilder);
        }
Exemple #51
0
			internal TypeDeclLocation(PhpType/*!*/ type, int nestingLevel)
				: base(nestingLevel)
			{
				this.type = type;
			}
Exemple #52
0
 internal virtual void ReportAbstractNotImplemented(ErrorSink /*!*/ errors, DType /*!*/ declaringType, PhpType /*!*/ referringType)
 {
     // to be implemented by methods and properties
     Debug.Fail(null);
     throw null;
 }
Exemple #53
0
 internal void ReportAbstractNotImplemented(ErrorSink /*!*/ errors, PhpType /*!*/ referringType)
 {
     member.ReportAbstractNotImplemented(errors, type, referringType);
 }
Exemple #54
0
        /// <summary>
		/// Notices the analyzer that class declaration is entered.
		/// </summary>
		internal void EnterTypeDecl(PhpType type)
		{
			TypeDeclLocation c = new TypeDeclLocation(type, locationStack.Count);
			typeDeclStack.Push(c);
			locationStack.Push(c);
		}