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

Introduce documentation-support module #428

Merged
merged 51 commits into from
Feb 13, 2023
Merged

Conversation

rickie
Copy link
Member

@rickie rickie commented Dec 29, 2022

This is the PR that introduces this module. After polishing it and merging it, we can add more extractors for the following things:

  • Tests of the BugPatterns.
  • Refaster rule (collections).
  • Refaster rule (collection) tests.

While reviewing, keep in mind that we'll add the above mentioned changes soon and this PR is the setup for those extractors as well.

Having some doubts about the naming "documentation generation" vs. "documentation generator" in some places. I'm curious what you guys think :).

@github-actions

This comment was marked as outdated.

getSimpleClassName(sourceFile.getName())));
}

// XXX: `JavaFileObject` will most likely be added as parameter to help identify other `DocType`s.
Copy link
Member Author

Choose a reason for hiding this comment

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

This is just to point out and pick up in the next iteration.

package tech.picnic.errorprone.plugin;

enum DocumentationType {
BUG_PATTERN("bugpattern", new BugPatternExtractor());
Copy link
Member Author

Choose a reason for hiding this comment

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

Here we can add the others as well :).

@rickie rickie force-pushed the rossendrijver/PSM-1716 branch 2 times, most recently from fa4c310 to 38235c1 Compare December 29, 2022 08:47
@rickie rickie added chore A task not related to code (build, formatting, process, ...) documentation A documentation update and removed chore A task not related to code (build, formatting, process, ...) labels Dec 29, 2022
@github-actions

This comment was marked as duplicate.

1 similar comment
@github-actions

This comment was marked as duplicate.

@Badbond Badbond self-requested a review December 29, 2022 09:13
@github-actions

This comment was marked as outdated.

@github-actions
Copy link

  • Surviving mutants in this change: 3
  • Killed mutants in this change: 28
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 3 20
🎉tech.picnic.errorprone.plugin.BugPatternExtractor 0 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2
🎉tech.picnic.errorprone.plugin.DocumentationGenerator 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

4 similar comments
@github-actions
Copy link

  • Surviving mutants in this change: 3
  • Killed mutants in this change: 28
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 3 20
🎉tech.picnic.errorprone.plugin.BugPatternExtractor 0 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2
🎉tech.picnic.errorprone.plugin.DocumentationGenerator 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@github-actions
Copy link

  • Surviving mutants in this change: 3
  • Killed mutants in this change: 28
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 3 20
🎉tech.picnic.errorprone.plugin.BugPatternExtractor 0 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2
🎉tech.picnic.errorprone.plugin.DocumentationGenerator 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@github-actions
Copy link

  • Surviving mutants in this change: 3
  • Killed mutants in this change: 28
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 3 20
🎉tech.picnic.errorprone.plugin.BugPatternExtractor 0 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2
🎉tech.picnic.errorprone.plugin.DocumentationGenerator 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@github-actions
Copy link

  • Surviving mutants in this change: 3
  • Killed mutants in this change: 28
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 3 20
🎉tech.picnic.errorprone.plugin.BugPatternExtractor 0 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2
🎉tech.picnic.errorprone.plugin.DocumentationGenerator 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@github-actions
Copy link

  • Surviving mutants in this change: 4
  • Killed mutants in this change: 30
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 4 22
🎉tech.picnic.errorprone.plugin.BugPatternExtractor 0 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2
🎉tech.picnic.errorprone.plugin.DocumentationGenerator 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

2 similar comments
@github-actions
Copy link

  • Surviving mutants in this change: 4
  • Killed mutants in this change: 30
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 4 22
🎉tech.picnic.errorprone.plugin.BugPatternExtractor 0 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2
🎉tech.picnic.errorprone.plugin.DocumentationGenerator 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@github-actions
Copy link

  • Surviving mutants in this change: 4
  • Killed mutants in this change: 30
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 4 22
🎉tech.picnic.errorprone.plugin.BugPatternExtractor 0 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2
🎉tech.picnic.errorprone.plugin.DocumentationGenerator 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@nathankooij nathankooij force-pushed the rossendrijver/PSM-1716 branch from 5db7116 to 51ac167 Compare December 30, 2022 11:43
@github-actions
Copy link

  • Surviving mutants in this change: 4
  • Killed mutants in this change: 30
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 4 22
🎉tech.picnic.errorprone.plugin.BugPatternExtractor 0 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2
🎉tech.picnic.errorprone.plugin.DocumentationGenerator 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

