Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DocBlocks for filters inside a conditional expression are not imported #185

Open
keesiemeijer opened this issue Dec 28, 2016 · 4 comments
Open
Labels

Comments

@keesiemeijer
Copy link
Contributor

keesiemeijer commented Dec 28, 2016

DocBlocks outside a conditional are not imported if there are other filters (with DocBlocks) within the conditional.

Example 1

In this example DocBlock 2 is not imported for the filter in_conditional_expression

/**
 * DocBlock 1
 */
function test_docblocks() {
	/**
	 * DocBlock 2
	 */
	if ( apply_filters( 'in_conditional_expression', true ) ) {
		/**
		 * DocBlock 3
		 */
		$value = apply_filters( 'in_conditional', true );
	}
}

Example 2

In this example the (wrong) DocBlock 2 is imported for the filter 'in_conditional`.

/**
 * DocBlock 1
 */
function test_docblocks() {
	/**
	 * DocBlock 2
	 */
	if ( apply_filters( 'in_conditional_expression', true ) ) {

		$value = apply_filters( 'in_conditional', true );
	}
}

The wp_save_post_revision_check_for_changes filter doesn't get its DocBlock imported because of this bug.

See this filter in trac

@keesiemeijer keesiemeijer changed the title DocBlocks inside a conditional expression are not imported DocBlocks for filters inside a conditional expression are not imported Dec 28, 2016
JDGrimes added a commit to JDGrimes/WP-Parser that referenced this issue Dec 30, 2016
PHPParser loops over the body of a conditional statement (the part between the curly brackets), before looping over each node in the expression. Because we were only saving the last docblock that wasn't associated with a documentable element, if there was also a documented filter within the condition body, the docblock for that filter would be picked up, and the docblock for the first filter in the condition expression would be discarded. So by the time we got to the node for the filter in the condition expression, there was no docblock saved to associate with it.

This is now fixed by keeping a stack of stray docblocks for non-documentable elements, so that instead of the docblock for the first filter being discarded it is just pushed down the stack. The docblock for the second filter within the condition block will be pushed on top of it, and then popped off once it has been used. So when we come around to actually looping over the node for the filter in the conditional expression, its docblock will be at the tip of the stack once again, and can be associated with the filter as expected.

See WordPress#185
JDGrimes added a commit to JDGrimes/WP-Parser that referenced this issue Dec 30, 2016
Discovered while working on WordPress#185.
@JDGrimes
Copy link
Contributor

I've created in #186, which addresses the first example (2 documented filters, first doc not picked up). The second example (first filter documented, second not, but docs imported for second one) is really more difficult to handle, and I'm not sure that it is worth the work. If it is really needed, I suppose that there may be some way to do it, but it is not straightforward, as far as I can see. I know that this may seem odd, but it works this way because the second filter is actually parsed first, then the first one.

@keesiemeijer
Copy link
Contributor Author

I've tested your patch on the wp-includes folder to see if there would be any differences between the current way docblocks are imported and with the patch. The only differences found are for the filters wp_save_post_revision_check_for_changes and header_video_settings. The first now gets imported correctly.

The filter header_video_settings doesn't have a dockblock and isn't imported currently. With your patch it's is imported with the wrong dockblock as you said above.

As all hooks should be documented this shouldn't be a problem. I've already created a ticket for this filter https://core.trac.wordpress.org/attachment/ticket/39130/39130.12.patch

@keesiemeijer
Copy link
Contributor Author

I've now tested your patch on trunk and it correctly adds the DocBlocks for these hooks:

  • custom_menu_order in /wp-admin/includes/menu.php
  • wp_save_post_revision_check_for_changes in /wp-includes/revision.php

These undocumented hooks get a wrong DocBlock assigned:

  • load-page-new.php in /wp-admin/admin.php (4 undocumented actions below it)
  • header_video_settings in /wp-includes/theme.php

All other DocBlocks for hooks (and functions, classes, methods) get imported the same as without the patch. The issue with the undocumented hooks should be fixed by adding the 6 missing DocBlocks to the hooks in WP itself.

@keesiemeijer
Copy link
Contributor Author

DocBlocks for elseif statements are not picked up (with or without #186). The method $node->getDocComment() doesn't return a DocBlock for Stmt_ElseIf type nodes, while it does for Stmt_If nodes.

In this example DocBlock 2 will never be imported for filter in_conditional_expression because it's in a elseif conditional expression.

/**
 * DocBlock 1
 */
function test_docblocks() {

	if ( 1 == 1 ) {

		/**
		 * DocBlock 2
		 */
	} elseif ( apply_filters( 'in_conditional_expression', true ) ) {

	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants