]> granicus.if.org Git - php/commitdiff
Add support for generating method entries from stubs
authorMáté Kocsis <kocsismate@woohoolabs.com>
Thu, 9 Apr 2020 09:27:20 +0000 (11:27 +0200)
committerMáté Kocsis <kocsismate@woohoolabs.com>
Sat, 11 Apr 2020 07:15:14 +0000 (09:15 +0200)
Closes GH-5363

Zend/zend_API.h
build/gen_stub.php
ext/date/php_date.c
ext/date/php_date.h
ext/date/php_date.stub.php
ext/date/php_date_arginfo.h
ext/date/tests/DateTimeZone_verify.phpt [deleted file]

index 16efa3422216e398b74f9293b78cdd801502c869..fbf725adeeb2407c5bca93274ac8333337d422df 100644 (file)
@@ -85,7 +85,7 @@ typedef struct _zend_fcall_info_cache {
 #define ZEND_DEP_ME(classname, name, arg_info, flags) ZEND_RAW_FENTRY(#name, zim_##classname##_##name, arg_info, flags | ZEND_ACC_DEPRECATED)
 #define ZEND_ABSTRACT_ME(classname, name, arg_info)    ZEND_RAW_FENTRY(#name, NULL, arg_info, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT)
 #define ZEND_MALIAS(classname, name, alias, arg_info, flags) ZEND_RAW_FENTRY(#name, zim_##classname##_##alias, arg_info, flags)
-#define ZEND_ME_MAPPING(name, func_name, arg_types, flags) ZEND_RAW_FENTRY(#name, zif_##func_name, arg_types, flags)
+#define ZEND_ME_MAPPING(name, func_name, arg_info, flags) ZEND_RAW_FENTRY(#name, zif_##func_name, arg_info, flags)
 
 #define ZEND_NS_FENTRY(ns, zend_name, name, arg_info, flags)           ZEND_RAW_FENTRY(ZEND_NS_NAME(ns, #zend_name), name, arg_info, flags)
 
index cfd1d42e36ee2455281dcf0a2e33e35dad65302c..1cbb21d74cc6546e8777dbeff7e5ae7079ba2669 100755 (executable)
@@ -6,6 +6,7 @@ use PhpParser\Node;
 use PhpParser\Node\Expr;
 use PhpParser\Node\Name;
 use PhpParser\Node\Stmt;
+use PhpParser\Node\Stmt\Class_;
 use PhpParser\PrettyPrinter\Standard;
 use PhpParser\PrettyPrinterAbstract;
 
@@ -206,7 +207,7 @@ class Type {
                 $classType = $type;
             } else {
                 // We can only represent a single class type.
-                return false;
+                return null;
             }
         }
         return new RepresentableType($classType, $builtinTypes);
@@ -306,6 +307,33 @@ class ArgInfo {
     }
 }
 