1 similar comment
@github-actions
Copy link

  • Surviving mutants in this change: 4
  • Killed mutants in this change: 30
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 4 22
🎉tech.picnic.errorprone.plugin.BugPatternExtractor 0 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2
🎉tech.picnic.errorprone.plugin.DocumentationGenerator 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@nathankooij
Copy link
Contributor

@rickie fixed the Windows tests. Will review the code ~today.

Copy link
Contributor

@nathankooij nathankooij left a comment

Choose a reason for hiding this comment

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

Very cool. Pushing a few tweaks, some others are still open. :)

<version>0.6.1-SNAPSHOT</version>
</parent>

<artifactId>documentation-generator</artifactId>
Copy link
Contributor

Choose a reason for hiding this comment

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

A completely different alternative: documentation-support.

Copy link
Contributor

Choose a reason for hiding this comment

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

Any thoughts on this one @rickie? :)

Copy link
Member Author

Choose a reason for hiding this comment

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

The suggestion is pretty good. The current one is IMO more inline with "refaster-compiler" and "refaster-runner". The former is most comparable to what we are doing in this module I would say.

The "-support" suffix to me indicates that others can easily use this for their own use cases / websites. (This may actually hold for some classes of this module 🤔, which is a good thing though and would make -support the better option.) OTOH how we use it and set it up is quite specific to our use case, which would make me lean towards the current name.

Not a very clear line of reasoning TBH, in essence both are fine by me. Was mostly not responding yet maybe others would've some input on this :).

Copy link
Member Author

Choose a reason for hiding this comment

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

Discussed with @Stephan202 and settled on a name. It's the alternative you brought up @nathankooij ! It captures the goal nicely and is similar to some other modules.

<artifactId>documentation-generator</artifactId>

<name>Picnic :: Error Prone Support :: Documentation Generation</name>
<description>Extracts data to generate the documentation</description>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<description>Extracts data to generate the documentation</description>
<description>Extracts data to generate the documentation.</description>

/**
* A {@link DocumentationExtractor} that describes how to extract data from a {@code BugChecker}.
*/
public final class BugPatternExtractor implements DocumentationExtractor<BugPatternData> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need to be public?

Copy link
Member Author

Choose a reason for hiding this comment

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

Don't think so actually :).

import tech.picnic.errorprone.plugin.models.BugPatternData;

