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

[apex] Summit-AST Apex module - Part 6 Passing testsuite #4251

Merged

Conversation

aaronhurst-google
Copy link
Contributor

@aaronhurst-google aaronhurst-google commented Dec 2, 2022

Describe the PR

Fix all issues to pass full testsuite. (Note that a few tests were previously disabled with TODOs. These fixes are still outstanding.)

Quick summary:

  • Upgrade com.google.summit:summit-ast to release version 2,0,0
  • Promote guava from test to compile scope dependency. It has been a dependency for some non-test cases (e.g. running ast-dump) and these were only succeeding due to the copy of guava bundled inside the apex-jorje.jar.
  • Replace wrapped AST node inside ASTMethod with equivalent details, allowing PMD AST nodes to be created for synthetic methods that don't correspond to parsed code. A trigger invoke method is one such example.
  • Synthesize ASTMethod nodes for trigger invoke methods.
  • Case normalize primitive type names, to match the behavior of Jorje.
  • Queries for parent classes and interfaces return type-erased version of name (without type arguments), to match previous behavior.
  • Full support for comments: both ASTFormalComments, comments in blocks, and suppression comments. Utilized existing code to the extent possible, which now lives in ApexCommentBuilder.java.
  • Implement separate SOQL and SOSL nodes with queries and bindings. Implement EnumValues (which create ASTField nodes) and VariableDeclarationGroup. (This completes all syntax, AFAIK)
  • Update test of source code positions with some minor differences. Summit re-enables testing positions of modifiers. Also some node counts are slightly different.
  • Replace Xpath use of deprecated getOperator with getOp.
  • Delete deprecated Jorje code from pmd-visualforce.
  • Property getter and setter methods default to visibility modifiers on property.
  • Fix PMD violations.
  • Fix checkstyle violations.

Related issues

Issue #3766

eklimo and others added 20 commits December 1, 2022 18:47
Fix an unexpected `RuntimeException` from
`AbstractApexNodeBase.getBeginColumn` in instances where a `Node` had a
start column of `0`.
Set `ASTMethod.getImage` to name of type for constructors
Change-Id: I033160534044936ac2ec416428662024b63e8c5f
- Don't build the `exceptionVariable` property of `CatchBlock` nodes.
  Some rules (e.g. `LocalVariableNamingConventionsRule`) expect the
  parent of every `ASTVariableDeclaration` to be an
  `ASTVariableDeclarationStatements`.
- Fix `LocalVariableNamingConventionsRule` crash.
Make updates related to new VariableDeclarationGroup.

Translate SOQL and SOSL expressions and bindings.

Change-Id: I18995800e292cabe9f61176fa7aefedfc9729def
Change-Id: I6fb29b07e3679f333cae37fe28dfd8b14c8d4a20
Change-Id: Iec7c8335b966b243a63243ad631193b82598808b
Change-Id: I662171da66517235ce30a701ed84b687edfdb3a3
* ASTFormalComments: represent and build.
* Mark comment containers
* Populate suppression map

This reuses the existing code to the extent possible.

Makes ApexDocTest pass.

Change-Id: I5843ffa9174f7f501aae551e5d493ee973c3dd45
Change-Id: I06a3bc7afce01d2050c46aa2ca674a7a91fc4c5a
* Case normalize primitive types (e.g. Integer)
* Use type-erased names for super classes and interfaces
* Include type arguments for all other uses

Add documentation.

Change-Id: I9edf979c58a5fcf6f251e93013be85fea22a8be1
…ecessarily) disabled code.

Change-Id: I45fab6872f5a69910452b6ac2429716b677bd93a
Change-Id: I232b8e7ad0ffc5f9ac8beab741e48d90b24063d4
Change-Id: I92b456c124c50ceb20416d69b1d88d0b5405dd89
…etOperator.

Change-Id: I1fdfc314ede7ccfcfe3e169acaef309ba07c17c1
Update code to remove reference to deleted MODULO operator.

Change-Id: I39d9f7adc0407aafa9af31d3b2253c6c37c735b1
…erences.

Re-enable some tests that were disabled due to Jorje limitations.

Change-Id: Id81582231afcc3b2e9f13ac52860ac0de538f41b
Change-Id: Id580cdfa39b4288c239a496ed4a61afb123b0b2f
…tic "invoke" method inside triggers.

Change-Id: I21344a36c9795deffd9c62aa0e768eb6f6742796
@pmd-test
Copy link

pmd-test commented Dec 2, 2022