+class FunctionName {
+    /** @var string|null */
+    public $className;
+    /** @var string */
+    public $name;
+
+    public function __construct(?string $className, string $name)
+    {
+        $this->className = $className;
+        $this->name = $name;
+    }
+
+    public function getDeclaration(): string
+    {
+        if ($this->className) {
+            return "ZEND_METHOD($this->className, $this->name);\n";
+        }
+
+        return "ZEND_FUNCTION($this->name);\n";
+    }
+
+    public function __toString()
+    {
+        return $this->className ? "$this->className::$this->name" : $this->name;
+    }
+}
+
 class ReturnInfo {
     /** @var bool */
     public $byRef;
@@ -324,11 +352,11 @@ class ReturnInfo {
 }
 
 class FuncInfo {
-    /** @var string */
+    /** @var FunctionName */
     public $name;
-    /** @var ?string */
-    public $className;
-    /** @var ?string */
+    /** @var int */
+    public $flags;
+    /** @var FunctionName|null */
     public $alias;
     /** @var bool */
     public $isDeprecated;
@@ -342,11 +370,17 @@ class FuncInfo {
     public $cond;
 
     public function __construct(
-        string $name, ?string $className, ?string $alias, bool $isDeprecated, array $args, ReturnInfo $return,
-        int $numRequiredArgs, ?string $cond
+        FunctionName $name,
+        int $flags,
+        ?FunctionName $alias,
+        bool $isDeprecated,
+        array $args,
+        ReturnInfo $return,
+        int $numRequiredArgs,
+        ?string $cond
     ) {
         $this->name = $name;
-        $this->className = $className;
+        $this->flags = $flags;
         $this->alias = $alias;
         $this->isDeprecated = $isDeprecated;
         $this->args = $args;
@@ -372,10 +406,99 @@ class FuncInfo {
     }
 
     public function getArgInfoName(): string {
-        if ($this->className) {
-            return 'arginfo_class_' . $this->className . '_' . $this->name;
+        if ($this->name->className) {
+            return 'arginfo_class_' . $this->name->className . '_' . $this->name->name;
+        }
+        return 'arginfo_' . $this->name->name;
+    }
+
+    public function getDeclarationKey(): string
+    {
+        $name = $this->alias ?? $this->name;
+
+        return "$name|$this->cond";
+    }
+
+    public function getDeclaration(): ?string
+    {
+        if ($this->flags & Class_::MODIFIER_ABSTRACT) {
+            return null;
+        }
+
+        $name = $this->alias ?? $this->name;
+
+        return $name->getDeclaration();
+    }
+
+    public function getFunctionEntry(): string {
+        if ($this->name->className) {
+            if ($this->alias) {
+                if ($this->alias->className) {
+                    return sprintf(
+                        "\tZEND_MALIAS(%s, %s, %s, %s, %s)\n",
+                        $this->alias->className, $this->name, $this->alias->name, $this->getArgInfoName(), $this->getFlagsAsString()
+                    );
+                } else {
+                    return sprintf(
+                        "\tZEND_ME_MAPPING(%s, %s, %s, %s)\n",
+                        $this->name->name, $this->alias->name, $this->getArgInfoName(), $this->getFlagsAsString()
+                    );
+                }
+            } else {
+                if ($this->flags & Class_::MODIFIER_ABSTRACT) {
+                    return sprintf(
+                        "\tZEND_ABSTRACT_ME(%s, %s, %s)\n",
+                        $this->name->className, $this->name->name, $this->getArgInfoName()
+                    );
+                }
+
+                return sprintf(
+                    "\tZEND_ME(%s, %s, %s, %s)\n",
+                    $this->name->className, $this->name->name, $this->getArgInfoName(), $this->getFlagsAsString()
+                );
+            }
+        } else {
+            if ($this->alias) {
+                return sprintf(
+                    "\tZEND_FALIAS(%s, %s, %s)\n",
+                    $this->name, $this->alias->name, $this->getArgInfoName()
+                );
+            }
+
+            if ($this->isDeprecated) {
+                return sprintf("\tZEND_DEP_FE(%s, %s)\n", $this->name, $this->getArgInfoName());
+            }
+
+            return sprintf("\tZEND_FE(%s, %s)\n", $this->name, $this->getArgInfoName());
+        }
+    }
+
+    private function getFlagsAsString(): string
+    {
+        $flags = "ZEND_ACC_PUBLIC";
+        if ($this->flags & Class_::MODIFIER_PROTECTED) {
+            $flags = "ZEND_ACC_PROTECTED";
+        } elseif ($this->flags & Class_::MODIFIER_PRIVATE) {
+            $flags = "ZEND_ACC_PRIVATE";
+        }
+
+        if ($this->flags & Class_::MODIFIER_STATIC) {
+            $flags .= "|ZEND_ACC_STATIC";
+        }
+
+        if ($this->flags & Class_::MODIFIER_FINAL) {
+            $flags .= "|ZEND_ACC_FINAL";
+        }
+
+        if ($this->flags & Class_::MODIFIER_ABSTRACT) {
+            $flags .= "|ZEND_ACC_ABSTRACT";
+        }
+
+        if ($this->isDeprecated) {
+            $flags .= "|ZEND_ACC_DEPRECATED";
         }
-        return 'arginfo_' . $this->name;
+
+        return $flags;
     }
 }
 
@@ -406,6 +529,9 @@ class FileInfo {
         $this->generateFunctionEntries = $generateFunctionEntries;
     }
 
+    /**
+     * @return iterable<FuncInfo>
+     */
     public function getAllFuncInfos(): iterable {
         yield from $this->funcInfos;
         foreach ($this->classInfos as $classInfo) {
@@ -417,7 +543,7 @@ class FileInfo {
 class DocCommentTag {
     /** @var string */
     public $name;
-    /** @var ?string */
+    /** @var string|null */
     public $value;
 
     public function __construct(string $name, ?string $value) {
@@ -458,7 +584,11 @@ function parseDocComment(DocComment $comment): array {
 }
 
 function parseFunctionLike(
-    PrettyPrinterAbstract $prettyPrinter, string $name, ?string $className, Node\FunctionLike $func, ?string $cond
+    PrettyPrinterAbstract $prettyPrinter,
+    FunctionName $name,
+    int $flags,
+    Node\FunctionLike $func,
+    ?string $cond
 ): FuncInfo {
     $comment = $func->getDocComment();
     $paramMeta = [];
@@ -476,7 +606,12 @@ function parseFunctionLike(
                 }
                 $paramMeta[$varName]['preferRef'] = true;
             } else if ($tag->name === 'alias') {
-                $alias = $tag->getValue();
+                $aliasParts = explode("::", $tag->getValue());
+                if (count($aliasParts) === 1) {
+                    $alias = new FunctionName(null, $aliasParts[0]);
+                } else {
+                    $alias = new FunctionName($aliasParts[0], $aliasParts[1]);
+                }
             } else if ($tag->name === 'deprecated') {
                 $isDeprecated = true;
             } else if ($tag->name === 'return') {
@@ -533,14 +668,25 @@ function parseFunctionLike(
     }
 
     $returnType = $func->getReturnType();
-    if ($returnType === null && !$haveDocReturnType && substr($name, 0, 2) !== '__') {
+    if ($returnType === null && !$haveDocReturnType && strpos($name->name, '__') !== 0) {
         throw new Exception("Missing return type for function $name()");
     }
 
     $return = new ReturnInfo(
         $func->returnsByRef(),
-        $returnType ? Type::fromNode($returnType) : null);
-    return new FuncInfo($name, $className, $alias, $isDeprecated, $args, $return, $numRequiredArgs, $cond);
+        $returnType ? Type::fromNode($returnType) : null
+    );
+
+    return new FuncInfo(
+        $name,
+        $flags,
+        $alias,
+        $isDeprecated,
+        $args,
+        $return,
+        $numRequiredArgs,
+        $cond
+    );
 }
 
 function handlePreprocessorConditions(array &$conds, Stmt $stmt): ?string {
@@ -622,7 +768,14 @@ function parseStubFile(string $fileName): FileInfo {
         }
 
         if ($stmt instanceof Stmt\Function_) {
-            $funcInfos[] = parseFunctionLike($prettyPrinter, $stmt->name->toString(), null, $stmt, $cond);
+            $funcInfos[] = parseFunctionLike(
+                $prettyPrinter,
+                new FunctionName(null, $stmt->name->toString()),
+                0,
+                $stmt,
+                $cond
+            );
+
             continue;
         }
 
@@ -639,8 +792,22 @@ function parseStubFile(string $fileName): FileInfo {
                     throw new Exception("Not implemented {$classStmt->getType()}");
                 }
 
+                $flags = $classStmt->flags;
+                if ($stmt instanceof Stmt\Interface_) {
+                    $flags |= Class_::MODIFIER_ABSTRACT;
+                }
+
+                if ($flags & Class_::MODIFIER_ABSTRACT && !($flags & Class_::MODIFIER_PUBLIC)) {
+                    throw new Exception("Abstract non-public methods are not supported");
+                }
+
                 $methodInfos[] = parseFunctionLike(
-                    $prettyPrinter, $classStmt->name->toString(), $className, $classStmt, $cond);
+                    $prettyPrinter,
+                    new FunctionName($className, $classStmt->name->toString()),
+                    $flags,
+                    $classStmt,
+                    $cond
+                );
             }
 
             $classInfos[] = new ClassInfo($className, $methodInfos);
@@ -746,7 +913,8 @@ function funcInfoToCode(FuncInfo $funcInfo): string {
     return $code . "\n";
 }
 
-function findEquivalentFuncInfo(array $generatedFuncInfos, $funcInfo): ?FuncInfo {
+/** @param FuncInfo[] $generatedFuncInfos */
+function findEquivalentFuncInfo(array $generatedFuncInfos, FuncInfo $funcInfo): ?FuncInfo {
     foreach ($generatedFuncInfos as $generatedFuncInfo) {
         if ($generatedFuncInfo->equalsApartFromName($funcInfo)) {
             return $generatedFuncInfo;
@@ -755,7 +923,7 @@ function findEquivalentFuncInfo(array $generatedFuncInfos, $funcInfo): ?FuncInfo
     return null;
 }
 
-/** @param FuncInfo[] $funcInfos */
+/** @param iterable<FuncInfo> $funcInfos */
 function generateCodeWithConditions(
         iterable $funcInfos, string $separator, Closure $codeGenerator): string {
     $code = "";
@@ -778,13 +946,11 @@ function generateCodeWithConditions(
 }
 
 function generateArgInfoCode(FileInfo $fileInfo): string {
-    $funcInfos = $fileInfo->funcInfos;
-
     $code = "/* This is a generated file, edit the .stub.php file instead. */\n";
     $generatedFuncInfos = [];
     $code .= generateCodeWithConditions(
         $fileInfo->getAllFuncInfos(), "\n",
-        function(FuncInfo $funcInfo) use(&$generatedFuncInfos) {
+        function (FuncInfo $funcInfo) use(&$generatedFuncInfos) {
             /* If there already is an equivalent arginfo structure, only emit a #define */
             if ($generatedFuncInfo = findEquivalentFuncInfo($generatedFuncInfos, $funcInfo)) {
                 $code = sprintf(
@@ -802,40 +968,50 @@ function generateArgInfoCode(FileInfo $fileInfo): string {
 
     if ($fileInfo->generateFunctionEntries) {
         $code .= "\n\n";
-        $generatedDeclarations = [];
-        $code .= generateCodeWithConditions($funcInfos, "", function(FuncInfo $funcInfo) use (&$generatedDeclarations) {
-            $name = $funcInfo->alias ?? $funcInfo->name;
-            $key = "$name|$funcInfo->cond";
-            if (isset($generatedDeclarations[$key])) {
-                return null;
-            }
 
-            $generatedDeclarations[$key] = true;
-            return "ZEND_FUNCTION($name);\n";
-        });
+        $generatedFunctionDeclarations = [];
+        $code .= generateCodeWithConditions(
+            $fileInfo->getAllFuncInfos(), "",
+            function (FuncInfo $funcInfo) use(&$generatedFunctionDeclarations) {
+                $key = $funcInfo->getDeclarationKey();
+                if (isset($generatedFunctionDeclarations[$key])) {
+                    return null;
+                }
 
-        $code .= "\n\nstatic const zend_function_entry ext_functions[] = {\n";
-        $code .= generateCodeWithConditions($fileInfo->funcInfos, "", function(FuncInfo $funcInfo) {
-            if ($funcInfo->alias) {
-                return sprintf(
-                    "\tZEND_FALIAS(%s, %s, %s)\n",
-                    $funcInfo->name, $funcInfo->alias, $funcInfo->getArgInfoName()
-                );
-            }
+                $generatedFunctionDeclarations[$key] = true;
 
-            if ($funcInfo->isDeprecated) {
-                return sprintf("\tZEND_DEP_FE(%s, %s)\n", $funcInfo->name, $funcInfo->getArgInfoName());
+                return $funcInfo->getDeclaration();
             }
+        );
 
-            return sprintf("\tZEND_FE(%s, %s)\n", $funcInfo->name, $funcInfo->getArgInfoName());
-        });
-        $code .= "\tZEND_FE_END\n";
-        $code .= "};\n";
+        $code .= "\n\n";
+
+        $code .= generateFunctionEntries(null, $fileInfo->funcInfos);
+
+        foreach ($fileInfo->classInfos as $classInfo) {
+            $code .= generateFunctionEntries($classInfo->name, $classInfo->funcInfos);
+        }
     }
 
     return $code;
 }
 
+/** @param FuncInfo[] $funcInfos */
+function generateFunctionEntries(?string $className, array $funcInfos): string {
+    $code = "";
+
+    $functionEntryName = $className ? "class_{$className}_methods" : "ext_functions";
+
+    $code .= "\n\nstatic const zend_function_entry {$functionEntryName}[] = {\n";
+    $code .= generateCodeWithConditions($funcInfos, "", function (FuncInfo $funcInfo) {
+        return $funcInfo->getFunctionEntry();
+    });
+    $code .= "\tZEND_FE_END\n";
+    $code .= "};\n";
+
+    return $code;
+}
+
 function initPhpParser() {
     $version = "4.3.0";
     $phpParserDir = __DIR__ . "/PHP-Parser-$version";
index 5c6825e50f3c580d089778428ff1eee3f427b624..67a9d66f635db236f8b0d31856b479355f494cb9 100644 (file)
@@ -76,97 +76,6 @@ PHPAPI time_t php_time()
 
 #include "php_date_arginfo.h"
 
-static const zend_function_entry date_funcs_interface[] = {
-       PHP_ABSTRACT_ME(DateTimeInterface, format, arginfo_class_DateTimeInterface_format)
-       PHP_ABSTRACT_ME(DateTimeInterface, getTimezone, arginfo_class_DateTimeInterface_getTimezone)
-       PHP_ABSTRACT_ME(DateTimeInterface, getOffset, arginfo_class_DateTimeInterface_getOffset)
-       PHP_ABSTRACT_ME(DateTimeInterface, getTimestamp, arginfo_class_DateTimeInterface_getTimestamp)
-       PHP_ABSTRACT_ME(DateTimeInterface, diff, arginfo_class_DateTimeInterface_diff)
-       PHP_ABSTRACT_ME(DateTimeInterface, __wakeup, arginfo_class_DateTimeInterface___wakeup)
-       PHP_FE_END
-};
-
-static const zend_function_entry date_funcs_date[] = {
-       PHP_ME(DateTime,                        __construct,            arginfo_class_DateTime___construct, ZEND_ACC_PUBLIC)
-       PHP_ME(DateTime,                        __wakeup,                       arginfo_class_DateTimeInterface___wakeup, ZEND_ACC_PUBLIC)
-       PHP_ME(DateTime,                        __set_state,            arginfo_class_DateTime___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME(DateTime,                        createFromImmutable,    arginfo_class_DateTime_createFromImmutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME(DateTime,                        createFromInterface,    arginfo_class_DateTime_createFromInterface, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME_MAPPING(createFromFormat, date_create_from_format,       arginfo_class_DateTime_createFromFormat, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME_MAPPING(getLastErrors, date_get_last_errors,     arginfo_class_DateTime_getLastErrors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME_MAPPING(format,          date_format,            arginfo_class_DateTimeInterface_format, 0)
-       PHP_ME_MAPPING(modify,          date_modify,            arginfo_class_DateTime_modify, 0)
-       PHP_ME_MAPPING(add,                     date_add,                       arginfo_class_DateTime_add, 0)
-       PHP_ME_MAPPING(sub,                     date_sub,                       arginfo_class_DateTime_sub, 0)
-       PHP_ME_MAPPING(getTimezone, date_timezone_get,  arginfo_class_DateTimeInterface_getTimezone, 0)
-       PHP_ME_MAPPING(setTimezone, date_timezone_set,  arginfo_class_DateTime_setTimezone, 0)
-       PHP_ME_MAPPING(getOffset,       date_offset_get,        arginfo_class_DateTimeInterface_getOffset, 0)
-       PHP_ME_MAPPING(setTime,         date_time_set,          arginfo_class_DateTime_setTime, 0)
-       PHP_ME_MAPPING(setDate,         date_date_set,          arginfo_class_DateTime_setDate, 0)
-       PHP_ME_MAPPING(setISODate,      date_isodate_set,       arginfo_class_DateTime_setISODate, 0)
-       PHP_ME_MAPPING(setTimestamp,    date_timestamp_set, arginfo_class_DateTime_setTimestamp, 0)
-       PHP_ME_MAPPING(getTimestamp,    date_timestamp_get, arginfo_class_DateTimeInterface_getTimestamp, 0)
-       PHP_ME_MAPPING(diff,                    date_diff, arginfo_class_DateTimeInterface_diff, 0)
-       PHP_FE_END
-};
-
-static const zend_function_entry date_funcs_immutable[] = {
-       PHP_ME(DateTimeImmutable, __construct,   arginfo_class_DateTimeImmutable___construct, ZEND_ACC_PUBLIC)
-       PHP_ME(DateTime, __wakeup,       arginfo_class_DateTimeInterface___wakeup, ZEND_ACC_PUBLIC)
-       PHP_ME(DateTimeImmutable, __set_state,   arginfo_class_DateTimeImmutable___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME_MAPPING(createFromFormat, date_create_immutable_from_format, arginfo_class_DateTimeImmutable_createFromFormat, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME_MAPPING(getLastErrors,    date_get_last_errors,    arginfo_class_DateTimeImmutable_getLastErrors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME_MAPPING(format,           date_format,             arginfo_class_DateTimeInterface_format, 0)
-       PHP_ME_MAPPING(getTimezone, date_timezone_get,  arginfo_class_DateTimeInterface_getTimezone, 0)
-       PHP_ME_MAPPING(getOffset,       date_offset_get,        arginfo_class_DateTimeInterface_getOffset, 0)
-       PHP_ME_MAPPING(getTimestamp,    date_timestamp_get, arginfo_class_DateTimeInterface_getTimestamp, 0)
-       PHP_ME_MAPPING(diff,                    date_diff, arginfo_class_DateTimeInterface_diff, 0)
-       PHP_ME(DateTimeImmutable, modify,        arginfo_class_DateTimeImmutable_modify, 0)
-       PHP_ME(DateTimeImmutable, add,           arginfo_class_DateTimeImmutable_add, 0)
-       PHP_ME(DateTimeImmutable, sub,           arginfo_class_DateTimeImmutable_sub, 0)
-       PHP_ME(DateTimeImmutable, setTimezone,   arginfo_class_DateTimeImmutable_setTimezone, 0)
-       PHP_ME(DateTimeImmutable, setTime,       arginfo_class_DateTimeImmutable_setTime, 0)
-       PHP_ME(DateTimeImmutable, setDate,       arginfo_class_DateTimeImmutable_setDate, 0)
-       PHP_ME(DateTimeImmutable, setISODate,    arginfo_class_DateTimeImmutable_setISODate, 0)
-       PHP_ME(DateTimeImmutable, setTimestamp,  arginfo_class_DateTimeImmutable_setTimestamp, 0)
-       PHP_ME(DateTimeImmutable, createFromMutable, arginfo_class_DateTimeImmutable_createFromMutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME(DateTimeImmutable, createFromInterface, arginfo_class_DateTimeImmutable_createFromInterface, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_FE_END
-};
-
-static const zend_function_entry date_funcs_timezone[] = {
-       PHP_ME(DateTimeZone,              __construct,                 arginfo_class_DateTimeZone___construct, ZEND_ACC_PUBLIC)
-       PHP_ME(DateTimeZone,              __wakeup,                    arginfo_class_DateTimeZone___wakeup, ZEND_ACC_PUBLIC)
-       PHP_ME(DateTimeZone,              __set_state,                 arginfo_class_DateTimeZone___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME_MAPPING(getName,           timezone_name_get,           arginfo_class_DateTimeZone_getName, 0)
-       PHP_ME_MAPPING(getOffset,         timezone_offset_get,         arginfo_class_DateTimeZone_getOffset, 0)
-       PHP_ME_MAPPING(getTransitions,    timezone_transitions_get,    arginfo_class_DateTimeZone_getTransitions, 0)
-       PHP_ME_MAPPING(getLocation,       timezone_location_get,       arginfo_class_DateTimeZone_getLocation, 0)
-       PHP_ME_MAPPING(listAbbreviations, timezone_abbreviations_list, arginfo_class_DateTimeZone_listAbbreviations, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME_MAPPING(listIdentifiers,   timezone_identifiers_list,   arginfo_class_DateTimeZone_listIdentifiers, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_FE_END
-};
-
-static const zend_function_entry date_funcs_interval[] = {
-       PHP_ME(DateInterval,              __construct,                 arginfo_class_DateInterval___construct, ZEND_ACC_PUBLIC)
-       PHP_ME(DateInterval,              __wakeup,                    arginfo_class_DateInterval___wakeup, ZEND_ACC_PUBLIC)
-       PHP_ME(DateInterval,              __set_state,                 arginfo_class_DateInterval___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME_MAPPING(format,            date_interval_format,        arginfo_class_DateInterval_format, 0)
-       PHP_ME_MAPPING(createFromDateString, date_interval_create_from_date_string,     arginfo_class_DateInterval_createFromDateString, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_FE_END
-};
-
-static const zend_function_entry date_funcs_period[] = {
-       PHP_ME(DatePeriod,                __construct,                 arginfo_class_DatePeriod___construct, ZEND_ACC_PUBLIC)
-       PHP_ME(DatePeriod,                __wakeup,                    arginfo_class_DatePeriod___wakeup, ZEND_ACC_PUBLIC)
-       PHP_ME(DatePeriod,                __set_state,                 arginfo_class_DatePeriod___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-       PHP_ME(DatePeriod,                getStartDate,                arginfo_class_DatePeriod_getStartDate, ZEND_ACC_PUBLIC)
-       PHP_ME(DatePeriod,                getEndDate,                  arginfo_class_DatePeriod_getEndDate, ZEND_ACC_PUBLIC)
-       PHP_ME(DatePeriod,                getDateInterval,             arginfo_class_DatePeriod_getDateInterval, ZEND_ACC_PUBLIC)
-       PHP_ME(DatePeriod,                getRecurrences,              arginfo_class_DatePeriod_getRecurrences, ZEND_ACC_PUBLIC)
-       PHP_FE_END
-};
-
 static char* guess_timezone(const timelib_tzdb *tzdb);
 static void date_register_classes(void);
 /* }}} */
@@ -1681,7 +1590,7 @@ static void date_register_classes(void) /* {{{ */
 {
        zend_class_entry ce_date, ce_immutable, ce_timezone, ce_interval, ce_period, ce_interface;
 
-       INIT_CLASS_ENTRY(ce_interface, "DateTimeInterface", date_funcs_interface);
+       INIT_CLASS_ENTRY(ce_interface, "DateTimeInterface", class_DateTimeInterface_methods);
        date_ce_interface = zend_register_internal_interface(&ce_interface);
        date_ce_interface->interface_gets_implemented = implement_date_interface_handler;
 
@@ -1702,7 +1611,7 @@ static void date_register_classes(void) /* {{{ */
        REGISTER_DATE_INTERFACE_CONST_STRING("RSS",              DATE_FORMAT_RFC1123);
        REGISTER_DATE_INTERFACE_CONST_STRING("W3C",              DATE_FORMAT_RFC3339);
 
-       INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
+       INIT_CLASS_ENTRY(ce_date, "DateTime", class_DateTime_methods);
        ce_date.create_object = date_object_new_date;
        date_ce_date = zend_register_internal_class_ex(&ce_date, NULL);
        memcpy(&date_object_handlers_date, &std_object_handlers, sizeof(zend_object_handlers));
@@ -1714,7 +1623,7 @@ static void date_register_classes(void) /* {{{ */
        date_object_handlers_date.get_gc = date_object_get_gc;
        zend_class_implements(date_ce_date, 1, date_ce_interface);
 
-       INIT_CLASS_ENTRY(ce_immutable, "DateTimeImmutable", date_funcs_immutable);
+       INIT_CLASS_ENTRY(ce_immutable, "DateTimeImmutable", class_DateTimeImmutable_methods);
        ce_immutable.create_object = date_object_new_date;
        date_ce_immutable = zend_register_internal_class_ex(&ce_immutable, NULL);
        memcpy(&date_object_handlers_immutable, &std_object_handlers, sizeof(zend_object_handlers));
@@ -1724,7 +1633,7 @@ static void date_register_classes(void) /* {{{ */
        date_object_handlers_immutable.get_gc = date_object_get_gc;
        zend_class_implements(date_ce_immutable, 1, date_ce_interface);
 
-       INIT_CLASS_ENTRY(ce_timezone, "DateTimeZone", date_funcs_timezone);
+       INIT_CLASS_ENTRY(ce_timezone, "DateTimeZone", class_DateTimeZone_methods);
        ce_timezone.create_object = date_object_new_timezone;
        date_ce_timezone = zend_register_internal_class_ex(&ce_timezone, NULL);
        memcpy(&date_object_handlers_timezone, &std_object_handlers, sizeof(zend_object_handlers));
@@ -1754,7 +1663,7 @@ static void date_register_classes(void) /* {{{ */
        REGISTER_TIMEZONE_CLASS_CONST_STRING("ALL_WITH_BC", PHP_DATE_TIMEZONE_GROUP_ALL_W_BC);
        REGISTER_TIMEZONE_CLASS_CONST_STRING("PER_COUNTRY", PHP_DATE_TIMEZONE_PER_COUNTRY);
 
-       INIT_CLASS_ENTRY(ce_interval, "DateInterval", date_funcs_interval);
+       INIT_CLASS_ENTRY(ce_interval, "DateInterval", class_DateInterval_methods);
        ce_interval.create_object = date_object_new_interval;
        date_ce_interval = zend_register_internal_class_ex(&ce_interval, NULL);
        memcpy(&date_object_handlers_interval, &std_object_handlers, sizeof(zend_object_handlers));
@@ -1769,7 +1678,7 @@ static void date_register_classes(void) /* {{{ */
        date_object_handlers_interval.get_gc = date_object_get_gc_interval;
        date_object_handlers_interval.compare = date_interval_compare_objects;
 
-       INIT_CLASS_ENTRY(ce_period, "DatePeriod", date_funcs_period);
+       INIT_CLASS_ENTRY(ce_period, "DatePeriod", class_DatePeriod_methods);
        ce_period.create_object = date_object_new_period;
        date_ce_period = zend_register_internal_class_ex(&ce_period, NULL);
        date_ce_period->get_iterator = date_object_period_get_iterator;
@@ -2691,6 +2600,26 @@ PHP_METHOD(DateTime, __wakeup)
 }
 /* }}} */
 
+/* {{{ proto DateTimeImmutable::__wakeup()
+*/
+PHP_METHOD(DateTimeImmutable, __wakeup)
+{
+       zval             *object = ZEND_THIS;
+       php_date_obj     *dateobj;
+       HashTable        *myht;
+
+       ZEND_PARSE_PARAMETERS_NONE();
+
+       dateobj = Z_PHPDATE_P(object);
+
+       myht = Z_OBJPROP_P(object);
+
+       if (!php_date_initialize_from_hash(&dateobj, myht)) {
+               zend_throw_error(NULL, "Invalid serialization data for DateTimeImmutable object");
+       }
+}
+/* }}} */
+
 /* Helper function used to add an associative array of warnings and errors to a zval */
 static void zval_from_error_container(zval *z, timelib_error_container *error) /* {{{ */
 {
index e3008e47e01b0d6f2fe205c9465b466170b285aa..871114c44b0d4852ea1c4f4488954b3f9d321fdb 100644 (file)
 extern zend_module_entry date_module_entry;
 #define phpext_date_ptr &date_module_entry
 
-/* Advanced Interface */
-PHP_METHOD(DateTime, __construct);
-PHP_METHOD(DateTime, __wakeup);
-PHP_METHOD(DateTime, __set_state);
-PHP_METHOD(DateTime, createFromImmutable);
-PHP_METHOD(DateTime, createFromInterface);
-
-PHP_METHOD(DateTimeImmutable, __construct);
-PHP_METHOD(DateTimeImmutable, __set_state);
-PHP_METHOD(DateTimeImmutable, modify);
-PHP_METHOD(DateTimeImmutable, add);
-PHP_METHOD(DateTimeImmutable, sub);
-PHP_METHOD(DateTimeImmutable, setTimezone);
-PHP_METHOD(DateTimeImmutable, setTime);
-PHP_METHOD(DateTimeImmutable, setDate);
-PHP_METHOD(DateTimeImmutable, setISODate);
-PHP_METHOD(DateTimeImmutable, setTimestamp);
-PHP_METHOD(DateTimeImmutable, createFromMutable);
-PHP_METHOD(DateTimeImmutable, createFromInterface);
-
-PHP_METHOD(DateTimeZone, __construct);
-PHP_METHOD(DateTimeZone, __wakeup);
-PHP_METHOD(DateTimeZone, __set_state);
-
-PHP_METHOD(DateInterval, __construct);
-PHP_METHOD(DateInterval, __wakeup);
-PHP_METHOD(DateInterval, __set_state);
-PHP_FUNCTION(date_interval_format);
-PHP_FUNCTION(date_interval_create_from_date_string);
-
-PHP_METHOD(DatePeriod, __construct);
-PHP_METHOD(DatePeriod, __wakeup);
-PHP_METHOD(DatePeriod, __set_state);
-PHP_METHOD(DatePeriod, getStartDate);
-PHP_METHOD(DatePeriod, getEndDate);
-PHP_METHOD(DatePeriod, getDateInterval);
-PHP_METHOD(DatePeriod, getRecurrences);
-
 PHP_RINIT_FUNCTION(date);
 PHP_RSHUTDOWN_FUNCTION(date);
 PHP_MINIT_FUNCTION(date);
index 23936a9d487a1342d012257e6fa5d0a2aeb6df3f..533eb455feb23e283f855cc0ca79f83b51fcdfcd 100644 (file)
@@ -117,7 +117,8 @@ function date_sun_info(int $time, float $latitude, float $longitude): array {}
 // NB: Adding return types to methods is a BC break!
 // For now only using @return annotations here.
 
-interface DateTimeInterface {
+interface DateTimeInterface
+{
     /** @return string */
     public function format(string $format);
 
@@ -136,153 +137,279 @@ interface DateTimeInterface {
     public function __wakeup();
 }
 
-class DateTime implements DateTimeInterface {
-    public function __construct(string $time = "now", ?DateTimeZone $timezone = null);
+class DateTime implements DateTimeInterface
+{
+    public function __construct(string $time = "now", ?DateTimeZone $timezone = null) {}
 
-    /** @return DateTime */
-    public static function __set_state(array $array);
-
-    /** @return DateTime */
-    public static function createFromImmutable(DateTimeImmutable $object);
-
-    public static function createFromInterface(DateTimeInterface $object): DateTime;
-
-    /** @return DateTime|false */
-    public static function createFromFormat(
-        string $format, string $time, ?DateTimeZone $timezone = null);
-
-    /** @return array|false */
-    public static function getLastErrors();
-
-    /** @return DateTime|false */
-    public function modify(string $modify);
-
-    /** @return DateTime */
-    public function add(DateInterval $interval);
-
-    /** @return DateTime */
-    public function sub(DateInterval $interval);
-
-    /** @return DateTime */
-    public function setTimezone(DateTimeZone $timezone);
-
-    /** @return DateTime */
-    public function setTime(int $hour, int $minute, int $second = 0, int $microseconds = 0);
+    public function __wakeup() {}
 
     /** @return DateTime */
-    public function setDate(int $year, int $month, int $day);
+    public static function __set_state(array $array) {}
 
     /** @return DateTime */
-    public function setISODate(int $year, int $week, int $day = 1);
-
-    /** @return DateTime */
-    public function setTimestamp(int $timestamp);
+    public static function createFromImmutable(DateTimeImmutable $object) {}
+
+    public static function createFromInterface(DateTimeInterface $object): DateTime {}
+
+    /**
+     * @return DateTime|false
+     * @alias date_create_from_format
+     */
+    public static function createFromFormat(string $format, string $time, ?DateTimeZone $timezone = null) {}
+
+    /**
+     * @return array|false
+     * @alias date_get_last_errors
+     */
+    public static function getLastErrors() {}
+
+    /**
+     * @return string
+     * @alias date_format
+     */
+    public function format(string $format) {}
+
+    /**
+     * @return DateTime|false
+     * @alias date_modify
+     */
+    public function modify(string $modify) {}
+
+    /**
+     * @return DateTime
+     * @alias date_add
+     */
+    public function add(DateInterval $interval) {}
+
+    /**
+     * @return DateTime
+     * @alias date_sub
+     */
+    public function sub(DateInterval $interval) {}
+
+    /**
+     * @return DateTimeZone|false
+     * @alias date_timezone_get
+     */
+    public function getTimezone() {}
+
+    /**
+     * @return DateTime
+     * @alias date_timezone_set
+     */
+    public function setTimezone(DateTimeZone $timezone) {}
+
+    /**
+     * @return int|false
+     * @alias date_offset_get
+     */
+    public function getOffset() {}
+
+    /**
+     * @return DateTime
+     * @alias date_time_set
+     */
+    public function setTime(int $hour, int $minute, int $second = 0, int $microseconds = 0) {}
+
+    /**
+     * @return DateTime
+     * @alias date_date_set
+     */
+    public function setDate(int $year, int $month, int $day) {}
+
+    /**
+     * @return DateTime
+     * @alias date_isodate_set
+     */
+    public function setISODate(int $year, int $week, int $day = 1) {}
+
+    /**
+     * @return DateTime
+     * @alias date_timestamp_set
+     */
+    public function setTimestamp(int $timestamp) {}
+
+    /**
+     * @return int|false
+     * @alias date_timestamp_get
+     */
+    public function getTimestamp() {}
+
+    /**
+     * @return DateInterval|false
+     * @alias date_diff
+     */
+    public function diff(DateTimeInterface $object, bool $absolute = false) {}
 }
 
-class DateTimeImmutable implements DateTimeInterface {
-    public function __construct(string $time = "now", ?DateTimeZone $timezone = null);
+class DateTimeImmutable implements DateTimeInterface
+{
+    public function __construct(string $time = "now", ?DateTimeZone $timezone = null) {}
 
-    /** @return DateTimeZone */
-    public static function __set_state(array $array);
-
-    /** @return DateTimeImmutable */
-    public static function createFromMutable(DateTime $object);
+    public function __wakeup() {}
 
-    public static function createFromInterface(DateTimeInterface $object): DateTimeImmutable;
-
-    /** @return DateTimeImmutable|false */
-    public static function createFromFormat(
-        string $format, string $time, ?DateTimeZone $timezone = null);
-
-    /** @return array|false */
-    public static function getLastErrors();
+    /** @return DateTimeZone */
+    public static function __set_state(array $array) {}
+
+    /**
+     * @return DateTimeImmutable|false
+     * @alias date_create_immutable_from_format
+     */
+    public static function createFromFormat(string $format, string $time, ?DateTimeZone $timezone = null) {}
+
+    /**
+     * @return array|false
+     * @alias date_get_last_errors
+     */
+    public static function getLastErrors() {}
+
+    /**
+     * @return string
+     * @alias date_format
+     */
+    public function format(string $format) {}
+
+    /**
+     * @return DateTimeZone|false
+     * @alias date_timezone_get
+     */
+    public function getTimezone() {}
+
+    /**
+     * @return int|false
+     * @alias date_offset_get
+     */
+    public function getOffset() {}
+
+    /**
+     * @return int|false
+     * @alias date_timestamp_get
+     */
+    public function getTimestamp() {}
+
+    /**
+     * @return DateInterval|false
+     * @alias date_diff
+     */
+    public function diff(DateTimeInterface $object, bool $absolute = false) {}
 
     /** @return DateTimeImmutable|false */
-    public function modify(string $modify);
+    public function modify(string $modify) {}
 
     /** @return DateTimeImmutable */
-    public function add(DateInterval $interval);
+    public function add(DateInterval $interval) {}
 
     /** @return DateTimeImmutable */
-    public function sub(DateInterval $interval);
+    public function sub(DateInterval $interval) {}
 
     /** @return DateTimeImmutable */
-    public function setTimezone(DateTimeZone $timezone);
+    public function setTimezone(DateTimeZone $timezone) {}
 
     /** @return DateTimeImmutable */
-    public function setTime(int $hour, int $minute, int $second = 0, int $microseconds = 0);
+    public function setTime(int $hour, int $minute, int $second = 0, int $microseconds = 0) {}
 
     /** @return DateTimeImmutable */
-    public function setDate(int $year, int $month, int $day);
+    public function setDate(int $year, int $month, int $day) {}
 
     /** @return DateTimeImmutable */
-    public function setISODate(int $year, int $week, int $day = 1);
+    public function setISODate(int $year, int $week, int $day = 1) {}
 
     /** @return DateTimeImmutable */
-    public function setTimestamp(int $timestamp);
-}
-
-class DateTimeZone {
-    public function __construct(string $timezone);
-
-    /** @return string */
-    public function getName();
-
-    /** @return int */
-    public function getOffset(DateTimeInterface $datetime);
-
-    /** @return array|false */
-    public function getTransitions(
-        int $timestamp_begin = PHP_INT_MIN, int $timestamp_end = PHP_INT_MAX);
+    public function setTimestamp(int $timestamp) {}
 
-    /** @return array|false */
-    public function getLocation();
+    /** @return DateTimeImmutable */
+    public static function createFromMutable(DateTime $object) {}
 
-    /** @return array */
-    public static function listAbbreviations();
+    public static function createFromInterface(DateTimeInterface $object): DateTimeImmutable {}
+}
 
-    /** @return array|false */
-    public static function listIdentifiers(int $what = DateTimeZone::ALL, ?string $country = null);
-
-    public function __wakeup();
+class DateTimeZone
+{
+    public function __construct(string $timezone) {}
+
+    /**
+     * @return string
+     * @alias timezone_name_get
+     */
+    public function getName() {}
+
+    /**
+     * @return int
+     * @alias timezone_offset_get
+     */
+    public function getOffset(DateTimeInterface $datetime) {}
+
+    /**
+     * @return array|false
+     * @alias timezone_transitions_get
+     */
+    public function getTransitions(int $timestamp_begin = PHP_INT_MIN, int $timestamp_end = PHP_INT_MAX) {}
+
+    /**
+     * @return array|false
+     * @alias timezone_location_get
+     */
+    public function getLocation() {}
+
+    /**
+     * @return array
+     * @alias timezone_abbreviations_list
+     */
+    public static function listAbbreviations() {}
+
+    /**
+     * @return array|false
+     * @alias timezone_identifiers_list
+     */
+    public static function listIdentifiers(int $what = DateTimeZone::ALL, ?string $country = null) {}
+
+    public function __wakeup() {}
 
     /** @return DateTimeZone */
-    public static function __set_state(array $array);
+    public static function __set_state(array $array) {}
 }
 
-class DateInterval {
-    public function __construct(string $interval_spec);
+class DateInterval
+{
+    public function __construct(string $interval_spec) {}
 
-    /** @return DateInterval|false */
-    public static function createFromDateString(string $time);
+    /**
+     * @return DateInterval|false
+     * @alias date_interval_create_from_date_string
+     */
+    public static function createFromDateString(string $time) {}
 
-    /** @return string */
-    public function format(string $format);
+    /**
+     * @return string
+     * @alias date_interval_format
+     */
+    public function format(string $format) {}
 
-    public function __wakeup();
+    public function __wakeup() {}
 
     /** @return DateInterval */
-    public static function __set_state(array $array);
+    public static function __set_state(array $array) {}
 }
 
-class DatePeriod implements Traversable {
+class DatePeriod implements Traversable
+{
     /* Has an overloaded signature */
-    public function __construct($start, $interval = UNKNOWN, $end = UNKNOWN);
+    public function __construct($start, $interval = UNKNOWN, $end = UNKNOWN) {}
 
     /** @return DateTimeInterface */
-    public function getStartDate();
+    public function getStartDate() {}
 
     /** @return DateTimeInterface|null */
-    public function getEndDate();
+    public function getEndDate() {}
 
     /** @return DateInterval */
-    public function getDateInterval();
+    public function getDateInterval() {}
 
     /** @return int|null */
-    public function getRecurrences();
+    public function getRecurrences() {}
 
-    public function __wakeup();
+    public function __wakeup() {}
 
     /** @return DatePeriod */
-    public static function __set_state(array $array);
+    public static function __set_state(array $array) {}
 }
index 1cc39b228857fec2488121d5286e91adb4cdc915..29646d081c3947dc9d8fbb203cfd2f705b4d89bc 100644 (file)
@@ -249,6 +249,8 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime___construct, 0, 0, 0)
        ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null")
 ZEND_END_ARG_INFO()
 
+#define arginfo_class_DateTime___wakeup arginfo_class_DateTimeInterface_getTimezone
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime___set_state, 0, 0, 1)
        ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0)
 ZEND_END_ARG_INFO()
@@ -269,6 +271,8 @@ ZEND_END_ARG_INFO()
 
 #define arginfo_class_DateTime_getLastErrors arginfo_class_DateTimeInterface_getTimezone
 
+#define arginfo_class_DateTime_format arginfo_class_DateTimeInterface_format
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_modify, 0, 0, 1)
        ZEND_ARG_TYPE_INFO(0, modify, IS_STRING, 0)
 ZEND_END_ARG_INFO()
@@ -279,10 +283,14 @@ ZEND_END_ARG_INFO()
 
 #define arginfo_class_DateTime_sub arginfo_class_DateTime_add
 
+#define arginfo_class_DateTime_getTimezone arginfo_class_DateTimeInterface_getTimezone
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_setTimezone, 0, 0, 1)
        ZEND_ARG_OBJ_INFO(0, timezone, DateTimeZone, 0)
 ZEND_END_ARG_INFO()
 
+#define arginfo_class_DateTime_getOffset arginfo_class_DateTimeInterface_getTimezone
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_setTime, 0, 0, 2)
        ZEND_ARG_TYPE_INFO(0, hour, IS_LONG, 0)
        ZEND_ARG_TYPE_INFO(0, minute, IS_LONG, 0)
@@ -306,22 +314,30 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_setTimestamp, 0, 0, 1)
        ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
 ZEND_END_ARG_INFO()
 
-#define arginfo_class_DateTimeImmutable___construct arginfo_class_DateTime___construct
+#define arginfo_class_DateTime_getTimestamp arginfo_class_DateTimeInterface_getTimezone
 
-#define arginfo_class_DateTimeImmutable___set_state arginfo_class_DateTime___set_state
+#define arginfo_class_DateTime_diff arginfo_class_DateTimeInterface_diff
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeImmutable_createFromMutable, 0, 0, 1)
-       ZEND_ARG_OBJ_INFO(0, object, DateTime, 0)
-ZEND_END_ARG_INFO()
+#define arginfo_class_DateTimeImmutable___construct arginfo_class_DateTime___construct
 
-ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable_createFromInterface, 0, 1, DateTimeImmutable, 0)
-       ZEND_ARG_OBJ_INFO(0, object, DateTimeInterface, 0)
-ZEND_END_ARG_INFO()
+#define arginfo_class_DateTimeImmutable___wakeup arginfo_class_DateTimeInterface_getTimezone
+
+#define arginfo_class_DateTimeImmutable___set_state arginfo_class_DateTime___set_state
 
 #define arginfo_class_DateTimeImmutable_createFromFormat arginfo_class_DateTime_createFromFormat
 
 #define arginfo_class_DateTimeImmutable_getLastErrors arginfo_class_DateTimeInterface_getTimezone
 
+#define arginfo_class_DateTimeImmutable_format arginfo_class_DateTimeInterface_format
+
+#define arginfo_class_DateTimeImmutable_getTimezone arginfo_class_DateTimeInterface_getTimezone
+
+#define arginfo_class_DateTimeImmutable_getOffset arginfo_class_DateTimeInterface_getTimezone
+
+#define arginfo_class_DateTimeImmutable_getTimestamp arginfo_class_DateTimeInterface_getTimezone
+
+#define arginfo_class_DateTimeImmutable_diff arginfo_class_DateTimeInterface_diff
+
 #define arginfo_class_DateTimeImmutable_modify arginfo_class_DateTime_modify
 
 #define arginfo_class_DateTimeImmutable_add arginfo_class_DateTime_add
@@ -338,6 +354,14 @@ ZEND_END_ARG_INFO()
 
 #define arginfo_class_DateTimeImmutable_setTimestamp arginfo_class_DateTime_setTimestamp
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeImmutable_createFromMutable, 0, 0, 1)
+       ZEND_ARG_OBJ_INFO(0, object, DateTime, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable_createFromInterface, 0, 1, DateTimeImmutable, 0)
+       ZEND_ARG_OBJ_INFO(0, object, DateTimeInterface, 0)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeZone___construct, 0, 0, 1)
        ZEND_ARG_TYPE_INFO(0, timezone, IS_STRING, 0)
 ZEND_END_ARG_INFO()
@@ -447,6 +471,39 @@ ZEND_FUNCTION(date_default_timezone_get);
 ZEND_FUNCTION(date_sunrise);
 ZEND_FUNCTION(date_sunset);
 ZEND_FUNCTION(date_sun_info);
+ZEND_METHOD(DateTime, __construct);
+ZEND_METHOD(DateTime, __wakeup);
+ZEND_METHOD(DateTime, __set_state);
+ZEND_METHOD(DateTime, createFromImmutable);
+ZEND_METHOD(DateTime, createFromInterface);
+ZEND_METHOD(DateTimeImmutable, __construct);
+ZEND_METHOD(DateTimeImmutable, __wakeup);
+ZEND_METHOD(DateTimeImmutable, __set_state);
+ZEND_METHOD(DateTimeImmutable, modify);
+ZEND_METHOD(DateTimeImmutable, add);
+ZEND_METHOD(DateTimeImmutable, sub);
+ZEND_METHOD(DateTimeImmutable, setTimezone);
+ZEND_METHOD(DateTimeImmutable, setTime);
+ZEND_METHOD(DateTimeImmutable, setDate);
+ZEND_METHOD(DateTimeImmutable, setISODate);
+ZEND_METHOD(DateTimeImmutable, setTimestamp);
+ZEND_METHOD(DateTimeImmutable, createFromMutable);
+ZEND_METHOD(DateTimeImmutable, createFromInterface);
+ZEND_METHOD(DateTimeZone, __construct);
+ZEND_METHOD(DateTimeZone, __wakeup);
+ZEND_METHOD(DateTimeZone, __set_state);
+ZEND_METHOD(DateInterval, __construct);
+ZEND_METHOD(DateInterval, __wakeup);
+ZEND_METHOD(DateInterval, __set_state);
+ZEND_METHOD(DatePeriod, __construct);
+ZEND_METHOD(DatePeriod, getStartDate);
+ZEND_METHOD(DatePeriod, getEndDate);
+ZEND_METHOD(DatePeriod, getDateInterval);
+ZEND_METHOD(DatePeriod, getRecurrences);
+ZEND_METHOD(DatePeriod, __wakeup);
+ZEND_METHOD(DatePeriod, __set_state);
+
+
 
 
 static const zend_function_entry ext_functions[] = {
@@ -500,3 +557,100 @@ static const zend_function_entry ext_functions[] = {
        ZEND_FE(date_sun_info, arginfo_date_sun_info)
        ZEND_FE_END
 };
+
+
+static const zend_function_entry class_DateTimeInterface_methods[] = {
+       ZEND_ABSTRACT_ME(DateTimeInterface, format, arginfo_class_DateTimeInterface_format)
+       ZEND_ABSTRACT_ME(DateTimeInterface, getTimezone, arginfo_class_DateTimeInterface_getTimezone)
+       ZEND_ABSTRACT_ME(DateTimeInterface, getOffset, arginfo_class_DateTimeInterface_getOffset)
+       ZEND_ABSTRACT_ME(DateTimeInterface, getTimestamp, arginfo_class_DateTimeInterface_getTimestamp)
+       ZEND_ABSTRACT_ME(DateTimeInterface, diff, arginfo_class_DateTimeInterface_diff)
+       ZEND_ABSTRACT_ME(DateTimeInterface, __wakeup, arginfo_class_DateTimeInterface___wakeup)
+       ZEND_FE_END
+};
+
+
+static const zend_function_entry class_DateTime_methods[] = {
+       ZEND_ME(DateTime, __construct, arginfo_class_DateTime___construct, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTime, __wakeup, arginfo_class_DateTime___wakeup, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTime, __set_state, arginfo_class_DateTime___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME(DateTime, createFromImmutable, arginfo_class_DateTime_createFromImmutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME(DateTime, createFromInterface, arginfo_class_DateTime_createFromInterface, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME_MAPPING(createFromFormat, date_create_from_format, arginfo_class_DateTime_createFromFormat, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_class_DateTime_getLastErrors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME_MAPPING(format, date_format, arginfo_class_DateTime_format, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(modify, date_modify, arginfo_class_DateTime_modify, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(add, date_add, arginfo_class_DateTime_add, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(sub, date_sub, arginfo_class_DateTime_sub, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(getTimezone, date_timezone_get, arginfo_class_DateTime_getTimezone, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(setTimezone, date_timezone_set, arginfo_class_DateTime_setTimezone, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(getOffset, date_offset_get, arginfo_class_DateTime_getOffset, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(setTime, date_time_set, arginfo_class_DateTime_setTime, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(setDate, date_date_set, arginfo_class_DateTime_setDate, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(setISODate, date_isodate_set, arginfo_class_DateTime_setISODate, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(setTimestamp, date_timestamp_set, arginfo_class_DateTime_setTimestamp, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(getTimestamp, date_timestamp_get, arginfo_class_DateTime_getTimestamp, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(diff, date_diff, arginfo_class_DateTime_diff, ZEND_ACC_PUBLIC)
+       ZEND_FE_END
+};
+
+
+static const zend_function_entry class_DateTimeImmutable_methods[] = {
+       ZEND_ME(DateTimeImmutable, __construct, arginfo_class_DateTimeImmutable___construct, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeImmutable, __wakeup, arginfo_class_DateTimeImmutable___wakeup, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeImmutable, __set_state, arginfo_class_DateTimeImmutable___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME_MAPPING(createFromFormat, date_create_immutable_from_format, arginfo_class_DateTimeImmutable_createFromFormat, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_class_DateTimeImmutable_getLastErrors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME_MAPPING(format, date_format, arginfo_class_DateTimeImmutable_format, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(getTimezone, date_timezone_get, arginfo_class_DateTimeImmutable_getTimezone, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(getOffset, date_offset_get, arginfo_class_DateTimeImmutable_getOffset, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(getTimestamp, date_timestamp_get, arginfo_class_DateTimeImmutable_getTimestamp, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(diff, date_diff, arginfo_class_DateTimeImmutable_diff, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeImmutable, modify, arginfo_class_DateTimeImmutable_modify, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeImmutable, add, arginfo_class_DateTimeImmutable_add, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeImmutable, sub, arginfo_class_DateTimeImmutable_sub, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeImmutable, setTimezone, arginfo_class_DateTimeImmutable_setTimezone, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeImmutable, setTime, arginfo_class_DateTimeImmutable_setTime, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeImmutable, setDate, arginfo_class_DateTimeImmutable_setDate, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeImmutable, setISODate, arginfo_class_DateTimeImmutable_setISODate, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeImmutable, setTimestamp, arginfo_class_DateTimeImmutable_setTimestamp, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeImmutable, createFromMutable, arginfo_class_DateTimeImmutable_createFromMutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME(DateTimeImmutable, createFromInterface, arginfo_class_DateTimeImmutable_createFromInterface, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_FE_END
+};
+
+
+static const zend_function_entry class_DateTimeZone_methods[] = {
+       ZEND_ME(DateTimeZone, __construct, arginfo_class_DateTimeZone___construct, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(getName, timezone_name_get, arginfo_class_DateTimeZone_getName, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(getOffset, timezone_offset_get, arginfo_class_DateTimeZone_getOffset, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(getTransitions, timezone_transitions_get, arginfo_class_DateTimeZone_getTransitions, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(getLocation, timezone_location_get, arginfo_class_DateTimeZone_getLocation, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(listAbbreviations, timezone_abbreviations_list, arginfo_class_DateTimeZone_listAbbreviations, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME_MAPPING(listIdentifiers, timezone_identifiers_list, arginfo_class_DateTimeZone_listIdentifiers, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME(DateTimeZone, __wakeup, arginfo_class_DateTimeZone___wakeup, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateTimeZone, __set_state, arginfo_class_DateTimeZone___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_FE_END
+};
+
+
+static const zend_function_entry class_DateInterval_methods[] = {
+       ZEND_ME(DateInterval, __construct, arginfo_class_DateInterval___construct, ZEND_ACC_PUBLIC)
+       ZEND_ME_MAPPING(createFromDateString, date_interval_create_from_date_string, arginfo_class_DateInterval_createFromDateString, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_ME_MAPPING(format, date_interval_format, arginfo_class_DateInterval_format, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateInterval, __wakeup, arginfo_class_DateInterval___wakeup, ZEND_ACC_PUBLIC)
+       ZEND_ME(DateInterval, __set_state, arginfo_class_DateInterval___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_FE_END
+};
+
+
+static const zend_function_entry class_DatePeriod_methods[] = {
+       ZEND_ME(DatePeriod, __construct, arginfo_class_DatePeriod___construct, ZEND_ACC_PUBLIC)
+       ZEND_ME(DatePeriod, getStartDate, arginfo_class_DatePeriod_getStartDate, ZEND_ACC_PUBLIC)
+       ZEND_ME(DatePeriod, getEndDate, arginfo_class_DatePeriod_getEndDate, ZEND_ACC_PUBLIC)
+       ZEND_ME(DatePeriod, getDateInterval, arginfo_class_DatePeriod_getDateInterval, ZEND_ACC_PUBLIC)
+       ZEND_ME(DatePeriod, getRecurrences, arginfo_class_DatePeriod_getRecurrences, ZEND_ACC_PUBLIC)
+       ZEND_ME(DatePeriod, __wakeup, arginfo_class_DatePeriod___wakeup, ZEND_ACC_PUBLIC)
+       ZEND_ME(DatePeriod, __set_state, arginfo_class_DatePeriod___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       ZEND_FE_END
+};
diff --git a/ext/date/tests/DateTimeZone_verify.phpt b/ext/date/tests/DateTimeZone_verify.phpt
deleted file mode 100644 (file)
index 0787d11..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
---TEST--
-Test DateTimeZone class registration
---FILE--
-<?php
-
-echo "*** Verify DateTimeZone class ***\n";
-
-echo "Verify DateTimeZone class registered OK\n";
-$class = new ReflectionClass('DateTimeZone');
-var_dump($class);
-
-echo "..and get names of all its methods\n";
-$methods = $class->getMethods();
-var_dump($methods);
-
-echo "..and get names of all its class constants\n";
-$constants = $class->getConstants();
-var_dump($constants);
-?>
---EXPECTF--
-*** Verify DateTimeZone class ***
-Verify DateTimeZone class registered OK
-object(ReflectionClass)#%d (1) {
-  ["name"]=>
-  string(12) "DateTimeZone"
-}
-..and get names of all its methods
-array(9) {
-  [0]=>
-  object(ReflectionMethod)#%d (2) {
-    ["name"]=>
-    string(11) "__construct"
-    ["class"]=>
-    string(12) "DateTimeZone"
-  }
-  [1]=>
-  object(ReflectionMethod)#%d (2) {
-    ["name"]=>
-    string(8) "__wakeup"
-    ["class"]=>
-    string(12) "DateTimeZone"
-  }
-  [2]=>
-  object(ReflectionMethod)#%d (2) {
-    ["name"]=>
-    string(11) "__set_state"
-    ["class"]=>
-    string(12) "DateTimeZone"
-  }
-  [3]=>
-  object(ReflectionMethod)#%d (2) {
-    ["name"]=>
-    string(7) "getName"
-    ["class"]=>
-    string(12) "DateTimeZone"
-  }
-  [4]=>
-  object(ReflectionMethod)#%d (2) {
-    ["name"]=>
-    string(9) "getOffset"
-    ["class"]=>
-    string(12) "DateTimeZone"
-  }
-  [5]=>
-  object(ReflectionMethod)#%d (2) {
-    ["name"]=>
-    string(14) "getTransitions"
-    ["class"]=>
-    string(12) "DateTimeZone"
-  }
-  [6]=>
-  object(ReflectionMethod)#%d (2) {
-    ["name"]=>
-    string(11) "getLocation"
-    ["class"]=>
-    string(12) "DateTimeZone"
-  }
-  [7]=>
-  object(ReflectionMethod)#%d (2) {
-    ["name"]=>
-    string(17) "listAbbreviations"
-    ["class"]=>
-    string(12) "DateTimeZone"
-  }
-  [8]=>
-  object(ReflectionMethod)#%d (2) {
-    ["name"]=>
-    string(15) "listIdentifiers"
-    ["class"]=>
-    string(12) "DateTimeZone"
-  }
-}
-..and get names of all its class constants
-array(14) {
-  ["AFRICA"]=>
-  int(1)
-  ["AMERICA"]=>
-  int(2)
-  ["ANTARCTICA"]=>
-  int(4)
-  ["ARCTIC"]=>
-  int(8)
-  ["ASIA"]=>
-  int(16)
-  ["ATLANTIC"]=>
-  int(32)
-  ["AUSTRALIA"]=>
-  int(64)
-  ["EUROPE"]=>
-  int(128)
-  ["INDIAN"]=>
-  int(256)
-  ["PACIFIC"]=>
-  int(512)
-  ["UTC"]=>
-  int(1024)
-  ["ALL"]=>
-  int(2047)
-  ["ALL_WITH_BC"]=>
-  int(4095)
-  ["PER_COUNTRY"]=>
-  int(4096)
-}