Index: parser.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/api/parser.inc,v retrieving revision 1.41.2.40 diff -u -F '^f' -r1.41.2.40 parser.inc --- parser.inc 2 Feb 2010 07:54:15 -0000 1.41.2.40 +++ parser.inc 2 Feb 2010 08:28:51 -0000 @@ -6,6 +6,16 @@ * The PHP documentation parser that generates content for api.module. */ +module_load_include('inc', 'pgp', 'engine/pgp.parser'); +module_load_include('inc', 'pgp', 'engine/pgp.reader'); +module_load_include('inc', 'pgp', 'engine/pgp.writer'); +module_load_include('inc', 'pgp', 'engine/pgp.editor'); +module_load_include('inc', 'pgp', 'engine/pgp.list'); +module_load_include('inc', 'pgp', 'engine/pgp.object'); + +// Constant to allow for switching between API parser and Grammar Parser. +define('USE_PARSER', 'YES'); + function api_parse_file($callback, $file_path, $branch, $file_name) { $docblock = array( 'object_name' => $file_name, @@ -59,6 +69,8 @@ function api_parse_html_file($docblock) * Read in the file at the given path and parse its documentation. */ function api_parse_php_file($docblock) { +if (USE_PARSER == 'NO') { + $docblock['code'] = api_format_php($docblock['source']); $docblocks = array($docblock); @@ -168,6 +180,149 @@ function api_parse_php_file($docblock) { api_save_documentation($docblocks); } +else { + api_parse_php_file_with_pgp($docblock); +} +} + +/** + * Returns a PGPEditor object. (Singleton) + * + * @return PGPEditor + */ +function api_get_editor() { + static $editor; + if (!$editor) { + $editor = new PGPEditor(); + } + return $editor; +} + +/** + * Read in the file at the given path and parse its documentation. + * + * @param array $docblock + * An array of the documentation block. + */ +function api_parse_php_file_with_pgp($docblock) { + // Edit grammar statements. + $editor = api_get_editor(); + + // Build grammar statements. + $reader = $editor->getReader(); + $reader->setSnippet($docblock['source']); + $reader->addTokenNames(); + $reader->buildGrammar(); + + // Retrieve items of interest. + $statements = $reader->getStatements(); + if (!$statements) { + // This is a text file or template file with no functions, constants, etc. + $docblock['code'] = api_format_php($docblock['source']); + api_save_documentation(array($docblock)); + // Free up memory. + $reader->reset(); + pgp_log_memory_use('reset'); + return; + } + + // Reserve the first array slot for the file documentation block. + $docblocks = array(); + $docblock['code'] = api_format_php($docblock['source']); + $docblocks[] = $docblock; + + // Set default documenation block array for items other than the file. + $default_block = array( + 'object_name' => '', + 'branch' => $docblock['branch'], + 'object_type' => '', + 'file_name' => $docblock['file_name'], + 'title' => '', + 'code' => '', + 'modified' => $docblock['modified'], // Only needed for 'file' item, but it simplifies parameters in other functions. + 'start_line' => 0, + 'see' => '', + 'class' => '', // TODO Added this + ); + + api_documentation_loop($statements, $default_block, $docblocks); + + // Free up memory. + $reader->reset(); + + api_save_documentation($docblocks); +} + +/** + * Build a list of documentation items. + * + * @param array $statements + * A PGPBody object of body statements. + * @param array $docblock + * The default documentation block item for the file. + * @param array $docblocks + * The array of documentation block items for the file. + */ +function api_documentation_loop($statements, $default_block, &$docblocks) { + $editor = api_get_editor(); + + // Traverse statement list to gather documentation items. + $current = $statements->first(); + while ($current->next != NULL) { + $statement = $current->data; + $type = is_object($statement) ? $statement->type : $statement['type']; + // Common processing. + switch ($type) { +// case T_INTERFACE: + case T_CLASS: + case T_FUNCTION: + case T_DEFINE: + case T_GLOBAL: + $docblock = $default_block; + $docblock['object_type'] = $editor->statementTypeToString($statement); + $docblock['object_name'] = $default_block['class'] . $editor->statementOperandToText($statement); + $docblock['title'] = $editor->statementOperandToText($statement); + $docblock['start_line'] = 0; // TODO + + $docblock['content'] = $editor->commentToString($statement->comment); + unset($statement->comment); + $docblock['code'] = api_format_php("toString() ."\n?".">"); + + if (in_array($statement->type, array(T_CLASS, T_FUNCTION))) { + $docblock['signature'] = $editor->functionGetSignature($statement); + } + break; + + case T_DOC_COMMENT: + $docblock = $default_block; + $docblock['content'] = $editor->commentToString($statement); + break; + + default: + $docblock = array(); + continue; + +// case T_CONST: +// case T_VAR: +// $docblock = api_documentation_global($statement, $branch_name, $file_name); +// break; + } + if (!empty($docblock)) { + $docblocks[] = $docblock; + } + + // Additional recursive processing on statements with bodies. + switch ($type) { +// case T_INTERFACE: + case T_CLASS: + $default_block['class'] = $docblock['object_name'] . '::'; + case T_FUNCTION: + api_documentation_loop($statement->body, $default_block, $docblocks); + break; + } + $current = $current->next; + } +} /** * Find functions called in a formatted block of code.