2 Messages
📖 Compared to experimental-apex-parser:
This changeset changes 15 violations,
introduces 34 new violations, 2 new errors and 0 new configuration errors,
removes 19 violations, 0 errors and 0 configuration errors.
Full report
📖 Compared to master:
This changeset changes 15 violations,
introduces 1202 new violations, 2 new errors and 0 new configuration errors,
removes 21 violations, 0 errors and 0 configuration errors.
Full report
Compared to experimental-apex-parser:
This changeset changes 15 violations,
introduces 33 new violations, 2 new errors and 0 new configuration errors,
removes 19 violations, 0 errors and 0 configuration errors.
Full report
Compared to master:
This changeset changes 15 violations,
introduces 1201 new violations, 2 new errors and 0 new configuration errors,
removes 21 violations, 0 errors and 0 configuration errors.
Full report
Compared to experimental-apex-parser:
This changeset changes 15 violations,
introduces 33 new violations, 2 new errors and 0 new configuration errors,
removes 19 violations, 0 errors and 0 configuration errors.
Full report
Compared to master:
This changeset changes 15 violations,
introduces 33 new violations, 2 new errors and 0 new configuration errors,
removes 19 violations, 0 errors and 0 configuration errors.
Full report

Generated by 🚫 Danger

…ue node.

Change-Id: I1542cdd3da3675a04f36c0b0627ea837e2005ac3
Change-Id: I3371e80418e11766657e7f461d26f440fcd78e79
Change-Id: I6c371bdecaf08d306bee7308e94f2f1bc5ef0e4c
…sting behavior.

Change-Id: I7b3406a60bbc18dc2b1e441b8c0122452f709404
Change-Id: Ib8d4a2d5941b47c47cbd469c1af5ab5f405b120f
…tactic type name.

Change-Id: I6ea22b890e60f24c2684f85753223f240e33509a
…t were previous satisfied by copy inside Jorje JAR.

Change-Id: Iebbc77d4f1ece8ec4712f749356d877858c14d21
@adangel adangel changed the title [apex] New Apex Parser - Passing testsuite [apex] Summit-AST Apex module - Part 6 Passing testsuite Dec 19, 2022
Copy link
Member

@adangel adangel left a comment

Choose a reason for hiding this comment

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

Thanks!
I'm really happy, that the rules are basically untouched - which is a good sign for code compatibility.

I've now also made our regression tester working for this branch, so the report is now available: https://chunk.io/pmd/69b8157066734c538c40dd3e8dbe6a82/diff1/index.html

It seems, that most rules work as before. There are some, that don't find issues anymore (ApexDoc), and some that relied on jorje actually resolving the types (AvoidNonExistingAnnotations), which we don't do. Maybe in that case, it would be better to rewrite the rule to have an explicit list of allowed annotations... (and we should then deprecated ASTAnnotation::isResolved on master as well).

Delete deprecated Jorje code from pmd-visualforce.

Not sure, maybe that's too early. It depends on where this branch will land and how this branch will be distributed.
If we decide to merge this branch into master(pmd6), then we'd need to restore these deprecated methods.

