back to dev
[m6w6/ext-http] / reflection2php.php
index 37747be51c48702b537dce5e153ed74b953804e2..e486012037fde36f229a296b06431137e7277a49 100755 (executable)
@@ -28,104 +28,178 @@ function c($n, $c) {
     return true;
 }
 
-if (!strlen($ext = $argv[1]))
-       die(sprintf("Usage: %s <ext>\n", $argv[0]));
+ob_start(function($s) {
+    // redirect any output to stderr
+    fwrite(STDERR, $s);
+    return true;
+});
+
+$out = STDOUT;
+switch ($argc) {
+    default:
+    case 3:
+        $out = fopen($argv[2], "w") or die;
+    case 2:
+        $ext = $argv[1];
+        break;
+    
+    case 1:
+        die(sprintf($out, "Usage: %s <ext>\n", $argv[0]));
+}
 
-printf("<?php\n\n");
+fprintf($out, "<?php\n\n");
 
 $ext = new ReflectionExtension($ext);
+
+$constants  = array();
+$functions  = array();
+$structures = array();
+
+// split up by namespace first
 foreach ($ext->getConstants() as $constant => $value) {
-    printf("define('%s', '%s');\n", $constant, $value);
+    $ns = ($nsend = strrpos($constant, "\\")) ? substr($constant, 0, $nsend++) : "";
+    $cn = substr($constant, $nsend);
+    $constants[$ns][$cn] = $value;
 }
-printf("\n");
-
 foreach ($ext->getFunctions() as $f) {
-    printf("function %s(", $f->getName());
-    $ps = array();
-    foreach ($f->getParameters() as $p) {
-        $p1 = sprintf("%s%s\$%s", t($p), $p->isPassedByReference()?"&":"", $p->getName());
-        if ($p->isOptional()) {
-            if ($p->isDefaultValueAvailable()) {
-                $p1 .= sprintf(" = %s", var_export($p->getDefaultValue(), true));
-            } elseif (!($p->isArray() || $p->getClass()) || $p->allowsNull()) {
-                $p1 .= " = NULL";
-            } elseif ($p->isArray()) {
-                $p1 .= " = array()";
-            }
-        }
-        $ps[] = $p1;
-    }
-    printf("%s) {\n}\n", implode(", ", $ps));
+    /* @var $f ReflectionFunction */
+    $ns = $f->inNamespace() ? $f->getNamespaceName() : "";
+    $functions[$ns][$f->getShortName()] = $f;
+}
+foreach ($ext->getClasses() as $c) {
+    /* @var $c ReflectionClass */
+    $ns = $c->inNamespace() ? $c->getNamespaceName() : "";
+    $structures[$ns][$c->getShortName()] = $c;
 }
-printf("\n");
 
-$classes = $ext->getClasses();
-usort($classes, function($a,$b) {
-        $cmp = strcmp($a->getNamespaceName(), $b->getNamespaceName());
-        if (!$cmp) {
-            $cmp = strcmp($a->getShortName(), $b->getShortName());
-        }
-        return $cmp;
-    }
-);
+$namespaces = array_unique(array_merge(
+        array_keys($constants),
+        array_keys($functions),
+        array_keys($structures)
+));
 
