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)); } }
/// <summary> /// Triggers the error by passing it to /// the user handler first (<see cref="PhpCoreConfiguration.UserErrorHandler"/> and then to /// the internal handler (<see cref="Throw(PhpError, string)"/>. /// </summary> public static void TriggerError(Context ctx, PhpError error, string message) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (message == null) { message = string.Empty; } // try the user handler var config = ctx.Configuration.Core; if (config.UserErrorHandler != null && (config.UserErrorTypes & error) != 0) { var trace = new PhpStackTrace(); if (!config.UserErrorHandler.Invoke(ctx, (int)error, message, trace.GetFilename(), trace.GetLine(), PhpValue.Null).IsFalse) { return; } } // fallback to internal handler Throw(error, message); }
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); }
public Exception(string message = "", long code = 0, Throwable previous = null) : base(message, innerException: previous as System.Exception) { _stacktrace = new PhpStackTrace(); this.file = _stacktrace.GetFilename(); this.line = _stacktrace.GetLine(); __construct(message, code, previous); }
public object getTraceAsString(ScriptContext context) { if (stringTraceCache == null) { PhpArray array = trace.Value as PhpArray; stringTraceCache = (array != null) ? PhpStackTrace.FormatUserTrace(array) : String.Empty; } return(stringTraceCache); }
/// <summary> /// Gets stack trace as string. /// </summary> public static string GetStackTraceString(this PhpStackTrace trace, int skip = 0) { var lines = trace.GetLines(); var result = new StringBuilder(); for (int i = 1 + skip, order = 0; i < lines.Length; i++, order++) { result.AppendLine(lines[i].ToStackTraceLine(order)); } return(result.ToString()); }
/// <summary> /// Gets stack trace as string. /// </summary> public static string GetStackTraceString(this PhpStackTrace trace, int skip = 0) { var result = StringBuilderUtilities.Pool.Get(); var lines = trace.GetLines(); for (int i = 1 + skip, order = 0; i < lines.Length; i++, order++) { lines[i].GetStackTraceLine(order, result); result.AppendLine(); } return(StringBuilderUtilities.GetStringAndReturn(result)); }
/// <summary> /// Invoked when the instance is created (not called when unserialized). /// </summary> protected override void InstanceCreated(ScriptContext context) { base.InstanceCreated(context); PhpStackTrace trace = new PhpStackTrace(context, 1); PhpStackFrame frame = trace.GetFrame(0); Debug.Assert(frame != null); this.file.Value = frame.File; this.line.Value = frame.Line; this.column.Value = frame.Column; this.trace.Value = trace.GetUserTrace(); }
/// <summary> /// Gets PHP `backtrace`. See <c>debug_backtrace()</c>. /// </summary> public static PhpArray GetBacktrace(this PhpStackTrace trace, int skip = 0, int limit = int.MaxValue) { if (skip < 0) { throw new ArgumentOutOfRangeException(); } var lines = trace.GetLines(); var arr = new PhpArray(); for (int i = 1 + skip; i < lines.Length - 1 && arr.Count < limit; i++) { arr.Add((PhpValue)lines[i].ToUserFrame()); } return(arr); }
/// <summary> /// Gets exception string. /// </summary> public static string FormatExceptionString(this PhpStackTrace trace, string exceptionname, string message) { var result = StringBuilderUtilities.Pool.Get(); // TODO: texts to resources // {exceptionname} in {location} // Stack trace: // #0 ... var lines = trace.GetLines(); result.Append(exceptionname); if (!string.IsNullOrEmpty(message)) { result.Append(": "); result.Append(message); } if (lines.Length != 0) { if (lines[0].HasLocation) { result.Append(" in "); lines[0].GetStackTraceLine(-1, result); } if (lines.Length > 1) { result.AppendLine(); result.AppendLine("Stack trace:"); for (int i = 1; i < lines.Length; i++) { lines[i].GetStackTraceLine(i - 1, result); result.AppendLine(); } } } // return(StringBuilderUtilities.GetStringAndReturn(result)); }
/// <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)); }
protected Exception() { _stacktrace = new PhpStackTrace(); }
protected Error() { _stacktrace = new PhpStackTrace(); }
//[return: PhpDeepCopy] // already deep copied public static PhpArray GetObjectVars(DTypeDesc caller, DObject obj, bool IgnoreReferences) { if (obj == null) { return(null); } Converter <object, object> copy = null; /////////////////////////////////////// // This is hot fix for a reference counting problem when reference aren't released in same way as in PHP. // Hence, we need to perform deep copy ignoring references if (IgnoreReferences) { copy = (value) => { PhpReference refValue = value as PhpReference; if (refValue != null) { return(copy(refValue.Value)); } PhpArray array = value as PhpArray; if (array != null) { PhpArray dst = new PhpArray(array.IntegerCount, array.StringCount); foreach (KeyValuePair <IntStringKey, object> entry in array) { // checks whether a value is a reference pointing to the instance itself: refValue = entry.Value as PhpReference; if (refValue != null && refValue.Value == array) { // copies the value so that it will self-reference the new instance (not the old one): dst.Add(entry.Key, new PhpReference(dst)); } else { dst.Add(entry.Key, copy(entry.Value)); } } return(dst); } return(value); } } ; else { copy = (value) => { return(PhpVariable.DeepCopy(value)); } }; // perform InplaceDeepCopy() here to save one more iteration through the array /////////////////////////////////////// PhpArray result = new PhpArray(0, obj.Count); var foreachEnumerator = obj.GetEnumerator((caller != null && caller.IsUnknown) ? PhpStackTrace.GetClassContext() : caller); while (foreachEnumerator.MoveNext()) //foreach (DictionaryEntry pair in obj) { DictionaryEntry pair = (DictionaryEntry)foreachEnumerator.Current; result.Add((string)pair.Key, copy(pair.Value)); } //result.InplaceCopyOnReturn = true; // already deep copied return(result); }
public static PhpArray GetClassVars(DTypeDesc caller, string className, bool parentsFirst, bool includeStatic) { ScriptContext script_context = ScriptContext.CurrentContext; DTypeDesc type = script_context.ResolveType(className); 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(); // add instance properties bool have_instance_props = false; if (!type.IsAbstract) { // the class has to be instantiated in order to discover default instance property values // (the constructor will initialize default properties, user defined constructor will not be called) DObject obj = type.New(script_context) as DObject; if (obj == null) { return(null); } // populate the resulting array taking into account current caller IDictionaryEnumerator enumerator = obj.GetEnumerator(caller); while (enumerator.MoveNext()) { result.Add(enumerator.Key, enumerator.Value); } have_instance_props = true; } // add static fields (static and instance fields if the type is abstract) if (includeStatic) { foreach (KeyValuePair <VariableName, DPropertyDesc> pair in type.EnumerateProperties(caller)) { if (pair.Value.IsStatic) { result.Add(pair.Key.ToString(), pair.Value.Get(null)); } else if (!have_instance_props) { result.Add(pair.Key.ToString(), null); } } } result.InplaceCopyOnReturn = true; return(result); }