@@ -36,7 +35,7 @@ public void understandsSimpleFile() {

// Verify
List<ASTMethod> methods = rootNode.findDescendantsOfType(ASTMethod.class);
assertEquals(4, methods.size());
assertEquals(1, methods.size());
Copy link
Member

Choose a reason for hiding this comment

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

I guess, this difference is because of the synthetic "<clinit>" and "<init>" methods. I checked it on the master branch: it these two methods plus "clone", which apparently jorje also generates.
Should we aim to mimic this behavior (and thus add a TODO here), or not? I think, we have several places, where we actually filter out these synthetic methods in rules... So, it would actually make more sense to not have these methods in the AST. But that would be a change to the current apex impl...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right. A user very likely wouldn't want to see any static analysis issue in synthetic code. These are difficult to present meaningfully and generally are not actionable for them to fix. +1 to suppressing them.

Thinking more generally... Is there any mechanism to mark and skip synthetic AST blocks? I'm imagining some sort of opt-in mechanism, where rules wouldn't visit synthetic nodes unless they pass a special flag or such. Right now I see a few conditions like !node.getImage().matches("<clinit>|<init>|clone") inconsistently dispersed in the code.

Representing these methods would have value in the future to resolve calls, build a callgraph, or some other higher-level abstractions. (FYI we're discussing a separate representation for symbol objects, but this is in the very early stages. Happy to discuss if you'd like.)

But this is a bit speculative at the moment. If you don't have any objection, I think it should be fine/easier to leave them out for now and note it somewhere.

Copy link
Member

Choose a reason for hiding this comment

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

Representing these methods would have value in the future to resolve calls, build a callgraph, or some other higher-level abstractions.

That's a good point. However, I'd also remove these synthetic methods for now completely to keep it simple. If we need them, we can add them later again (and maybe mark the AST nodes somehow as "synthethic", e.g. by a simple boolean flag).

public void testOldOperatorProperty() {
Report report = apex.executeRuleOnResource(makeXPath("//BooleanExpression[@Operator='&&']"),
"BooleanExpressions.cls");
assertSize(report, 0); // retired
Copy link
Member

Choose a reason for hiding this comment

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

👍 for creating a separate test case.
But: Shouldn't this xpath query with the deprecated attribute Operator still work? It seems, it doesn't find any nodes...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The deprecated getOperator method was fully removed in this branch. The method returned a Jorje type and would block the above-mentioned goal to compile without the Jorje JAR... or faking some of its classes.

Since I updated some xpath tests, I added an old variant to investigate and capture the xpath behavior after removal.

This is another case where the merge back into pmd6 or 7 should preserve the deprecated method. (And it would also need a summit-to-jorje conversion to behave correctly.)

pom.xml Outdated Show resolved Hide resolved
@aaronhurst-google
Copy link
Contributor Author

I've now also made our regression tester working for this branch, so the report is now available:

Thank you much! I will start investigating some of these issues.

Delete deprecated Jorje code from pmd-visualforce.

Not sure, maybe that's too early. It depends on where this branch will land and how this branch will be distributed.
If we decide to merge this branch into master(pmd6), then we'd need to restore these deprecated methods.

Our team is eager to prototype a copy with the Jorje code actually removed (as opposed to present but deprecated), so it's useful if it could be this experimental branch. (Maybe others would find that useful?) I be happy to resolve the merge into master or pmd 7 to restore and keep this code deprecated as long as you see fit. Is that ok on your end?

The deprecation was proposed for master/pmd6.
…ately after modifiers.

This matches one observed property in the way that Jorje ordered nodes.

Update the dump test.
@adangel adangel self-requested a review January 10, 2023 11:47
@adangel
Copy link
Member

adangel commented Jan 14, 2023

Our team is eager to prototype a copy with the Jorje code actually removed (as opposed to present but deprecated), so it's useful if it could be this experimental branch. (Maybe others would find that useful?) I be happy to resolve the merge into master or pmd 7 to restore and keep this code deprecated as long as you see fit. Is that ok on your end?

That sounds fine. I'm currently thinking about how we can release PMD 7 sooner (see #4284). So, thinking ahead: Maybe we can just deprecate the removed methods/classes for PMD 6 (I think, this is already the case) and plan to merge this experimental branch eventually into PMD 7.
That means, that there wouldn't be a PMD6-solution with jorje removed outside of this experimental branch, but PMD7 would have jorje removed... WDYT?

@adangel
Copy link
Member

adangel commented Jan 14, 2023

I've now also made our regression tester working for this branch, so the report is now available:

Thank you much! I will start investigating some of these issues.

I'm going to merge this PR now. The rule related fixes can come in further PRs.

@adangel adangel merged commit 5c4e5ec into pmd:experimental-apex-parser Jan 14, 2023
@adangel
Copy link
Member

adangel commented Jan 14, 2023

@aaronhurst-google I've merged also master into experimental-apex-parser.

I've fixed the problem around the rule "AvoidNonExistentAnnotations" (I think): a9cbe7e

However, there is now a new change in - it's about #4146 .
This will require an update to the apex grammar -> it needs to be updated to support the new with clauses WITH USER_MODE and WITH SYSTEM_MODE: https://github.com/nawforce/apex-parser/blob/a5adae847d394fe8bb2c8ce03329a8caccc4871b/antlr/ApexParser.g4#L686-L689

Could you take care of this? Thanks!

I've left the tests activated, so the build is failing now again.

Interestingly, jorje also doesn't support all the latest language features:

<test-code disabled="true">
<!-- disabled, because jorje can't parse "as user" -->
<description>Consider "insert as"</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>7</expected-linenumbers>
<code><![CDATA[
public class UserMode {
public void coverAllCasesWithTest() {
Contact c;
c = [SELECT Name FROM Contact WITH USER_MODE];
// Should be flagged a critical issue
insert contact;
// Should be ignored
insert as user contact;
// Should be at best a warning because it ignores CRUD but explicitly
insert as system contact;
}
}
]]></code>
</test-code>

@adangel adangel added this to the 7.0.0 milestone Feb 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants