Skip to content

Commit

Permalink
Have InvalidParam support records
Browse files Browse the repository at this point in the history
Fixes #2321.

Fixes #3437

FUTURE_COPYBARA_INTEGRATE_REVIEW=#3437 from PicnicSupermarket:rossendrijver/invalidparam_records 128ca4d
PiperOrigin-RevId: 495341457
  • Loading branch information
graememorgan authored and Error Prone Team committed Dec 14, 2022
1 parent 5feefe1 commit dd34f34
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 3 deletions.
15 changes: 15 additions & 0 deletions check_api/src/main/java/com/google/errorprone/util/ASTHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,21 @@ private static boolean isFinal(Symbol symbol) {
return (symbol.flags() & Flags.FINAL) == Flags.FINAL;
}

/**
* Flag for record types, canonical record constructors and type members that are part of a
* record's state vector. Can be replaced by {@code com.sun.tools.javac.code.Flags.RECORD} once
* the minimum JDK version is 14.
*/
private static final long RECORD_FLAG = 1L << 61;

/**
* Returns whether the given {@link Symbol} is a record, a record's canonical constructor or a
* member that is part of a record's state vector.
*/
public static boolean isRecord(Symbol symbol) {
return (symbol.flags() & RECORD_FLAG) == RECORD_FLAG;
}

/**
* Determines whether a symbol has an annotation of the given type. This includes annotations
* inherited from superclasses due to {@code @Inherited}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
package com.google.errorprone.bugpatterns.javadoc;

import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.MoreCollectors.onlyElement;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import static com.google.errorprone.bugpatterns.javadoc.Utils.diagnosticPosition;
import static com.google.errorprone.bugpatterns.javadoc.Utils.getBestMatch;
import static com.google.errorprone.bugpatterns.javadoc.Utils.getDocComment;
import static com.google.errorprone.bugpatterns.javadoc.Utils.getDocTreePath;
import static com.google.errorprone.bugpatterns.javadoc.Utils.replace;
import static com.google.errorprone.matchers.Description.NO_MATCH;
import static com.google.errorprone.names.LevenshteinEditDistance.getEditDistance;
import static com.google.errorprone.util.ASTHelpers.getSymbol;
import static com.google.errorprone.util.ASTHelpers.isRecord;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
Expand Down Expand Up @@ -74,14 +78,21 @@ public final class InvalidParam extends BugChecker implements ClassTreeMatcher,
public Description matchClass(ClassTree classTree, VisitorState state) {
DocTreePath path = getDocTreePath(state);
if (path != null) {
ImmutableSet<String> parameters = ImmutableSet.of();
ImmutableSet<String> parameters =
isRecord(getSymbol((Tree) classTree))
? getCanonicalRecordConstructor(classTree).getParameters().stream()
.map(p -> p.getName().toString())
.collect(toImmutableSet())
: ImmutableSet.of();

ImmutableSet<String> typeParameters =
classTree.getTypeParameters().stream()
.map(t -> t.getName().toString())
.collect(toImmutableSet());

new ParamsChecker(state, classTree, parameters, typeParameters).scan(path, null);
}
return Description.NO_MATCH;
return NO_MATCH;
}

@Override
Expand All @@ -98,7 +109,15 @@ public Description matchMethod(MethodTree methodTree, VisitorState state) {
.collect(toImmutableSet());
new ParamsChecker(state, methodTree, parameters, typeParameters).scan(path, null);
}
return Description.NO_MATCH;
return NO_MATCH;
}

private static MethodTree getCanonicalRecordConstructor(ClassTree classTree) {
return classTree.getMembers().stream()
.filter(MethodTree.class::isInstance)
.map(MethodTree.class::cast)
.filter(tree -> isRecord(getSymbol((Tree) tree)))
.collect(onlyElement());
}

/** Checks that documented parameters match the method's parameter list. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@

package com.google.errorprone.bugpatterns.javadoc;

import static org.junit.Assume.assumeTrue;

import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;
import com.google.errorprone.CompilationTestHelper;
import com.google.errorprone.util.RuntimeVersion;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
Expand Down Expand Up @@ -164,4 +167,117 @@ public void excludedName_noMatchDespiteSimilarParam() {
"}")
.doTest();
}

@Test
public void negative_record() {
assumeTrue(RuntimeVersion.isAtLeast16());
helper
.addSourceLines(
"Test.java", //
"/**",
" * @param name Name.",
" */",
"public record Test(String name) {}")
.doTest();
}

@Test
public void badParameterName_record() {
assumeTrue(RuntimeVersion.isAtLeast16());
helper
.addSourceLines(
"Test.java",
"/**",
" // BUG: Diagnostic contains: Parameter name `bar` is unknown",
" * @param bar Foo.",
" */",
"public record Test(String foo) {}")
.doTest();
}

@Test
public void multipleConstructors_record() {
assumeTrue(RuntimeVersion.isAtLeast16());
helper
.addSourceLines(
"Test.java",
"/**",
" * @param foo Foo.",
" * @param bar Bar.",
" */",
"public record Test(String foo, Integer bar) {",
" public Test(Integer bar) {",
" this(null, bar);",
" }",
"",
" /**",
" // BUG: Diagnostic contains: Parameter name `bar` is unknown",
" * @param bar Foo.",
" */",
" public Test(String foo) {",
" this(foo, null);",
" }",
"}")
.doTest();
}

@Test
public void typeParameter_record() {
assumeTrue(RuntimeVersion.isAtLeast16());
helper
.addSourceLines(
"Negative.java",
"/**",
" * @param <T> The type parameter.",
" * @param contents Contents.",
" * @param bar Bar.",
" */",
"public record Negative<T>(T contents, String bar) {}")
.addSourceLines(
"Positive.java",
"/**",
" // BUG: Diagnostic contains: Parameter name `E` is unknown",
" * @param <E> The type parameter.",
" * @param contents Contents.",
" * @param bar Bar.",
" */",
"public record Positive<T>(T contents, String bar) {}")
.doTest();
}

@Test
public void compactConstructor_record() {
assumeTrue(RuntimeVersion.isAtLeast16());
helper
.addSourceLines(
"Test.java",
"/**",
" * @param name Name.",
" */",
"public record Test(String name) {",
" public Test {}",
"}")
.doTest();
}

@Test
public void normalConstructor_record() {
assumeTrue(RuntimeVersion.isAtLeast16());
helper
.addSourceLines(
"Test.java",
"/**",
" * @param name Name.",
" */",
"public record Test(String name) {",
" /**",
" // BUG: Diagnostic contains: Parameter name `foo` is unknown",
" * @param foo Name.",
" */",
" public Test(String name) {",
" this.name = name;",
" }",
" }")
.doTest();
}
}

0 comments on commit dd34f34

Please sign in to comment.