diff --git a/composer.lock b/composer.lock index 978b69e..b00f16e 100644 --- a/composer.lock +++ b/composer.lock @@ -1,7 +1,7 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], "content-hash": "6702889e0a9f2aec0b235a17dad1def6", diff --git a/lib/class-importer.php b/lib/class-importer.php index b83e597..d2eca0d 100644 --- a/lib/class-importer.php +++ b/lib/class-importer.php @@ -69,6 +69,13 @@ class Importer implements LoggerAwareInterface { */ public $post_type_hook; + /** + * Post type name for constants + * + * @var string + */ + public $post_type_constant; + /** * Handy store for meta about the current item being imported * @@ -100,6 +107,7 @@ public function __construct( array $args = array() ) { 'post_type_method' => 'wp-parser-method', 'post_type_function' => 'wp-parser-function', 'post_type_hook' => 'wp-parser-hook', + 'post_type_constant' => 'wp-parser-constant', 'taxonomy_file' => 'wp-parser-source-file', 'taxonomy_namespace' => 'wp-parser-namespace', 'taxonomy_package' => 'wp-parser-package', @@ -147,7 +155,7 @@ public function import( array $data, $skip_sleep = false, $import_ignored_functi delete_option( 'wp_parser_root_import_dir' ); // Sanity check -- do the required post types exist? - if ( ! post_type_exists( $this->post_type_class ) || ! post_type_exists( $this->post_type_function ) || ! post_type_exists( $this->post_type_hook ) ) { + if ( ! post_type_exists( $this->post_type_class ) || ! post_type_exists( $this->post_type_function ) || ! post_type_exists( $this->post_type_hook ) || ! post_type_exists( $this->post_type_constant ) ) { $this->logger->error( sprintf( 'Missing post type; check that "%1$s", "%2$s", and "%3$s" are registered.', $this->post_type_class, $this->post_type_function, $this->post_type_hook ) ); exit; } @@ -306,6 +314,7 @@ public function import_file( array $file, $skip_sleep = false, $import_ignored = 'functions' => array(), 'classes' => array(), 'hooks' => array(), + 'constants' => array(), ), $file ); $count = 0; @@ -337,6 +346,15 @@ public function import_file( array $file, $skip_sleep = false, $import_ignored = } } + foreach ( $file['constants'] as $constant ) { + $this->import_constant( $constant, $import_ignored ); + $count ++; + + if ( ! $skip_sleep && 0 == $count % 10 ) { + sleep( 3 ); + } + } + if ( 'wp-includes/version.php' === $file['path'] ) { $this->import_version( $file ); } @@ -405,6 +423,20 @@ public function import_hook( array $data, $parent_post_id = 0, $import_ignored = return $hook_id; } + /** + * Create a post for a constant + * + * @param array $data Constant. + * @param int $parent_post_id Optional; post ID of the parent (file, class, or function) this item belongs to. + * Defaults to zero (no parent). + * @param bool $import_ignored Optional; defaults to false. If true, constants marked `@ignore` will be imported. + * + * @return bool|int Post ID of this constant, false if any failure. + */ + public function import_constant( array $data, $parent_post_id = 0, $import_ignored = false ) { + $constant_id = $this->import_item( $data, $parent_post_id, $import_ignored, array( 'post_type' => $this->post_type_constant ) ); + } + /** * Create a post for a class * @@ -730,7 +762,7 @@ public function import_item( array $data, $parent_post_id = 0, $import_ignored = $data['doc']['tags']['deprecated'] = $this->file_meta['deprecated']; } - if ( $post_data['post_type'] !== $this->post_type_class ) { + if ( ! in_array( $post_data['post_type'], array( $this->post_type_class, $this->post_type_constant ) ) ) { $anything_updated[] = update_post_meta( $post_id, '_wp-parser_args', $data['arguments'] ); } @@ -769,6 +801,10 @@ public function import_item( array $data, $parent_post_id = 0, $import_ignored = $this->logger->info( "\t\t" . sprintf( '%1$s method "%2$s"', $action, $ns_name ) ); break; + case $this->post_type_constant: + $this->logger->info( "\t\t" . sprintf( '%1$s constant "%2$s"', $action, $ns_name ) ); + break; + default: $this->logger->info( "\t" . sprintf( '%1$s function "%2$s"', $action, $ns_name ) ); } diff --git a/lib/class-plugin.php b/lib/class-plugin.php index 5fe7f95..1325b46 100644 --- a/lib/class-plugin.php +++ b/lib/class-plugin.php @@ -28,7 +28,7 @@ public function on_load() { } /** - * Register the function and class post types + * Register the post types. */ public function register_post_types() { @@ -116,6 +116,24 @@ public function register_post_types() { ) ); } + + if ( ! post_type_exists( 'wp-parser-constant' ) ) { + + register_post_type( + 'wp-parser-constant', + array( + 'has_archive' => 'constants', + 'label' => __( 'Constants', 'wp-parser' ), + 'public' => true, + 'rewrite' => array( + 'feeds' => false, + 'slug' => 'constant', + 'with_front' => false, + ), + 'supports' => $supports, + ) + ); + } } /** @@ -123,7 +141,7 @@ public function register_post_types() { */ public function register_taxonomies() { - $object_types = array( 'wp-parser-class', 'wp-parser-method', 'wp-parser-function', 'wp-parser-hook' ); + $object_types = array( 'wp-parser-class', 'wp-parser-method', 'wp-parser-function', 'wp-parser-hook', 'wp-parser-constant' ); if ( ! taxonomy_exists( 'wp-parser-source-file' ) ) { diff --git a/lib/runner.php b/lib/runner.php index cacbec2..0c9e7e0 100644 --- a/lib/runner.php +++ b/lib/runner.php @@ -76,9 +76,11 @@ function parse_files( $files, $root ) { foreach ( $file->getConstants() as $constant ) { $out['constants'][] = array( - 'name' => $constant->getShortName(), - 'line' => $constant->getLineNumber(), - 'value' => $constant->getValue(), + 'name' => $constant->getShortName(), + 'line' => $constant->getLineNumber(), + 'value' => $constant->getValue(), + 'end_line' => $constant->getNode()->getAttribute( 'endLine' ), + 'doc' => export_docblock( $constant ), ); } diff --git a/tests/phpunit/includes/export-testcase.php b/tests/phpunit/includes/export-testcase.php index b3fe845..a0da34b 100644 --- a/tests/phpunit/includes/export-testcase.php +++ b/tests/phpunit/includes/export-testcase.php @@ -433,6 +433,18 @@ protected function assertHookHasDocs( $hook, $docs ) { $this->assertEntityHasDocs( $hook, $docs ); } + /** + * Asserts that a constant has a DocBlock. + * + * @param string $constant Constant name. + * @param array $docs The expected data for the constant's DocBlock. + */ + protected function assertConstantHasDocs( $constant, $docs ) { + + $constant = $this->find_entity_data_in( $this->export_data, 'constants', $constant ); + $this->assertEntityHasDocs( $constant, $docs ); + } + /** * Find the exported data for an entity. * diff --git a/tests/phpunit/tests/export/docblocks.inc b/tests/phpunit/tests/export/docblocks.inc index 05686f5..03f0cbb 100644 --- a/tests/phpunit/tests/export/docblocks.inc +++ b/tests/phpunit/tests/export/docblocks.inc @@ -88,3 +88,12 @@ do_action( 'undocumented_hook' ); * A reference array action. */ do_action_ref_array( 'test_ref_array_action', array( &$var ) ); + +define( 'TEST_UNDOCUMENTED_CONST', true ); + +/** + * Documented constant. + * + * @since 5.0 + */ +define ('TEST_CONST', true ); diff --git a/tests/phpunit/tests/export/docblocks.php b/tests/phpunit/tests/export/docblocks.php index 0d49b15..5b56e9a 100644 --- a/tests/phpunit/tests/export/docblocks.php +++ b/tests/phpunit/tests/export/docblocks.php @@ -142,4 +142,31 @@ public function test_property_docblocks() { , array( 'description' => 'This is a docblock for a class property.' ) ); } + + /** + * Test the constant docs are exported. + */ + public function test_constant_docblocks() { + + $this->assertConstantHasDocs( + 'TEST_CONST' + , array( + 'description' => 'Documented constant.', + ) + ); + } + + /** + * Test that constants that aren't documented don't receive docs from another node. + */ + public function test_undocumented_constant() { + + $this->assertConstantHasDocs( + 'TEST_UNDOCUMENTED_CONST' + , array( + 'description' => '', + ) + ); + } + }