/**
* A {@link DocumentationExtractor} that describes how to extract data from a {@code BugChecker}.
Copy link
Contributor

Choose a reason for hiding this comment

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

We use BugPattern and BugChecker interchangeably. Let's make sure we are consistent in what we mean.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm yes, we should. However I kind of want to propose to defer that decision as we would also want to solve that for the whole project in one go.

Copy link
Contributor

Choose a reason for hiding this comment

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

Works for me.


@Override
public BugPatternData extractData(ClassTree tree, TaskEvent taskEvent) {
ClassSymbol symbol = ASTHelpers.getSymbol(tree);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we include a checkArgument here to enforce that this is indeed a BugPattern, e.g. annotation must be present.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sounds good :).

.resolve("docs" + File.separator + "bugpattern-CompilerBasedTestInput.json")
.toFile()
.exists())
.isFalse();
Copy link
Contributor

Choose a reason for hiding this comment

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

AssertJ also provides shorthands for Files and Paths, so let's use that. :)

"public final class MinimalTestChecker extends BugChecker {}");

CharSequence expectedJson =
FileObjects.forResource(getClass(), "bugpattern_example_minimal_testdata.json")
Copy link
Contributor

Choose a reason for hiding this comment

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

Think it's nicer to use the Resources API for this.

assertThat(
Files.readString(
outputPath.resolve(
"docs" + File.separator + "bugpattern-CompilerBasedTestInput.json")))
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"docs" + File.separator + "bugpattern-CompilerBasedTestInput.json")))
Paths.of("docs", "bugpattern-CompilerBasedTestInput.json")))

or simply chain Path#resolve.

import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.io.TempDir;

final class DocumentationGeneratorBugPatternTest extends DocumentationGeneratorCompilerBasedTest {
Copy link
Contributor

Choose a reason for hiding this comment

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

Something that came to mind after reading this test: it might be nicer to separate the writing and identification concerns into separate classes.


abstract class DocumentationGeneratorCompilerBasedTest {
public void compile(String outputDirectory, String... lines) {
compile(outputDirectory, FileObjects.forSourceLines("CompilerBasedTestInput.java", lines));
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we extract this to a constant since we refer to it in other places?

@github-actions
Copy link

  • Surviving mutants in this change: 4
  • Killed mutants in this change: 29
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 4 19
🎉tech.picnic.errorprone.plugin.BugPatternExtractor 0 5
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2
🎉tech.picnic.errorprone.plugin.DocumentationGenerator 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@rickie rickie force-pushed the rossendrijver/PSM-1716 branch from 7720e00 to 688dc83 Compare December 31, 2022 13:20
@rickie
Copy link
Member Author

rickie commented Dec 31, 2022

Rebased and applied almost all feedback that was left. Did some minor changes I discussed with @Stephan202 as well :).

Thanks for the extensive review @nathankooij 🚀:heart:.

@github-actions
Copy link

  • Surviving mutants in this change: 7
  • Killed mutants in this change: 30
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 3 18
🧟tech.picnic.errorprone.plugin.BugPatternExtractor 2 6
🧟tech.picnic.errorprone.plugin.DocumentationGenerator 2 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

1 similar comment
@github-actions
Copy link

  • Surviving mutants in this change: 7
  • Killed mutants in this change: 30
class surviving killed
🧟tech.picnic.errorprone.plugin.DocumentationGeneratorTaskListener 3 18
🧟tech.picnic.errorprone.plugin.BugPatternExtractor 2 6
🧟tech.picnic.errorprone.plugin.DocumentationGenerator 2 3
🎉tech.picnic.errorprone.plugin.models.BugPatternData 0 1
🎉tech.picnic.errorprone.plugin.DocumentationType 0 2

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@rickie
Copy link
Member Author

rickie commented Dec 31, 2022

I wasn't expecting this TBH. Not sure if I have time to dive into the Windows issue again 😬.

@Stephan202 Stephan202 force-pushed the rossendrijver/PSM-1716 branch from 302274e to 485c85c Compare February 11, 2023 13:51
@github-actions
Copy link

  • Surviving mutants in this change: 6
  • Killed mutants in this change: 37
class surviving killed
🧟tech.picnic.errorprone.documentation.DocumentationGeneratorTaskListener 3 14
🧟tech.picnic.errorprone.documentation.BugPatternExtractor 2 10
🧟tech.picnic.errorprone.documentation.DocumentationGenerator 1 8
🎉tech.picnic.errorprone.documentation.ExtractorType 0 5

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

Copy link
Member

@Stephan202 Stephan202 left a comment

Choose a reason for hiding this comment

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

Added one more commit. Suggested commit message:

Introduce `documentation-support` module (#428)

This new module provides the initial version of a framework for the extraction 
of data from bug checkers and Refaster rules, to be used as input for website
generation.

Comment on lines 18 to 25
public static void compile(Path outputDirectory, String fileName, String... lines) {
performCompilationForFile(
outputDirectory.toAbsolutePath().toString(), FileObjects.forSourceLines(fileName, lines));
}

public static void compile(String outputDirectory, String fileName, String... lines) {
performCompilationForFile(outputDirectory, FileObjects.forSourceLines(fileName, lines));
}
Copy link
Member

Choose a reason for hiding this comment

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

The first method can delegate to the second.

Comment on lines 64 to 78
@Test
void emptyDirectoryWhenNotStartingKindAnalyze(@TempDir Path directory) {
Path outputPath = directory.resolve("pkg");
JavacTaskCompilation.compile(outputPath, "A.java", "package pkg;");

assertThat(directory).isEmptyDirectory();
}

@Test
void noClassNoOutput(@TempDir Path directory) {
Path outputPath = directory.resolve("pkg");
JavacTaskCompilation.compile(outputPath, "A.java", "package pkg;");

assertThat(directory).isEmptyDirectory();
}
Copy link
Member

Choose a reason for hiding this comment

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

These tests are identical 👀

javacFileManager,
null,
ImmutableList.of(
"-Xplugin:DocumentationGenerator -XoutputDirectory=" + outputDirectory),
Copy link
Member

Choose a reason for hiding this comment

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

This class' name is more generic than warranted by the implementation. Will propose something.

* purposes from processed files.
*/
@AutoService(Plugin.class)
public final class DocumentationGenerator implements Plugin {
Copy link
Member

Choose a reason for hiding this comment

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

K, let's defer this; will add an XXX comment.


// XXX: Generalize and move this class so that it can also be used by `refaster-compiler`.
// XXX: Add support for this class to the `ErrorProneTestHelperSourceFormat` check.
public final class JavacTaskCompilation {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe just Compilation?


/** A {@link BugChecker} that validates the {@link BugPatternExtractor}. */
@BugPattern(summary = "Validates `BugPatternExtractor` extraction", severity = ERROR)
public static final class TestChecker extends BugChecker implements ClassTreeMatcher {
Copy link
Member

Choose a reason for hiding this comment

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

Let's keep inner classes at the bottom.


@Test
void emptyDirectoryWhenNotStartingKindAnalyze(@TempDir Path directory) {
Path outputPath = directory.resolve("pkg");
Copy link
Member

Choose a reason for hiding this comment

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

Here and below: the .resolve("pkg") isn't relevant to the test.

final class DocumentationGeneratorTaskListenerTest {
@EnabledOnOs(WINDOWS)
@Test
void readOnlyFileSystemWindows(@TempDir Path directory) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
void readOnlyFileSystemWindows(@TempDir Path directory) throws IOException {
void readOnlyFileSystemWindows(@TempDir Path outputDirectory) throws IOException {

Etc.

Comment on lines 92 to 122
@Test
void skipTaskListenerStartedCreatesNoDirectories(@TempDir Path directory) {
Path outputPath = directory.resolve("pkg").toAbsolutePath();
JavaFileObject javaFileObject =
FileObjects.forSourceLines(
"A.java",
"package pkg;",
"",
"import com.google.errorprone.bugpatterns.BugChecker;",
"",
"public final class A extends BugChecker {}");
JavaCompiler compiler = JavacTool.create();
JavacTaskImpl task =
(JavacTaskImpl)
compiler.getTask(
null,
null,
null,
ImmutableList.of("-Xplugin:DocumentationGenerator -XoutputDirectory=" + outputPath),
ImmutableList.of(),
ImmutableList.of(javaFileObject));

task.parse();
TaskEvent taskEvent = new TaskEvent(Kind.ANALYZE, javaFileObject);

for (TaskListener tl : task.getTaskListeners()) {
tl.finished(taskEvent);
}

assertThat(directory).isEmptyDirectory();
}
Copy link
Member

Choose a reason for hiding this comment

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

This test doesn't seem too add much; suggest we drop it.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's okay, but dropping it will give a Pitest warning :).

Copy link
Member

Choose a reason for hiding this comment

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

I'm open to suggestions that cover the relevant branch in a less contrived manner 🙃

.hasMessage("'%s' must be of the form '%s=<value>'", pathArg, OUTPUT_DIRECTORY_FLAG);
}

@EnabledOnOs(WINDOWS)
Copy link
Member

Choose a reason for hiding this comment

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

We can instead use a path that's invalid on all supported OS'es.

@github-actions
Copy link

  • Surviving mutants in this change: 6
  • Killed mutants in this change: 37
class surviving killed
🧟tech.picnic.errorprone.documentation.DocumentationGeneratorTaskListener 4 13
🧟tech.picnic.errorprone.documentation.BugPatternExtractor 2 10
🎉tech.picnic.errorprone.documentation.ExtractorType 0 5
🎉tech.picnic.errorprone.documentation.DocumentationGenerator 0 9

Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed.

@rickie
Copy link
Member Author

rickie commented Feb 11, 2023

Cool stuff btw 🚀! Will check out the changes in more detail later :).

@rickie rickie removed the request for review from Badbond February 13, 2023 08:10
@rickie
Copy link
Member Author

rickie commented Feb 13, 2023

Very nice changes @Stephan202, will merge this one 😄!

@rickie rickie merged commit 0f15070 into master Feb 13, 2023
@rickie rickie deleted the rossendrijver/PSM-1716 branch February 13, 2023 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation A documentation update
Development

Successfully merging this pull request may close these issues.

4 participants