-
Notifications
You must be signed in to change notification settings - Fork 27
Add control flow graph implementation #281
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
Conversation
- RoutineImplementationNodeImpl - AnonymousMethodNodeImpl
fourls
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've gone through all the core CFG stuff now, I've got a few initial comments that I'll put out so we can get started. I have more reviewing to do still, don't worry 😄
Overall, looks very cool and seems to work well! I have a few broad thoughts/questions:
-
The core CFG stuff relies heavily on public fields, which is very uncomfortably un-encapsulated in my view. I found it difficult to follow since there was very little "contract" about what could change. I see this comes directly from SonarJava - can we deviate from them and redesign for more encapsulation and better OO vibes?
-
In something this logically complex I think it'll be vital to have plenty of explanatory comments if we're going to have any chance of maintenance + continual improvement. At the moment it's very sparse.
-
Rules shouldn't instantiate
...Implclasses themselves, that should be done through the API layer (e.g. aControlFlowGraphFactorythat builds a newControlFlowGraph, for example). Core rules can useImplbehaviour by casting toControlFlowGraphImplif they absolutely need to. -
I don't really see the need to keep the
ControlFlowGraphinterface empty for the time being, although if this is something that you think would be beneficial then I don't really mind. Would the API change all that much after this PR is merged?
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/CFGBuilder.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/CFGBuilder.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/CFGBuilder.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphData.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphImpl.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphImpl.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphImpl.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphImpl.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/ControlFlowGraphChecker.java
Outdated
Show resolved
Hide resolved
|
I didn't respond to each review comment because many things have changed and it is practically a rewrite. I have tried to:
|
delphi-checks/src/main/java/au/com/integradev/delphi/checks/RedundantJumpCheck.java
Outdated
Show resolved
Hide resolved
delphi-checks/src/test/java/au/com/integradev/delphi/checks/RedundantJumpCheckTest.java
Outdated
Show resolved
Hide resolved
delphi-checks/src/main/java/au/com/integradev/delphi/checks/LoopExecutingAtMostOnceCheck.java
Outdated
Show resolved
Hide resolved
...hi-checks/src/main/resources/org/sonar/l10n/delphi/rules/community-delphi/RedundantJump.html
Outdated
Show resolved
Hide resolved
...hi-checks/src/main/resources/org/sonar/l10n/delphi/rules/community-delphi/RedundantJump.html
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/CfgDebug.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/checker/CfgCheckerFactory.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/checker/StatementTerminator.java
Outdated
Show resolved
Hide resolved
...-frontend/src/main/java/org/sonar/plugins/communitydelphi/api/ast/CaseItemStatementNode.java
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/ExitPath.java
Outdated
Show resolved
Hide resolved
|
There are a few aspects of the current shape that I am not completely happy with yet that I think would be worth discussing/brainstorming:
|
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/block/BlockImpl.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/UnknownException.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/Block.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/Block.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphImpl.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphFactory.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphFactory.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphImpl.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/block/BlockImpl.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/ControlFlowGraphTest.java
Fixed
Show fixed
Hide fixed
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphDebug.java
Outdated
Show resolved
Hide resolved
...-frontend/src/main/java/au/com/integradev/delphi/antlr/ast/node/AnonymousMethodNodeImpl.java
Outdated
Show resolved
Hide resolved
...end/src/main/java/au/com/integradev/delphi/antlr/ast/node/RoutineImplementationNodeImpl.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/ControlFlowGraphTest.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/checker/BlockChecker.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/checker/GraphChecker.java
Outdated
Show resolved
Hide resolved
...rontend/src/main/java/au/com/integradev/delphi/antlr/ast/node/CaseItemStatementNodeImpl.java
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/ControlFlowGraphTest.java
Fixed
Show fixed
Hide fixed
cirras
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some incomplete conversations, including completing the documentation sweep in the API layer.
Importantly, I'd like to see @returns, @params, etc. in the javadocs.
This does lead to some repetition, but that's the convention across the project.
fourls
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really great, functionality is really impressive and I couldn't find any obvious bugs. I have a lot of comments with questions, ideas for renaming/refactoring, and recs for where to put more tests.
The domain of this PR is really complex, confusing, and wide-ranging - we're basically reviewing an entirely new semantic model of Delphi code, and so there's so much that it's difficult to deep-dive on any single thing. In my view, that means that we need to reduce the cognitive noise as much as possible by improving naming/modelling and making sure testing is comprehensive (since we're relying on them to assert most of the functionality is correct).
...hi-checks/src/main/resources/org/sonar/l10n/delphi/rules/community-delphi/RedundantJump.html
Outdated
Show resolved
Hide resolved
...hi-checks/src/main/resources/org/sonar/l10n/delphi/rules/community-delphi/RedundantJump.json
Outdated
Show resolved
Hide resolved
delphi-checks/src/main/java/au/com/integradev/delphi/checks/RedundantJumpCheck.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/UnconditionalJump.java
Outdated
Show resolved
Hide resolved
delphi-checks/src/main/java/au/com/integradev/delphi/checks/RedundantJumpCheck.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphBuilder.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphVisitor.java
Outdated
Show resolved
Hide resolved
...checks-testkit/src/main/java/au/com/integradev/delphi/checks/verifier/CheckVerifierImpl.java
Show resolved
Hide resolved
...checks-testkit/src/main/java/au/com/integradev/delphi/checks/verifier/CheckVerifierImpl.java
Outdated
Show resolved
Hide resolved
...checks-testkit/src/main/java/au/com/integradev/delphi/checks/verifier/CheckVerifierImpl.java
Outdated
Show resolved
Hide resolved
fourls
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Fixed most of my concerns from the previous round of review.
This round I had a bit more of a look at the CFG tests to see if everything matched up - mostly good, I have a few comments.
delphi-checks/src/main/java/au/com/integradev/delphi/checks/RedundantJumpCheck.java
Show resolved
Hide resolved
delphi-checks/src/main/java/au/com/integradev/delphi/checks/RedundantJumpCheck.java
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphVisitor.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/Finally.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/block/BlockBuilder.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/ControlFlowGraphTest.java
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphImpl.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/ControlFlowGraphTest.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/ControlFlowGraphTest.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/ControlFlowGraphTest.java
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/ControlFlowGraphTest.java
Dismissed
Show dismissed
Hide dismissed
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/block/ProtoBlockFactory.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/block/ProtoBlockFactory.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/block/ProtoBlockFactory.java
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/ControlFlowGraphTest.java
Show resolved
Hide resolved
delphi-frontend/src/test/java/au/com/integradev/delphi/cfg/checker/BlockChecker.java
Show resolved
Hide resolved
fourls
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Only a few quite minor things now. Not sure why GitHub's split them up into a few mini reviews.
You'll have to rebase at some point as there are merge conflicts + the workflows have stopped running.
cirras
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some pedantic comments about the javadocs and API layer.
Once these are sorted, I'm happy.
delphi-checks/src/main/java/au/com/integradev/delphi/checks/LoopExecutingAtMostOnceCheck.java
Outdated
Show resolved
Hide resolved
delphi-checks/src/test/java/au/com/integradev/delphi/checks/CheckTestNameTest.java
Outdated
Show resolved
Hide resolved
delphi-checks/src/test/java/au/com/integradev/delphi/checks/CheckTestNameTest.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphBuilder.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/Block.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/Halt.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/UnconditionalJump.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/UnconditionalJump.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/UnknownException.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/UnknownException.java
Outdated
Show resolved
Hide resolved
fourls
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me! This will be a really great new feature that can power a lot of really interesting rules.
a16f1dc to
6d26885
Compare
|
Went a little overzealous with the delete button and failed to compile again. All @cirras comments should be addressed now. |
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/api/Halt.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/block/Terminator.java
Outdated
Show resolved
Hide resolved
cirras
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This time for sure, maybe!
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphImpl.java
Outdated
Show resolved
Hide resolved
delphi-frontend/src/main/java/au/com/integradev/delphi/cfg/ControlFlowGraphVisitor.java
Show resolved
Hide resolved
cirras
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy with this now - well done. 👍
There's a trivial follow-up, which is releasing the API for custom plugins. We'll do that once we've built some more things on this feature and are confident that we like the current shape of the CFG API.
This PR adds the notion of a control flow graph. Control flow graphs are a stepping stone in data flow analysis and symbolic execution.
With just the control flow graph alone, two new rules could be implemented:
In addition to that, some more API traversal methods were added:
RepeatStatementNode::getGuardExpressionRepeatStatementNode::getStatementsCaseStatementNode::getSelectorExpressionCaseItemStatementNode::getStatementThe thinking is that the control flow graph will be internal for a while before being exposed in the stable API. In light of this, I have made a
ControlFlowGraphinterface in the API, but there are no public ways to create/interact with it.