function extract_class_signatures($files, $extensions) { $class_signatures = array(); $interface_signatures = array(); foreach ($files as $file) { $doc = new DOMDocument(); $doc->loadHTMLFile($file); $xpath = new DOMXpath($doc); list($classname, $is_interface) = extract_class_name($xpath, $file); if (empty($classname)) { // no usual class synopsis found inside the file, just skip this class continue; } $fields = extract_class_fields($xpath, $classname, $file); $methods = extract_class_methods($xpath, $classname, $file); $extension_name = get_extension_name($file, $extensions); if (!isset($class_signatures[$extension_name][$classname])) { if ($is_interface) { if (!isset($interface_signatures[$extension_name])) { $interface_signatures[$extension_name] = array(); } $interface_signatures[$extension_name][$classname] = array('constants' => $fields['constants'], 'properties' => $fields['properties'], 'static_properties' => $fields['static_properties'], 'methods' => $methods['methods'], 'static_methods' => $methods['static_methods']); } else { if (!isset($class_signatures[$extension_name])) { $class_signatures[$extension_name] = array(); } $class_signatures[$extension_name][$classname] = array('constants' => $fields['constants'], 'properties' => $fields['properties'], 'static_properties' => $fields['static_properties'], 'methods' => $methods['methods'], 'static_methods' => $methods['static_methods']); } } else { // there are some duplicate class names in extensions, use only the first one } } return array($class_signatures, $interface_signatures); }
function extract_function_signatures($files, $extensions, $signatures = array()) { foreach ($files as $file) { $extension_name = get_extension_name($file, $extensions); if (!isset($signatures[$extension_name])) { $signatures[$extension_name] = array(); } $doc = new DOMDocument(); $doc->loadHTMLFile($file); $xpath = new DOMXpath($doc); $nodes = $xpath->query('//div[contains(@class, "methodsynopsis")]'); if ($nodes->length == 0) { // no signature found, maybe its an alias? $nodes = $xpath->query('//div[contains(@class, "description")]/p[@class="simpara"][contains(text(), "This function is an alias of:")]'); if ($nodes->length) { $signatures[$extension_name][] = handle_func_alias($xpath, $nodes, $file); } } else { if ($nodes->length == 1) { if (!preg_match('/\\w+::\\w+/', $nodes->item(0)->textContent)) { $signatures[$extension_name][] = handle_func_def($xpath, $nodes->item(0), $file); } else { fwrite(STDERR, "WARNING: Only class-like function definition found in " . $file . "\n"); continue; } } else { if ($nodes->length > 1) { // more than one signature for a single function name // maybe its a procedural style of a method like xmlwriter_text -> XMLWriter::text // search for the first non object style synopsis and extract from that foreach ($nodes as $node) { if (!preg_match('/\\w+::\\w+/', $node->textContent)) { $signatures[$extension_name][] = handle_func_def($xpath, $node, $file); break; } } } } } } return $signatures; }
function extract_constant_names($files, $extensions) { $constants = array(); $class_constants = array(); foreach ($files as $file) { $doc = new DOMDocument(); $doc->loadHTMLFile($file); $xpath = new DOMXpath($doc); // Unfortunately, the constatns are not marked with classes in code, // only a <strong><code>UPPERCASE_LETTER</code></strong> seem to be universal among them // xpath1 doesn't have uppercase so but fortunetly the alphabet is pretty limited // so translate() will do for uppercasing content so we only select full uppercased contents $nodes = $xpath->query('//strong/code[translate(text(), "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ") = text()]'); foreach ($nodes as $node) { // regexp lifted from http://php.net/manual/en/language.constants.php added ":" so we can pick up class constants if (preg_match('/^[a-zA-Z_\\x7f-\\xff][:a-zA-Z0-9_\\x7f-\\xff]*$/', trim($node->textContent))) { $constant = trim($node->textContent); // these are so common they are in almost every file, // to trim down the number of non-empty extensions we handle them elsewhere if (strpos($constant, 'E_') === 0 || strpos($constant, '__') === 0 || in_array($constant, array('NULL', 'TRUE', 'FALSE'))) { $constants['common'][$constant] = true; continue; } $extension_name = get_extension_name($file, $extensions); if (strpos($constant, "::") !== false) { if (!isset($class_constants[$extension_name])) { $class_constants[$extension_name] = array(); } $class_constants[$extension_name][$constant] = true; } else { if (!isset($constants[$extension_name])) { $constants[$extension_name] = array(); } $constants[$extension_name][$constant] = true; } } } } return array($constants, $class_constants); }