Skip to content

[core] Deprecate jjtree methods from the Node interface#2172

Merged
adangel merged 18 commits into
pmd:masterfrom
oowekyala:deprecate-jjtree-methods
Jan 17, 2020
Merged

[core] Deprecate jjtree methods from the Node interface#2172
adangel merged 18 commits into
pmd:masterfrom
oowekyala:deprecate-jjtree-methods

Conversation

@oowekyala

Copy link
Copy Markdown
Member

The PR deprecates a lot of stuff that should be gone from the interface (and AbstractNode). This will make implementation of the interface much easier, and usage safer.

At the same time I added some methods with non-biased names to the interface. I think since a default implementation is added to AbstractNode too, it should be an acceptable breaking change, and allow user migration to start now.

@oowekyala oowekyala added the in:ast About the AST structure or API, the parsing step label Dec 17, 2019
@oowekyala oowekyala added this to the 6.21.0 milestone Dec 17, 2019
@oowekyala oowekyala force-pushed the deprecate-jjtree-methods branch from 4683801 to 87eaaef Compare December 18, 2019 18:52
@ghost

ghost commented Dec 18, 2019

Copy link
Copy Markdown
1 Message
📖 This changeset introduces 0 new violations, 2 new errors and 0 new configuration errors,
removes 0 violations, 2 errors and 0 configuration errors.
Full report
This changeset introduces 0 new violations, 2 new errors and 0 new configuration errors,
removes 0 violations, 2 errors and 0 configuration errors.
Full report
This changeset introduces 0 new violations, 2 new errors and 0 new configuration errors,
removes 0 violations, 2 errors and 0 configuration errors.
Full report

Generated by 🚫 Danger

@adangel adangel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, that's the right direction for the Node interface. 👍 Have a look at my comments, maybe we can improve the API further.

Comment thread pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java Outdated
Comment thread pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java
Comment thread pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java
Comment thread pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java
@adangel adangel self-requested a review January 5, 2020 18:34
I don't think we should expose tokens as an API
yet. They're an implementation detail, not used
much, and the AST should be able to reflect all
the information that can be found in the tokens.

The methods of AbstractNode can be pulled down
to AbstractJjtreeNode and made protected.

@adangel adangel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late review.

I completely agree to deprecate/remove the "jjt*" methods. I'm not sure yet, which traversal methods we actually should provide with having NodeStream in the future, which provides the same functionality for traversing.

I've added a simple description of the Node API in the wiki: https://github.com/pmd/pmd/wiki/PMD-7.0.0-API#description-of-node-api (based on your very good class comment for Node).

If we add this second way of traversing the AST, then I would right now add directly List<Node> getChildren() instead of having to call two methods (getNumChildren(), getChild(int)) in order to iterate.
In the wiki, I only have the minimum methods. Should we add more methods? Like "getIndexInParent()", "getNextSibling()", "isFirstChild()", "getNthParent(int)", ... there are almost endless possibilities. I guess, the more methods we add, the difficult the API usage becomes?

Comment thread pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java Outdated
Comment thread pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java
Comment thread pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java
@oowekyala

oowekyala commented Jan 10, 2020

Copy link
Copy Markdown
Member Author

I've added a simple description of the Node API

Very nice!

First in PMD 7: Should we really provide two different ways to traverse the AST: via NodeStream children() and via Node getChild(int)? In general, I think, the API should provide only one way: It's easier to use, harder to misuse, only one implementation to maintain/optimize.

About the tree traversal methods that are on Node (getParent/getChild/etc): I think we need them to implement NodeStreams.

The cool thing about the current node stream implementation is that it works for any Node, using just the four basic primitives getParent/getChild/getNumChildren/getIndexInParent. Having them on the node interface gives a very clear implementation path for someone wanting to make a new Node:

  • implement those four primitives
  • get NodeStreams and all the other traversal methods for free, including all the optimized NodeStream implementations

We could imagine a Node interface that strongly relies on NodeStream, ie not exposing those primitives. But then, an implementor of Node will need to implement a NodeStream for the children! This means, there will be more implementations of NodeStream to maintain, and they'll live outside of pmd-core's internal packages, so we'll have to publish part of the node stream implementations. I'm not sure this is something we want..

FWIW I like the mental model that NodeStream is just free stuff built on top of Node, and not integral to the Node interface. I also think methods like getParent and getChild are harmless: even if there is an equivalent NodeStream way, those methods are really basic, well-specified and well-understood (every tree data structure ever written has some combination of those methods).

If we add this second way of traversing the AST, then I would right now add directly List getChildren() instead of having to call two methods (getNumChildren(), getChild(int)) in order to iterate.

I would rather make it a Iterable<Node> children(). This makes it possible to use foreach right now, and the transition to NodeStream<Node> children() will be binary & source compatible (NodeStream is an Iterable).

As you have seen by my questions, I didn't understand the comment, so we need to rewrite it.
Suggestion: [...]

Your suggestion seems very fine to me

@oowekyala

Copy link
Copy Markdown
Member Author

More things to say here:

I think the methods about XPath should be removed from the interface and handled by an external object. This would decouple our Node -> DOM transformation from node implementations. For now we only map nodes to a DOM element with some attributes. But to support a more complete transformation, some additional methods would be required (eg access to comments, namespace, etc), and adding them directly to the node interface makes it messy. What if we want to change the XPath API, eg change the Attribute class? That's not really the problem of the Node, the AST is still the same.

Node instances are meant to be used by eg developers writing Java rules. They don't care about the XPath representation, so won't miss these methods. Also the Attribute objects, if they're created directly by Nodes, cannot know about the DOM they're used in. This is sad, because it would give a simple solution to the problem of reporting usages of deprecated attributes.

I imagine we could use something like:

interface DomAdapter {

  Iterator<Attribute> getAttributes(Node node);

  String getElementName(Node node);

}

provided by a LanguageVersionHandler.

@adangel adangel self-assigned this Jan 17, 2020
@adangel adangel merged commit 83c568a into pmd:master Jan 17, 2020
@oowekyala oowekyala deleted the deprecate-jjtree-methods branch January 17, 2020 08:56
@adangel adangel added the is:deprecation The main focus is deprecating public APIs or rules, eg to make them internal, or removing them label Jan 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

in:ast About the AST structure or API, the parsing step is:deprecation The main focus is deprecating public APIs or rules, eg to make them internal, or removing them

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants