static void AddScriptReference(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } // remember the assembly for class map: s_assClassMap.AddPhpAssemblyNoLock(assembly); // reflect the module for imported symbols: var module = assembly.ManifestModule; // PhpPackageReferenceAttribute foreach (var r in module.GetCustomAttributes <PhpPackageReferenceAttribute>()) { Context.AddScriptReference(r.ScriptType); } // ImportPhpTypeAttribute foreach (var t in module.GetCustomAttributes <ImportPhpTypeAttribute>()) { TypesTable.DeclareAppType(PhpTypeInfoExtension.GetPhpTypeInfo(t.ImportedType)); } // ImportPhpFunctionsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpFunctionsAttribute>()) { // TODO: remember the container, do not reflect repetitiously foreach (var m in t.ContainerType.GetMethods()) { if (m.IsPublic && m.IsStatic && !m.IsPhpHidden()) { RoutinesTable.DeclareAppRoutine(m.Name, m); } } } // ImportPhpConstantsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpConstantsAttribute>()) { // TODO: remember the container, do not reflect repetitiously foreach (var m in t.ContainerType.GetMembers(BindingFlags.Static | BindingFlags.Public)) { if (m is FieldInfo fi && !fi.IsPhpHidden()) { Debug.Assert(fi.IsStatic && fi.IsPublic); if (fi.IsInitOnly || fi.IsLiteral) { ConstsMap.DefineAppConstant(fi.Name, PhpValue.FromClr(fi.GetValue(null))); } else { ConstsMap.DefineAppConstant(fi.Name, new Func <PhpValue>(() => PhpValue.FromClr(fi.GetValue(null)))); } }
public int RegisterMyWidget() { var tinfo = PhpTypeInfoExtension.GetPhpTypeInfo <jpen_Example_Widget>(); this.app.Context.DeclareType(tinfo, "jpen_Example_Widget"); this.app.Context.Call("register_widget", "jpen_Example_Widget"); return(0); }
private static int RunTests(string assemblyFullPath, string[] args) { Console.WriteLine($"Opening assembly \"{assemblyFullPath}\"..."); Assembly pchpAssembly; try { pchpAssembly = Assembly.LoadFrom(assemblyFullPath); } catch (System.Exception e) { Console.WriteLine("Error in opening the assembly:"); Console.WriteLine(e); return(1); } Context.AddScriptReference(pchpAssembly); Console.WriteLine("Assembly loaded"); Console.WriteLine(); // Initialize PHP context with the current root directory and console output using var ctx = Context.CreateConsole(PharName, args); // Set $_SERVER['SCRIPT_NAME'] to be different from __FILE__ so that it NEVER executes // (there is the condition for execution __FILE__ === realpath($_SERVER['SCRIPT_NAME']) in PHPUnit PHAR entry file) ctx.Server[CommonPhpArrayKeys.SCRIPT_NAME] = "__DUMMY_INVALID_FILE"; // Run the PHAR entry point so that all the classes are included var pharLoader = Context.TryGetDeclaredScript(PharName); if (pharLoader.IsValid) { RunScript(ctx, () => pharLoader.Evaluate(ctx, PhpArray.NewEmpty(), null).ToInt()); } // Run the tests themselves return(RunScript(ctx, () => (int)Command.main(ctx, PhpTypeInfoExtension.GetPhpTypeInfo <Command>()))); }
/// <summary> /// Reflects given assembly for PeachPie compiler specifics - compiled scripts, references to other assemblies, declared functions and classes. /// Scripts and declarations are loaded into application context (static). /// </summary> /// <param name="assembly">PeachPie compiler generated assembly.</param> /// <remarks>Not thread safe.</remarks> public static void AddScriptReference(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } if (assembly.GetType(ScriptInfo.ScriptTypeName) == null || !TryAddAssembly(assembly)) { // nothing to reflect return; } // reflect the module for imported symbols: var module = assembly.ManifestModule; // PhpPackageReferenceAttribute foreach (var r in module.GetCustomAttributes <PhpPackageReferenceAttribute>()) { AddPhpPackageReference(r.ScriptType); } // ImportPhpTypeAttribute foreach (var t in module.GetCustomAttributes <ImportPhpTypeAttribute>()) { TypesTable.DeclareAppType(PhpTypeInfoExtension.GetPhpTypeInfo(t.ImportedType)); } // ImportPhpFunctionsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpFunctionsAttribute>()) { if (ExtensionsAppContext.ExtensionsTable.VisitFunctionsContainer(t.ContainerType, out var attr)) { foreach (var m in t.ContainerType.GetMethods()) { if (m.IsPublic && m.IsStatic && !m.IsSpecialName && !m.IsPhpHidden()) { ExtensionsAppContext.ExtensionsTable.AddRoutine(attr, RoutinesTable.DeclareAppRoutine(m.Name, m)); } } } } // ImportPhpConstantsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpConstantsAttribute>()) { if (!s_processedConstantsContainers.Add(t.ContainerType)) { // already visited before continue; } // var extensionName = t.ContainerType.GetCustomAttribute <PhpExtensionAttribute>(false)?.FirstExtensionOrDefault; // reflect constants defined in the container foreach (var m in t.ContainerType.GetMembers(BindingFlags.Static | BindingFlags.Public)) { if (m is FieldInfo fi && !fi.IsPhpHidden()) { Debug.Assert(fi.IsStatic && fi.IsPublic); if (fi.IsInitOnly || fi.IsLiteral) { // constant ConstsMap.DefineAppConstant(fi.Name, PhpValue.FromClr(fi.GetValue(null)), false, extensionName); } else { // static field ConstsMap.DefineAppConstant(fi.Name, new Func <PhpValue>(() => PhpValue.FromClr(fi.GetValue(null))), false, extensionName); } }
/// <summary> /// Reflects given assembly for PeachPie compiler specifics - compiled scripts, references to other assemblies, declared functions and classes. /// Scripts and declarations are loaded into application context (static). /// </summary> /// <param name="assembly">PeachPie compiler generated assembly.</param> /// <remarks>Not thread safe.</remarks> public static void AddScriptReference(Assembly assembly) { if (assembly == null) { throw new ArgumentNullException(nameof(assembly)); } if (assembly.GetType(ScriptInfo.ScriptTypeName) == null || !s_processedAssemblies.Add(assembly)) { // nothing to reflect return; } s_processedAssembliesArr = ArrayUtils.AppendRange(assembly, s_processedAssembliesArr); // TODO: ImmutableArray<T> // remember the assembly for class map: s_assClassMap.AddPhpAssemblyNoLock(assembly); // reflect the module for imported symbols: var module = assembly.ManifestModule; // PhpPackageReferenceAttribute foreach (var r in module.GetCustomAttributes <PhpPackageReferenceAttribute>()) { if (r.ScriptType != null) // always true { AddScriptReference(r.ScriptType.Assembly); } } // ImportPhpTypeAttribute foreach (var t in module.GetCustomAttributes <ImportPhpTypeAttribute>()) { TypesTable.DeclareAppType(PhpTypeInfoExtension.GetPhpTypeInfo(t.ImportedType)); } // ImportPhpFunctionsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpFunctionsAttribute>()) { if (ExtensionsAppContext.ExtensionsTable.VisitFunctionsContainer(t.ContainerType, out var attr)) { foreach (var m in t.ContainerType.GetMethods()) { if (m.IsPublic && m.IsStatic && !m.IsPhpHidden()) { ExtensionsAppContext.ExtensionsTable.AddRoutine(attr, RoutinesTable.DeclareAppRoutine(m.Name, m)); } } } } // ImportPhpConstantsAttribute foreach (var t in module.GetCustomAttributes <ImportPhpConstantsAttribute>()) { if (!s_processedConstantsContainers.Add(t.ContainerType)) { // already visited before continue; } // reflect constants defined in the container foreach (var m in t.ContainerType.GetMembers(BindingFlags.Static | BindingFlags.Public)) { if (m is FieldInfo fi && !fi.IsPhpHidden()) { Debug.Assert(fi.IsStatic && fi.IsPublic); if (fi.IsInitOnly || fi.IsLiteral) { ConstsMap.DefineAppConstant(fi.Name, PhpValue.FromClr(fi.GetValue(null))); } else { ConstsMap.DefineAppConstant(fi.Name, new Func <PhpValue>(() => PhpValue.FromClr(fi.GetValue(null)))); } }