static PhpReference GetRefMemberNotFound(DObject self, string name, DTypeDesc caller) { PhpReference reference; bool getter_exists; // search in RT fields if (self.RuntimeFields != null && self.RuntimeFields.ContainsKey(name)) { var namekey = new IntStringKey(name); return(self.RuntimeFields.table._ensure_item_ref(ref namekey, self.RuntimeFields)); } // property is not present -> try to invoke __get reference = self.InvokeGetterRef(name, caller, out getter_exists); if (getter_exists) { return((reference == null) ? new PhpReference() : reference); } // (no notice/warning/error thrown by PHP) // add the field reference = new PhpReference(); if (self.RuntimeFields == null) { self.RuntimeFields = new PhpArray(); } self.RuntimeFields[name] = reference; return(reference); }
/// <summary> /// Checks whether a target of callback argument can be invoked. /// </summary> /// <param name="callback">The callback to check.</param> /// <param name="caller">The class context used to bind the callback function.</param> /// <param name="argIndex">The index of argument starting from 1 or 0 if not applicable.</param> /// <param name="argName">A name of the argument or <B>null</B> reference if not applicable.</param> /// <param name="emptyAllowed">Whether an empty callback is allowed.</param> /// <returns>Whether the callback can be bound to its target or it is empty and that is allowed.</returns> /// <remarks>The callback is bound if it can be.</remarks> public static bool CheckCallback(PhpCallback callback, DTypeDesc caller, string argName, int argIndex, bool emptyAllowed) { // error has already been reported by Convert.ObjectToCallback: if (callback == PhpCallback.Invalid) { return(false); } // callback is empty: if (callback == null) { return(emptyAllowed); } // callback is bindable: if (callback.Bind(true, caller, null)) { return(true); } if (argName != null) { argName = String.Concat('\'', argName, '\''); } else { argName = "#" + argIndex; } PhpException.Throw(PhpError.Warning, CoreResources.GetString("noncallable_callback", ((IPhpConvertible)callback).ToString(), argName)); return(false); }
public static void DefaultAutoload(NamingContext namingContext, DTypeDesc caller, string className) { // TODO: skip in pure mode var context = ScriptContext.CurrentContext; var fileExtensions = context.SplAutoloadExtensions.GetEnumerator(); bool stateChanged = true; while (!stateChanged || ScriptContext.CurrentContext.ResolveType(className, namingContext, caller, null, ResolveTypeFlags.None) == null) { if (!fileExtensions.MoveNext()) { PhpException.Throw(PhpError.Error, string.Format(CoreResources.class_could_not_be_loaded, className)); return; } // try to dynamically include the file specified by the class name, if it exists string FullFileName = className + fileExtensions.Current; if (PhpFile.Exists(FullFileName)) { context.DynamicInclude(FullFileName, context.WorkingDirectory, null, null, null, InclusionTypes.IncludeOnce); stateChanged = true; } else { stateChanged = false; } } }
/// <summary> /// Called before 'Compile' to initialize module & assembly builders, so they can be used by the caller. /// </summary> internal bool PreCompile(CompilationContext /*!*/ context, ScriptContext /*!*/ scriptContext, SourceCodeDescriptor descriptor, EvalKinds kind, DTypeDesc referringType) { Debug.Assert(descriptor.Line == this.sourceUnit.Line); Debug.Assert(descriptor.Column == this.sourceUnit.Column); this.resolvingScriptContext = scriptContext; this.referringType = referringType; // TODO: isDynamic is tricky... // .. we need to define module_builder before any type/etc.. is reduced from the parser // .. but we don't know whether it will be dynamic in advance! this.assembly_builder = scriptContext.ApplicationContext.TransientAssemblyBuilder; this.module_builder = assembly_builder.DefineModule(this, context.Config.Compiler.Debug, descriptor.ContainingTransientModuleId, kind, descriptor.ContainingSourcePath); this.module = module_builder; this.evalKind = kind; sourceUnit.Parse( context.Errors, this, context.Config.Compiler.LanguageFeatures); if (context.Errors.AnyFatalError) { return(false); } // any declaration implies non-dynamicity: // TODO: this mode needs to be checked... // isDynamic = types == null && functions == null && constants == null; return(true); }
/// <summary> /// Initialize the ClassCOntextHolder with a known DTypeDesc. /// Use UnknownTypeDesc.Singleton to specify an unknown caller. In this case the caller will be determined when needed. /// </summary> /// <param name="caller"></param> public ClassContextHolder(DTypeDesc caller) { if (caller == null || !caller.IsUnknown) { ClassContext = caller; } }
private static bool IsSameCompilationUnit(PhpTypeDesc /*!*/ selfType, DTypeDesc dependentType) { Debug.Assert(selfType != null && dependentType != null); if (object.ReferenceEquals(dependentType.RealType.Module, selfType.RealType.Module)) { int selfTransientId, dependentTransientId; string selfFileName, dependentFileName; string selfTypeName, dependentTypeName; ReflectionUtils.ParseTypeId(selfType.RealType, out selfTransientId, out selfFileName, out selfTypeName); if (selfTransientId != PHP.Core.Reflection.TransientAssembly.InvalidEvalId) // always true, => TransientCompilationUnit { ReflectionUtils.ParseTypeId(dependentType.RealType, out dependentTransientId, out dependentFileName, out dependentTypeName); // transient modules, must have same ids return(selfTransientId == dependentTransientId); } else { // same module, not transient modules return(true); } } else { // different modules => different units for sure return(false); } }
public static bool Register(NamingContext namingContext, DTypeDesc caller, PhpCallback autoloadFunction, bool throwError, bool prepend) { if (autoloadFunction == null) { PhpException.ArgumentNull("autoloadFunction"); return(false); } if (autoloadFunction.Bind(!throwError, caller, namingContext)) { var context = ScriptContext.CurrentContext; if (FindAutoloadFunction(context, autoloadFunction.ToPhpRepresentation()) != null) { return(false); } if (prepend) { context.SplAutoloadFunctions.AddFirst(autoloadFunction); } else { context.SplAutoloadFunctions.AddLast(autoloadFunction); } return(true); } else { return(false); } }
public static bool PropertyExists(DTypeDesc caller, object classNameOrObject, string propertyName) { ScriptContext context = ScriptContext.CurrentContext; DTypeDesc type = ClassNameOrObjectToType(context, null, caller, classNameOrObject, true); if (type == null) { return(false); } // determine the calling class context //DTypeDesc caller = PhpStackTrace.GetClassContext(); if (caller != null && caller.IsUnknown) { caller = PhpStackTrace.GetClassContext(); } DPropertyDesc property; if (type.GetProperty(new VariableName(propertyName), caller, out property) == GetMemberResult.OK) { // CT property was found return(true); } else { // search RT fields, if possible DObject obj = classNameOrObject as DObject; return(obj != null && obj.RuntimeFields != null && obj.RuntimeFields.ContainsKey(propertyName)); } }
public static PhpArray GetClassMethods(DTypeDesc caller, object classNameOrObject) { ScriptContext context = ScriptContext.CurrentContext; DTypeDesc type = ClassNameOrObjectToType(context, null, caller, classNameOrObject, true); if (type == null) { return(null); } // determine the calling type //DTypeDesc caller = PhpStackTrace.GetClassContext(); if (caller != null && caller.IsUnknown) { caller = PhpStackTrace.GetClassContext(); } PhpArray result = new PhpArray(); foreach (KeyValuePair <Name, DRoutineDesc> pair in type.EnumerateMethods(caller)) { result.Add(pair.Key.ToString()); } return(result); }
/// <summary> /// Creates a new instance of a type by invoking its constructor. /// </summary> /// <param name="type">The type to instantiate.</param> /// <param name="context">ScriptContext to be passed to the <c>type</c> constructor.</param> /// <param name="caller">DTypeDesc to be passed to the <c>type</c> constructor.</param> /// <returns>New instance of <c>type</c> created using specified constructor.</returns> /// <exception cref="PhpException">Fatal error.</exception> /// <exception cref="PhpUserException">Uncaught user exception.</exception> /// <exception cref="ScriptDiedException">Script died or exit.</exception> /// <exception cref="TargetInvocationException">An internal error thrown by the target.</exception> internal static DObject InvokeConstructor(DTypeDesc /*!*/ type, ScriptContext context, DTypeDesc caller) { Debug.Assert(type != null); try { var newobj = type.RealTypeCtor_ScriptContext_DTypeDesc; if (newobj == null) { lock (type) if ((newobj = type.RealTypeCtor_ScriptContext_DTypeDesc) == null) { // emit the type creation: newobj = type.RealTypeCtor_ScriptContext_DTypeDesc = (DTypeDesc.Ctor_ScriptContext_DTypeDesc)BuildNewObj <DTypeDesc.Ctor_ScriptContext_DTypeDesc>(type.RealType, Emit.Types.ScriptContext_DTypeDesc); } } return(ClrObject.Wrap(newobj(context, caller))); } catch (TargetInvocationException e) { if (e.InnerException is PhpException || e.InnerException is PhpUserException || e.InnerException is ScriptDiedException || e.InnerException is System.Threading.ThreadAbortException) { throw e.InnerException; } throw; } }
/// <summary> /// The argument <paramref name="completeSource" /> determines whether the source code /// is complete PHP script file, which is a case in dynamic includ in Silverlight /// </summary> public TransientCompilationUnit Build(string /*!*/ sourceCode, SourceCodeDescriptor descriptor, EvalKinds kind, CompilationContext /*!*/ context, ScriptContext /*!*/ scriptContext, DTypeDesc referringType, NamingContext namingContext, bool completeSource) { PhpSourceFile source_file = new PhpSourceFile(context.Config.Compiler.SourceRoot, RelativePath.ParseCanonical(descriptor.ContainingSourcePath)); Encoding encoding = context.Config.Globalization.PageEncoding; TransientCompilationUnit result = new TransientCompilationUnit (sourceCode, source_file, encoding, namingContext, descriptor.Line, descriptor.Column, completeSource); if (!result.PreCompile(context, scriptContext, descriptor, kind, referringType)) { return(null); } DefineGlobalType(((TransientModuleBuilder)result.ModuleBuilder).AssemblyBuilder.RealModuleBuilder); if (!result.Compile(context, kind)) { return(null); } BakeGlobals(); result.PostCompile(descriptor); return(result); }
/// <summary> /// Used by full-reflect (CLR). /// </summary> public ClassConstant(VariableName name, DTypeDesc /*!*/ declaringType, PhpMemberAttributes memberAttributes) : base(new DConstantDesc(declaringType, memberAttributes, null)) { Debug.Assert(declaringType != null); this.name = name; }
/// <summary> /// Serializes a graph of connected objects to a byte array using a given formatter. /// </summary> /// <param name="variable">The variable to serialize.</param> /// <param name="caller">DTypeDesc of the caller's class context if it is known or UnknownTypeDesc if it should be determined lazily.</param> /// <returns> /// The serialized representation of the <paramref name="variable"/> or a <B>null</B> reference on error. /// </returns> /// <exception cref="PhpException">Serialization failed (Notice).</exception> public PhpBytes Serialize(object variable, DTypeDesc caller) { MemoryStream stream = new MemoryStream(); try { try { // serialize the variable into the memory stream GetFormatter(caller).Serialize(stream, variable); } catch (System.Reflection.TargetInvocationException e) { throw e.InnerException; } } catch (SerializationException e) { PhpException.Throw(PhpError.Notice, LibResources.GetString("serialization_failed", e.Message)); return(null); } // extract the serialized data return(new PhpBytes(stream.ToArray())); }
/// <summary> /// Deserializes a graph of connected object from a byte array using a given formatter. /// </summary> /// <param name="bytes">The byte array to deserialize the graph from.</param> /// <param name="caller">DTypeDesc of the caller's class context if it is known or UnknownTypeDesc if it should be determined lazily.</param> /// <returns> /// The deserialized object graph or an instance of <see cref="PhpReference"/> containing <B>false</B> on error. /// </returns> /// <exception cref="PhpException">Deserialization failed (Notice).</exception> public PhpReference Deserialize(PhpBytes bytes, DTypeDesc caller) { MemoryStream stream = new MemoryStream(bytes.ReadonlyData); object result = null; try { try { // deserialize the data result = GetFormatter(caller).Deserialize(stream); } catch (System.Reflection.TargetInvocationException e) { throw e.InnerException; } } catch (SerializationException e) { PhpException.Throw(PhpError.Notice, LibResources.GetString("deserialization_failed", e.Message, stream.Position, stream.Length)); return(new PhpReference(false)); } return(PhpVariable.MakeReference(result)); }
public PhpInvokeBinderKey(string methodName, int genericParamsCount, int paramsCount, DTypeDesc callerClassContext, Type returnType) { this.methodName = methodName; this.genericArgumentCount = genericParamsCount; this.argumentCount = paramsCount; this.callerClassContext = callerClassContext; this.returnType = returnType; StringBuilder sb = new StringBuilder((methodName != null ? methodName.Length : 0) + returnType.Name + 16); sb.Append(methodName); sb.Append("|"); sb.Append(argumentCount); sb.Append("|"); sb.Append(genericArgumentCount); sb.Append("|"); sb.Append(returnType.Name); sb.Append("|"); if (callerClassContext != null) { sb.Append(callerClassContext.GetHashCode()); } stringKey = sb.ToString(); }
/// <summary> /// Applies the new item access on a given variable (<B>ReadRef</B> semantics). /// </summary> public override PhpReference GetRef(ref object var, ScriptContext context, DTypeDesc caller) { PhpReference reference = new PhpReference(); Operators.SetItem(reference, ref var); return(reference); }
internal override bool Analyze(DirectTypeRef node, Analyzer analyzer) { resolvedType = analyzer.ResolveTypeName(node.ClassName, analyzer.CurrentType, analyzer.CurrentRoutine, node.Span, false); // base call must follow the class name resolution: bool args_static = base.Analyze(node, analyzer); if (args_static) { DTypeDesc[] resolved_arguments = DTypeDesc.EmptyArray; var genericParams = node.GenericParams; if (genericParams != null && genericParams.Count > 0) { resolved_arguments = new DTypeDesc[genericParams.Count]; for (int i = 0; i < genericParams.Count; i++) { resolved_arguments[i] = TypeRefHelper.ResolvedType(genericParams[i]).TypeDesc; } } resolvedType = resolvedType.MakeConstructedType(analyzer, resolved_arguments, node.Span); } return(args_static); }
public PhpGetMemberBinder(string fieldName, DTypeDesc classContext, bool issetSemantics, Type/*!*/returnType) { this._fieldName = fieldName; this._classContext = classContext; this._issetSemantics = issetSemantics; this._returnType = returnType; }
/// <summary> /// Used by compiler and full-reflect. /// </summary> internal DPropertyDesc(DTypeDesc/*!*/ declaringType, PhpMemberAttributes memberAttributes) : base(declaringType, memberAttributes) { Debug.Assert(declaringType != null); this._getterStub = null; // to be generated on demand this._setterStub = null; // to be generated on demand }
public PhpGetMemberBinder(string fieldName, DTypeDesc classContext, bool issetSemantics, Type /*!*/ returnType) { this._fieldName = fieldName; this._classContext = classContext; this._issetSemantics = issetSemantics; this._returnType = returnType; }
public static DObject GetTypeOf(NamingContext/*!*/ namingContext, DTypeDesc caller, object typeNameOrObject) { ScriptContext context = ScriptContext.CurrentContext; DTypeDesc type = PhpObjects.ClassNameOrObjectToType(context, namingContext, caller, typeNameOrObject, true); if (type == null) return null; return ClrObject.Create(type.RealType); }
/// <remarks> /// We have to inject <c>export</c> method into <see cref="Library.SPL.Reflector"/> interface, since it cannot be written in C# /// (abstract public static method with implementation in an interface). It could be declared in pure IL, but it would be ugly. /// </remarks> /// <param name="typedesc"><see cref="DTypeDesc"/> corresponding to <see cref="Library.SPL.Reflector"/>.</param> private void AddExportMethod(DTypeDesc /*!*/ typedesc) { Debug.Assert(typedesc != null); Debug.Assert(typedesc.RealType == typeof(Library.SPL.Reflector)); // public static object export( ScriptContext context ){ return null; } AddMethodToType(typedesc, PhpMemberAttributes.Public | PhpMemberAttributes.Static | PhpMemberAttributes.Abstract, "export", null); }
public static void Call(NamingContext namingContext, DTypeDesc caller, string className) { ScriptContext context = ScriptContext.CurrentContext; // If class isn't defined autoload functions are called automatically until class is declared if (context.IsSplAutoloadEnabled) ScriptContext.CurrentContext.ResolveType(className, namingContext, caller, null, ResolveTypeFlags.UseAutoload); }
/// <summary> /// Invokes this callback. Can be used if DTypeDesc of caller's class context is known without an overhead of determining it. /// </summary> /// <param name="caller">DTypeDesc of the caller's class context.</param> /// <param name="args">Arguments to be passed to target function or method (can be <see cref="PhpReference"/>s).</param> /// <returns>The value returned by the called function or method (can be a <see cref="PhpReference"/>).</returns> public object Invoke(DTypeDesc caller, params object[] args) { if (!IsBound && !Bind(false, caller, null)) { return(null); } return(InvokeInternal(args)); }
/// <param name="context">A script context to get declarators from.</param> /// <param name="caller">A current type context.</param> public TypesProvider(ScriptContext /*!*/ context, DTypeDesc /*!*/ caller) { Debug.Assert(context != null && caller != null); this.context = context; this.caller = caller; Debug.WriteLine("PROVIDER", "created"); }
protected PhpBaseInvokeMemberBinder(string methodName, int genericParamsCount, int paramsCount, DTypeDesc callerClassContext, Type returnType) { this._methodName = methodName; this._genericParamsCount = genericParamsCount; this._paramsCount = paramsCount; this._classContext = callerClassContext; this._returnType = returnType; }
/// <param name="context">A script context to get declarators from.</param> /// <param name="caller">A current type context.</param> public TypesProvider(ScriptContext/*!*/ context, DTypeDesc/*!*/ caller) { Debug.Assert(context != null && caller != null); this.context = context; this.caller = caller; Debug.WriteLine("PROVIDER", "created"); }
/// <summary> /// Used by all subclasses except for <see cref="GlobalTypeDesc"/>. /// </summary> protected DMemberDesc(DTypeDesc /*!*/ declaringType, PhpMemberAttributes memberAttributes) { Debug.Assert(declaringType != null); this.declaringType = declaringType; this.memberAttributes = memberAttributes; this.member = null; // to be filled by DMember or at run-time (if applicable) }
public static string GetCalledClass(DTypeDesc caller) { if (caller == null || caller.IsUnknown) { return(null); } return(caller.MakeFullName()); }
/// <summary> /// ResizeItemss types stack to maximum of a given size and a double of the current size. /// </summary> /// <param name="size">The minimal required size.</param> private void ResizeTypes(int size) { int new_size = (size > 2 * Items.Length) ? size : 2 * Items.Length; // doubles the items array: DTypeDesc[] new_types = new DTypeDesc[new_size]; Array.Copy(Types, 0, new_types, 0, Top); Types = new_types; }
/// <summary> /// Used by compiler. /// </summary> public ClassConstant(VariableName name, DTypeDesc /*!*/ declaringType, PhpMemberAttributes memberAttributes, SourceUnit /*!*/ sourceUnit, Text.Span position) : base(new DConstantDesc(declaringType, memberAttributes, null)) { Debug.Assert(declaringType != null); this.name = name; this.span = position; this.sourceUnit = sourceUnit; }
/// <summary> /// Creates a formatter (always non-null). /// </summary> /// <param name="caller">DTypeDesc of the class context or UnknownTypeDesc if class context is not known yet and will be determined lazily.</param> /// <returns>New IFormatter class instance.</returns> private IFormatter GetFormatter(DTypeDesc caller) { IFormatter result = CreateFormatter(caller); if (result == null) { throw new InvalidMethodImplementationException(GetType().FullName + "CreateFormatter"); } return(result); }
// variables may be null when the code is global protected LinqContext(DObject outerType, Dictionary<string, object> variables, ScriptContext/*!*/ context, DTypeDesc typeHandle) { if (context == null) throw new ArgumentNullException("context"); this.variables = variables; this.outerType = outerType; this.context = context; this.typeHandle = typeHandle; }
/// <summary> /// Gets dynamic object representing classes /// </summary> public override bool TryGetMember( GetMemberBinder binder, out Object result ) { DTypeDesc resType = ResolveType(binder.Name); result = new ClassScope(Context, resType); return(true); }
public static void Call(NamingContext namingContext, DTypeDesc caller, string className) { ScriptContext context = ScriptContext.CurrentContext; // If class isn't defined autoload functions are called automatically until class is declared if (context.IsSplAutoloadEnabled) { ScriptContext.CurrentContext.ResolveType(className, namingContext, caller, null, ResolveTypeFlags.UseAutoload); } }
/// <summary> /// Used by compiler through subclasses (<paramref name="arglessStub"/> is <B>null</B> then). /// Called by a declaring helper at run-time. /// </summary> /// <param name="declaringType">The declaring type. Can be null.</param> /// <param name="memberAttributes">Attributes of the function.</param> /// <param name="arglessStub">The stub to be called. Cannot be null.</param> /// <param name="needsIndex">True to allocate <see cref="Index"/>. Usable for preserved descs, for global functions that can be reused.</param> internal DRoutineDesc(DTypeDesc/*!*/ declaringType, PhpMemberAttributes memberAttributes, RoutineDelegate arglessStub, bool needsIndex) : base(declaringType, memberAttributes) { Debug.Assert(declaringType != null); this._arglessStub = arglessStub; // allocate an index, only for preserved descs if (needsIndex) // assign an index only if needed (save indexes, since they cause prealocation of larger BitArray) this.Index = System.Threading.Interlocked.Increment(ref LastIndex); }
public static int Parse(NamingContext /*!*/ namingContext, DTypeDesc caller, PhpResource parser, string data, bool is_final) { XmlParserResource xmlParser = XmlParserResource.ValidResource(parser); if (xmlParser != null) { return(xmlParser.Parse(caller, namingContext, data, is_final) ? 1 : 0); } return(0); }
/// <summary> /// Creates appropriate binder according to paramaters specified /// </summary> /// <param name="methodName">Name of the method known during binder creation.</param> /// <param name="genericParamsCount">Number of generic type arguments of the method</param> /// <param name="paramsCount">Number of arguments of the method</param> /// <param name="callerClassContext">TypeDesc of the class that is calling this method</param> /// <param name="returnType">Type which is expected from the call site to return</param> /// <returns>Return appropriate binder derived from PhpInvokeMemberBinder</returns> public static PhpInvokeMemberBinder Create(string methodName, int genericParamsCount, int paramsCount, DTypeDesc callerClassContext, Type returnType) { if (methodName == null) { return new PhpIndirectInvokeMemberBinder(genericParamsCount, paramsCount, callerClassContext, returnType); } else { return new PhpInvokeMemberBinder(methodName, genericParamsCount, paramsCount, callerClassContext, returnType); } }
public static object CallUserFunction(DTypeDesc caller, PhpCallback function, params object[] args) { if (function == null) { PhpException.ArgumentNull("function"); return null; } if (function.IsInvalid) return null; // invoke the callback: return PhpVariable.Dereference(function.Invoke(caller, args)); }
static PhpReference notsetOperation(DObject self, string name, DTypeDesc caller, PhpReference refrnc) { bool getter_exists; // the CT property has been unset -> try to invoke __get PhpReference get_ref = self.InvokeGetterRef(name, caller, out getter_exists); if (getter_exists) return get_ref ?? new PhpReference(); Debug.Assert(refrnc != null); refrnc.IsAliased = true; refrnc.IsSet = true; return refrnc; }
public void BindOrBiteMyLegsOff(DTypeDesc caller, NamingContext namingContext) { if (Callback != null) { if (Callback.TargetInstance == null && Parser._handlerObject != null) _currentCallback = new PhpCallback(Parser._handlerObject, Callback.RoutineName); else _currentCallback = Callback; Bound = _currentCallback.Bind(true, caller, namingContext); } else { Bound = false; } }
public static object CallUserFunctionArray(DTypeDesc caller, PhpCallback function, PhpArray args) { object[] args_array; if (args != null) { args_array = new object[args.Count]; args.CopyValuesTo(args_array, 0); } else { args_array = ArrayUtils.EmptyObjects; } return CallUserFunction(caller, function, args_array); }
public static CallSiteBinder/*!*/MethodCall(string methodName, int genericParamsCount, int paramsCount, DTypeDesc classContext, Type/*!*/returnType) { // CallSite< Func< CallSite, object /*target instance*/, ScriptContext, {args}*/*method call arguments*/, (DTypeDesc)?/*class context, iff <classContext>.IsUnknown*/, (object)?/*method name, iff <methodName>==null*/, <returnType> > > PhpInvokeBinderKey key = new PhpInvokeBinderKey(methodName, genericParamsCount, paramsCount, classContext, returnType); lock (invokeMemberBinders) { PhpInvokeMemberBinder res; if (!invokeMemberBinders.TryGetValue(key.ToString(), out res)) { invokeMemberBinders[key.ToString()] = res = PhpBaseInvokeMemberBinder.Create(methodName, genericParamsCount, paramsCount, classContext, returnType); } return res; } }
/// <summary> /// Generates Expression that throws a 'Protected method called' or 'Private method called' <see cref="PhpException"/>. /// </summary> /// <param name="method">The <see cref="DRoutineDesc"/>.</param> /// <param name="callerContext">The caller that was passed to method lookup or <B>null</B> /// if it should be determined by this method (by tracing the stack).</param> /// <remarks> /// This method is intended to be called after <see cref="DTypeDesc.GetMethod"/> has returned /// <see cref="GetMemberResult.BadVisibility"/> while performing a method lookup. /// </remarks> public static Expression/*!*/ ThrowVisibilityError(DRoutineDesc/*!*/ method, DTypeDesc/*!*/ callerContext) { if (method.IsProtected) { return ThrowError("protected_method_called", method.DeclaringType.MakeFullName(), method.MakeFullName(), callerContext == null ? String.Empty : callerContext.MakeFullName()); } else if (method.IsPrivate) { return ThrowError("private_method_called", method.DeclaringType.MakeFullName(), method.MakeFullName(), callerContext == null ? String.Empty : callerContext.MakeFullName()); } throw new NotImplementedException(); }
/// <summary> /// Calls the method referred by <paramref name="methodName"/> from the user defined /// object <paramref name="classNameOrObject"/> with parameters <paramref name="args"/>. /// </summary> /// <param name="caller">DTypeDesc of the caller's class context. Can be UnknownTypeDesc.</param> /// <param name="methodName">The name of the method.</param> /// <param name="classNameOrObject">An instance to invoke the method on or a class name.</param> /// <param name="args">Parameters to invoke the method with.</param> /// <returns>The method's return value (always dereferenced).</returns> internal static object CallUserMethodInternal(DTypeDesc caller, string methodName, object classNameOrObject, ICollection args) { PhpException.Throw(PhpError.Notice, LibResources.GetString("call_user_method_deprecated")); object ret_val = false; DObject obj; string class_name; ScriptContext context = ScriptContext.CurrentContext; //DTypeDesc classContext = PhpStackTrace.GetClassContext(); // TODO: GetClassContext only if needed by context.ResolveType if (caller != null && caller.IsUnknown) caller = PhpStackTrace.GetClassContext(); if ((obj = classNameOrObject as DObject) != null) { // push arguments on stack context.Stack.AddFrame(args); ret_val = obj.InvokeMethod(methodName, caller, context); } else if ((class_name = PhpVariable.AsString(classNameOrObject)) != null) { // push arguments on stack context.Stack.AddFrame(args); ResolveTypeFlags flags = ResolveTypeFlags.UseAutoload | ResolveTypeFlags.ThrowErrors; DTypeDesc type = PHP.Core.Convert.ObjectToTypeDesc(class_name, flags, caller, context, null, null); ret_val = Operators.InvokeStaticMethod(type, methodName, null, caller, context); } else { PhpException.InvalidArgument("classNameOrObject", LibResources.GetString("arg:not_object_or_class_name")); } return PhpVariable.Dereference(ret_val); }
public ReflectionException(ScriptContext context, DTypeDesc caller) : base(context, caller) { }
public RecursiveDirectoryIterator(ScriptContext/*!*/context, DTypeDesc caller) : base(context, caller) { }
public FilesystemIterator(ScriptContext/*!*/context, DTypeDesc caller) : base(context, caller) { }
public SplFileInfo(ScriptContext/*!*/context, DTypeDesc caller) : base(context, caller) { }
public __PHP__DateTime(ScriptContext context, DTypeDesc caller) : base(context, caller) { }
public static DTypeDesc MakeGenericTypeInstantiation(DTypeDesc genericType, DTypeDesc[]/*!*/ args, int argCount) { // error already reported: if (genericType == null) return null; // checks the arguments and substitutes the default types to the missing ones if applicable: if (!genericType.MakeGenericArguments(ref args, ref argCount, _ReportErrorMakingInstantiation)) { // some mandatory arguments are missing: return null; } Type[] real_args = new Type[argCount]; for (int i = 0; i < argCount; i++) { // error already reported: if (args[i] == null) return null; real_args[i] = args[i].RealType; } Type instantiation = genericType.RealType.MakeGenericType(real_args); return DTypeDesc.Create(instantiation); }
public static object NewClr(DTypeDesc clrType, ScriptContext context) { PhpStack stack = context.Stack; if (clrType == null) { stack.RemoveFrame(); return null; } // invoke constructor argless stub, which will instantiate the type stack.AllowProtectedCall = true; return /*(DObject)*/((ClrTypeDesc)clrType).Constructor.Invoke(null, stack); }
public static bool InstanceOf(object var, DTypeDesc type) { return (type != null) ? type.RealType.IsInstanceOfType(PhpVariable.Unwrap(var)) : false; }
public static DObject TypeOf(DTypeDesc type) { return (type != null) ? ClrObject.WrapRealObject(type.RealType) : null; }
public static DTypeDesc MakeGenericTypeInstantiation(DTypeDesc genericType, DTypeDesc arg1) { return MakeGenericTypeInstantiation(genericType, new DTypeDesc[] { arg1 }); }
public static string GetFullyQualifiedName(DTypeDesc type) { if (type == null) return string.Empty; return type.MakeFullName(); }
public static DTypeDesc MakeGenericTypeInstantiation(DTypeDesc genericType, DTypeDesc arg1, DTypeDesc arg2, DTypeDesc arg3, DTypeDesc arg4) { return MakeGenericTypeInstantiation(genericType, new DTypeDesc[] { arg1, arg2, arg3, arg4 }); }
private static void ReportErrorMakingInstantiation(DTypeDesc.MakeGenericArgumentsResult/*!*/ error, DTypeDesc/*!*/ genericType, DTypeDesc argument, GenericParameterDesc/*!*/ parameter) { switch (error) { case DTypeDesc.MakeGenericArgumentsResult.IncompatibleConstraint: PhpException.Throw(PhpError.Error, CoreResources.GetString("incompatible_type_parameter_constraints_type", argument.MakeFullName(), parameter.RealType.GenericParameterPosition, parameter.RealType.Name)); break; case DTypeDesc.MakeGenericArgumentsResult.MissingArgument: PhpException.Throw(PhpError.Error, CoreResources.GetString("missing_type_argument_in_type_use", genericType.MakeFullName(), parameter.RealType.GenericParameterPosition, parameter.RealType.Name)); break; case DTypeDesc.MakeGenericArgumentsResult.TooManyArguments: PhpException.Throw(PhpError.Warning, CoreResources.GetString("too_many_type_arguments_in_type_use", genericType.MakeFullName(), genericType.GenericParameters.Length)); break; } }
public static DTypeDesc MakeGenericTypeInstantiation(DTypeDesc genericType, DTypeDesc[]/*!*/ args) { return MakeGenericTypeInstantiation(genericType, args, args.Length); }