-foreach ($classes as $class) {
+// simple sort
+natsort($namespaces);
 
-    if ($class->inNamespace()) {
-        printf("namespace %s\n{\n", $class->getNamespaceName());
+foreach ($namespaces as $ns) {
+    fprintf($out, "namespace %s%s\n{\n", $ns, strlen($ns) ? " " : "");
+    //
+    if (isset($constants[$ns])) {
+        ksort($constants[$ns], SORT_NATURAL);
+        foreach ($constants[$ns] as $cn => $value) {
+            fprintf($out, "\tconst %s = %s;\n", $cn, var_export($value, true));
+        }
     }
-       printf("\t%s%s %s ", m($class->getModifiers()), $class->isInterface() ? "interface":"class" ,$class->getShortName());
-       if ($p = $class->getParentClass()) {
-               printf("extends \\%s ", $p->getName());
-       }
-       if ($i = $class->getInterfaceNames()) {
-               printf("implements \\%s ", implode(", \\", array_filter($i,function($v){return$v!="Traversable";})));
-       }
-       printf("\n\t{\n");
-
-       $_=0;
-       foreach ($class->getConstants() as $n => $v) {
-               c($n, $class) and $_+=printf("\t\tconst %s = %s;\n", $n, var_export($v, true));
-       }
-       $_ and printf("\n");
-       $_=0;
-       foreach ($class->getProperties() as $p) {
-               if ($p->getDeclaringClass()->getName() == $class->getName()) {
-                       $_+=printf("\t\t%s\$%s;\n", m($p->getModifiers()), $p->getName());
-               }
-       }
-       $_ and printf("\n");
-
-       foreach ($class->getMethods() as $m) {
-               if ($m->getDeclaringClass()->getName() == $class->getName()) {
-                       printf("\t\t%sfunction %s(", m($m->getModifiers()), $m->getName());
-                       $ps = array();
-                       foreach ($m->getParameters() as $p) {
-                               $p1 = sprintf("%s%s\$%s", t($p), $p->isPassedByReference()?"&":"", $p->getName());
+    //
+    if (isset($functions[$ns])) {
+        ksort($functions[$ns], SORT_NATURAL);
+        foreach ($functions[$ns] as $fn => $f) {
+            /* @var $f ReflectionFunction */
+            fprintf($out, "\n\tfunction %s(", $fn);
+            $ps = array();
+            foreach ($f->getParameters() as $p) {
+                $p1 = sfprintf($out, "%s%s\$%s", t($p), 
+                        $p->isPassedByReference()?"&":"", $p->getName());
                 if ($p->isOptional()) {
                     if ($p->isDefaultValueAvailable()) {
-                        $p1 .= sprintf(" = %s", var_export($p->getDefaultValue(), true));
+                        $p1 .= sfprintf($out, " = %s", 
+                                var_export($p->getDefaultValue(), true));
                     } elseif (!($p->isArray() || $p->getClass()) || $p->allowsNull()) {
-                        $p1 .= sprintf(" = NULL");
+                        $p1 .= " = NULL";
                     } elseif ($p->isArray()) {
                         $p1 .= " = array()";
                     }
                 }
-                               $ps[] = $p1;
-                       }
-                       printf("%s)", implode(", ", $ps));
-                       if ($m->isAbstract()) {
-                               printf(";\n\n");
-                       } else {
-                               printf(" {\n\t\t}\n\n");
-                       }
-               }
-       }
+                $ps[] = $p1;
+            }
+            fprintf($out, "%s) {\n\t}\n", implode(", ", $ps));
+        }
+    }
+    //
+    if (isset($structures[$ns])) {
+        uasort($structures[$ns], function ($a, $b) {
+            /* @var $a ReflectionClass */
+            /* @var $b ReflectionClass */
+            $score = array_sum([
+                -!$a->isInterface()+
+                -!$a->isAbstract()+
+                -!$a->isTrait()+
+                -!substr_compare($a->getShortName(), "Exception", -strlen("Exception")),
+                +!$b->isInterface()+
+                +!$b->isAbstract()+
+                +!$b->isTrait()+
+                -!substr_compare($b->getShortName(), "Exception", -strlen("Exception")),
+            ]);
+            
+            if ($score) {
+                return -$score;
+            }
+            return strnatcmp($a->getShortName(), $b->getShortName());
+        });
+        foreach ($structures[$ns] as $cn => $c) {
+            fprintf($out, "\n\t%s%s %s ", m($c->getModifiers()), 
+                    $c->isInterface() ? "interface":"class", $c->getShortName());
+            if ($p = $c->getParentClass()) {
+                fprintf($out, "extends \\%s ", $p->getName());
+            }
+            if ($i = $c->getInterfaceNames()) {
+                fprintf($out, "implements \\%s ", 
+                        implode(", \\", array_filter($i, function($v) {
+                            return $v != "Traversable";
+                            
+                        }))
+                );
+            }
+            fprintf($out, "\n\t{\n");
+
+            $_=0;
+            foreach ($c->getConstants() as $n => $v) {
+                c($n, $c) and $_+=fprintf($out, "\t\tconst %s = %s;\n", $n, 
+                        var_export($v, true));
+            }
+            $_ and fprintf($out, "\n");
+            $_=0;
+            foreach ($c->getProperties() as $p) {
+                if ($p->getDeclaringClass()->getName() == $c->getName()) {
+                    $_+=fprintf($out, "\t\t%s\$%s;\n", m($p->getModifiers()), 
+                            $p->getName());
+                }
+            }
+            $_ and fprintf($out, "\n");
 
-    printf("\t}\n");
-    if ($class->inNamespace()) {
-        printf("}\n");
+            foreach ($c->getMethods() as $m) {
+                if ($m->getDeclaringClass()->getName() == $c->getName()) {
+                    fprintf($out, "\t\t%sfunction %s(", m($m->getModifiers()), 
+                            $m->getName());
+                    $ps = array();
+                    foreach ($m->getParameters() as $p) {
+                        $p1 = sprintf("%s%s\$%s", t($p), 
+                                $p->isPassedByReference()?"&":"", $p->getName());
+                        if ($p->isOptional()) {
+                            if ($p->isDefaultValueAvailable()) {
+                                $p1 .= sprintf(" = %s", 
+                                        var_export($p->getDefaultValue(), true));
+                            } elseif (!($p->isArray() || $p->getClass()) || $p->allowsNull()) {
+                                $p1 .= sprintf(" = NULL");
+                            } elseif ($p->isArray()) {
+                                $p1 .= " = array()";
+                            }
+                        }
+                        $ps[] = $p1;
+                    }
+                    fprintf($out, "%s)", implode(", ", $ps));
+                    if ($m->isAbstract()) {
+                        fprintf($out, ";\n\n");
+                    } else {
+                        fprintf($out, " {\n\t\t}\n\n");
+                    }
+                }
+            }
+
+            fprintf($out, "\t}\n");
+            
+        }
     }
-    printf("\n");
+    //
+    fprintf($out, "}\n\n");
 }
-