Skip to content

Commit

Permalink
Merge branch 'google:master' into record-unused-param-false-positives
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcono1234 authored Aug 8, 2023
2 parents 89e2ba9 + 1c1f0f8 commit 2ecedd4
Show file tree
Hide file tree
Showing 115 changed files with 4,365 additions and 753 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ jobs:
- os: ubuntu-latest
java: 21-ea
experimental: true
- os: ubuntu-latest
java: 22-ea
experimental: true
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
steps:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@
/** Explanation why the API is restricted, to be inserted into the compiler output. */
String explanation();

/** Link explaining why the API is restricted */
String link();
/** Optional link explaining why the API is restricted. */
String link() default "";

/**
* Allow the restricted API on paths matching this regular expression.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ public class ErrorProneOptions {
private static final String PATCH_IMPORT_ORDER_PREFIX = "-XepPatchImportOrder:";
private static final String EXCLUDED_PATHS_PREFIX = "-XepExcludedPaths:";
private static final String IGNORE_LARGE_CODE_GENERATORS = "-XepIgnoreLargeCodeGenerators:";

private static final String ERRORS_AS_WARNINGS_FLAG = "-XepAllErrorsAsWarnings";
private static final String SUGGESTIONS_AS_WARNINGS_FLAG = "-XepAllSuggestionsAsWarnings";
private static final String ENABLE_ALL_CHECKS = "-XepAllDisabledChecksAsWarnings";
private static final String IGNORE_SUPPRESSION_ANNOTATIONS = "-XepIgnoreSuppressionAnnotations";
private static final String DISABLE_ALL_CHECKS = "-XepDisableAllChecks";
Expand All @@ -75,6 +75,7 @@ public static int isSupportedOption(String option) {
|| option.equals(IGNORE_UNKNOWN_CHECKS_FLAG)
|| option.equals(DISABLE_WARNINGS_IN_GENERATED_CODE_FLAG)
|| option.equals(ERRORS_AS_WARNINGS_FLAG)
|| option.equals(SUGGESTIONS_AS_WARNINGS_FLAG)
|| option.equals(ENABLE_ALL_CHECKS)
|| option.equals(DISABLE_ALL_CHECKS)
|| option.equals(IGNORE_SUPPRESSION_ANNOTATIONS)
Expand Down Expand Up @@ -163,6 +164,7 @@ final PatchingOptions build() {
private final boolean disableWarningsInGeneratedCode;
private final boolean disableAllWarnings;
private final boolean dropErrorsToWarnings;
private final boolean suggestionsAsWarnings;
private final boolean enableAllChecksAsWarnings;
private final boolean disableAllChecks;
private final boolean isTestOnlyTarget;
Expand All @@ -180,6 +182,7 @@ private ErrorProneOptions(
boolean disableWarningsInGeneratedCode,
boolean disableAllWarnings,
boolean dropErrorsToWarnings,
boolean suggestionsAsWarnings,
boolean enableAllChecksAsWarnings,
boolean disableAllChecks,
boolean isTestOnlyTarget,
Expand All @@ -195,6 +198,7 @@ private ErrorProneOptions(
this.disableWarningsInGeneratedCode = disableWarningsInGeneratedCode;
this.disableAllWarnings = disableAllWarnings;
this.dropErrorsToWarnings = dropErrorsToWarnings;
this.suggestionsAsWarnings = suggestionsAsWarnings;
this.enableAllChecksAsWarnings = enableAllChecksAsWarnings;
this.disableAllChecks = disableAllChecks;
this.isTestOnlyTarget = isTestOnlyTarget;
Expand Down Expand Up @@ -230,6 +234,10 @@ public boolean isDropErrorsToWarnings() {
return dropErrorsToWarnings;
}

public boolean isSuggestionsAsWarnings() {
return suggestionsAsWarnings;
}

public boolean isTestOnlyTarget() {
return isTestOnlyTarget;
}
Expand Down Expand Up @@ -263,6 +271,7 @@ private static class Builder {
private boolean disableAllWarnings = false;
private boolean disableWarningsInGeneratedCode = false;
private boolean dropErrorsToWarnings = false;
private boolean suggestionsAsWarnings = false;
private boolean enableAllChecksAsWarnings = false;
private boolean disableAllChecks = false;
private boolean isTestOnlyTarget = false;
Expand Down Expand Up @@ -319,6 +328,10 @@ public void setDropErrorsToWarnings(boolean dropErrorsToWarnings) {
this.dropErrorsToWarnings = dropErrorsToWarnings;
}

public void setSuggestionsAsWarnings(boolean suggestionsAsWarnings) {
this.suggestionsAsWarnings = suggestionsAsWarnings;
}

public void setDisableAllWarnings(boolean disableAllWarnings) {
severityMap.entrySet().stream()
.filter(e -> e.getValue() == Severity.WARN)
Expand Down Expand Up @@ -364,6 +377,7 @@ public ErrorProneOptions build(ImmutableList<String> remainingArgs) {
disableWarningsInGeneratedCode,
disableAllWarnings,
dropErrorsToWarnings,
suggestionsAsWarnings,
enableAllChecksAsWarnings,
disableAllChecks,
isTestOnlyTarget,
Expand Down Expand Up @@ -420,6 +434,9 @@ public static ErrorProneOptions processArgs(Iterable<String> args) {
case ERRORS_AS_WARNINGS_FLAG:
builder.setDropErrorsToWarnings(true);
break;
case SUGGESTIONS_AS_WARNINGS_FLAG:
builder.setSuggestionsAsWarnings(true);
break;
case ENABLE_ALL_CHECKS:
builder.setEnableAllChecksAsWarnings(true);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.common.collect.ImmutableRangeSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Range;
import com.google.common.collect.TreeRangeSet;
import com.google.errorprone.BugCheckerInfo;
import com.google.errorprone.BugPattern.SeverityLevel;
import com.google.errorprone.ErrorProneOptions;
Expand Down Expand Up @@ -306,7 +307,7 @@ public boolean isSuppressed(Symbol sym, VisitorState state) {

/** Computes a RangeSet of code regions which are suppressed by this bug checker. */
public ImmutableRangeSet<Integer> suppressedRegions(VisitorState state) {
ImmutableRangeSet.Builder<Integer> suppressedRegions = ImmutableRangeSet.builder();
TreeRangeSet<Integer> suppressedRegions = TreeRangeSet.create();
new TreeScanner<Void, Void>() {
@Override
public Void scan(Tree tree, Void unused) {
Expand All @@ -318,7 +319,7 @@ public Void scan(Tree tree, Void unused) {
return null;
}
}.scan(state.getPath().getCompilationUnit(), null);
return suppressedRegions.build();
return ImmutableRangeSet.copyOf(suppressedRegions);
}

public interface AnnotationTreeMatcher extends Suppressible {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public boolean canAlias(JavaExpression a, JavaExpression b) {
public String visualize(CFGVisualizer<?, AccessPathStore<V>, ?> cfgVisualizer) {
throw new UnsupportedOperationException("DOT output not supported");
}

/**
* Builder for {@link AccessPathStore} instances. To obtain an instance, obtain a {@link
* AccessPathStore} (such as {@link AccessPathStore#empty()}), and call {@link
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,23 +301,23 @@ public Void visitMethodInvocation(MethodInvocationTree node, Void unused) {
// allow the inference to conclude later that x[0] = m(x)[0, 0], meaning the nullness qualifier
// for x's <String> is the same as the one for m(x)'s <String>.
for (TypeVariableSymbol typeVar : callee.getTypeParameters()) {
TypeVariableInferenceVar typeVarIV = TypeVariableInferenceVar.create(typeVar, node);
TypeVariableInferenceVar typeVarIv = TypeVariableInferenceVar.create(typeVar, node);
visitUnannotatedTypeVarRefsAndEquateInferredComponents(
typeVarIV,
typeVarIv,
callee.getReturnType(),
callee,
node,
iv -> qualifierConstraints.putEdge(typeVarIV, iv));
iv -> qualifierConstraints.putEdge(typeVarIv, iv));
Streams.forEachPair(
formalParameters.stream(),
node.getArguments().stream(),
(formal, actual) ->
visitUnannotatedTypeVarRefsAndEquateInferredComponents(
typeVarIV,
typeVarIv,
formal.type(),
formal.symbol(),
actual,
iv -> qualifierConstraints.putEdge(iv, typeVarIV)));
iv -> qualifierConstraints.putEdge(iv, typeVarIv)));
}
return super.visitMethodInvocation(node, unused);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.InstanceOfTree;
import com.sun.source.tree.MemberReferenceTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
Expand Down Expand Up @@ -785,6 +786,17 @@ public Void visitMemberSelect(MemberSelectTree tree, Void unused) {
}
return super.visitMemberSelect(tree, null);
}

@Override
public Void visitMemberReference(MemberReferenceTree tree, Void unused) {
if (sym.equals(getSymbol(tree))) {
fix.replace(
state.getEndPosition(tree.getQualifierExpression()),
state.getEndPosition(tree),
"::" + replacement);
}
return super.visitMemberReference(tree, unused);
}
}.scan(state.getPath().getCompilationUnit(), null);
return fix.build();
}
Expand Down Expand Up @@ -1047,6 +1059,7 @@ public static void addSuppressWarnings(
fixBuilder.prefixWith(suppressibleNode, replacement);
}
}

/**
* Modifies {@code fixBuilder} to either remove a {@code warningToRemove} warning from the closest
* {@code SuppressWarning} node or remove the entire {@code SuppressWarning} node if {@code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ private static boolean hasJUnitAttr(MethodSymbol methodSym) {
isJunit3TestCase,
hasAnnotation(JUNIT4_TEST_ANNOTATION),
hasAnnotation(JUNIT4_THEORY_ANNOTATION));

/**
* A list of test runners that this matcher should look for in the @RunWith annotation. Subclasses
* of the test runners are also matched.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,12 @@ public static Matcher<ClassTree> isDirectImplementationOf(String clazz) {
return new IsDirectImplementationOf(isProvidedType);
}

/** Matches any node that is a direct extension of the given class. */
public static Matcher<ClassTree> isExtensionOf(String clazz) {
Matcher<Tree> isProvidedType = isSameType(clazz);
return new IsExtensionOf(isProvidedType);
}

@SafeVarargs
public static Matcher<Tree> hasAnyAnnotation(Class<? extends Annotation>... annotations) {
ArrayList<Matcher<Tree>> matchers = new ArrayList<>(annotations.length);
Expand Down Expand Up @@ -1332,6 +1338,7 @@ public static boolean isThrowingFunctionalInterface(Type clazzType, VisitorState
return CLASSES_CONSIDERED_THROWING.get(state).stream()
.anyMatch(t -> isSubtype(clazzType, t, state));
}

/**
* {@link FunctionalInterface}s that are generally used as a lambda expression for 'a block of
* code that's going to fail', e.g.:
Expand Down Expand Up @@ -1368,6 +1375,22 @@ protected Iterable<? extends Tree> getChildNodes(ClassTree classTree, VisitorSta
}
}

private static class IsExtensionOf extends ChildMultiMatcher<ClassTree, Tree> {
IsExtensionOf(Matcher<Tree> classMatcher) {
super(MatchType.AT_LEAST_ONE, classMatcher);
}

@Override
protected Iterable<? extends Tree> getChildNodes(ClassTree classTree, VisitorState state) {
List<Tree> matched = new ArrayList<>();
Tree extendsClause = classTree.getExtendsClause();
if (extendsClause != null) {
matched.add(extendsClause);
}
return matched;
}
}

/** Matches an AST node whose compilation unit's package name matches the given predicate. */
public static <T extends Tree> Matcher<T> packageMatches(Predicate<String> predicate) {
return (tree, state) -> predicate.test(getPackageFullName(state));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ public interface MultiMatcher<T extends Tree, N extends Tree> extends Matcher<T>
@AutoValue
abstract class MultiMatchResult<N extends Tree> {
MultiMatchResult() {}

/** True if the MultiMatcher matched the nodes expected. */
public abstract boolean matches();

/**
* The list of nodes which matched the MultiMatcher's expectations (could be empty if the match
* type was ALL and there were no child nodes). Only sensical if {@link #matches()} is true.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
/** A collection of {@link TypePredicate}s. */
public final class TypePredicates {

/** Matches nothing (always {@code false}). */
public static TypePredicate nothing() {
return (type, state) -> false;
}

/** Matches everything (always {@code true}). */
public static TypePredicate anything() {
return (type, state) -> true;
}

/** Match arrays. */
public static TypePredicate isArray() {
return Array.INSTANCE;
Expand All @@ -55,16 +65,16 @@ public static TypePredicate isDescendantOf(Supplier<Type> type) {
return new DescendantOf(type);
}

/** Match types that are a sub-type of one of the given types. */
public static TypePredicate isDescendantOfAny(Iterable<String> types) {
return new DescendantOfAny(fromStrings(types));
}

/** Match sub-types of the given type. */
public static TypePredicate isDescendantOf(String type) {
return isDescendantOf(Suppliers.typeFromString(type));
}

/** Match types that are a sub-type of one of the given types. */
public static TypePredicate isDescendantOfAny(Iterable<String> types) {
return new DescendantOfAny(fromStrings(types));
}

public static TypePredicate allOf(TypePredicate... predicates) {
return (type, state) -> {
for (TypePredicate predicate : predicates) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ public ScannerSupplier applyOverrides(ErrorProneOptions errorProneOptions) {
&& !errorProneOptions.isEnableAllChecksAsWarnings()
&& !errorProneOptions.isDropErrorsToWarnings()
&& !errorProneOptions.isDisableAllChecks()
&& !errorProneOptions.isDisableAllWarnings()) {
&& !errorProneOptions.isDisableAllWarnings()
&& !errorProneOptions.isSuggestionsAsWarnings()) {
return this;
}

Expand All @@ -168,6 +169,12 @@ public ScannerSupplier applyOverrides(ErrorProneOptions errorProneOptions) {
.forEach(c -> severities.put(c.canonicalName(), SeverityLevel.WARNING));
}

if (errorProneOptions.isSuggestionsAsWarnings()) {
getAllChecks().values().stream()
.filter(c -> c.defaultSeverity() == SeverityLevel.SUGGESTION)
.forEach(c -> severities.put(c.canonicalName(), SeverityLevel.WARNING));
}

if (errorProneOptions.isDisableAllWarnings()) {
checks.values().stream()
.filter(c -> c.defaultSeverity() == SeverityLevel.WARNING)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ public void recognizesDemoteErrorToWarning() {
assertThat(options.isDropErrorsToWarnings()).isTrue();
}

@Test
public void recognizesAllSuggestionsAsWarnings() {
ErrorProneOptions options =
ErrorProneOptions.processArgs(new String[] {"-XepAllSuggestionsAsWarnings"});
assertThat(options.isSuggestionsAsWarnings()).isTrue();
}

@Test
public void recognizesDisableAllChecks() {
ErrorProneOptions options =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public class ASTHelpersSuggestions extends BugChecker implements MethodInvocatio
anyOf(
instanceMethod()
.onDescendantOf("com.sun.tools.javac.code.Symbol")
.namedAnyOf("isDirectlyOrIndirectlyLocal", "isLocal", "packge"),
.namedAnyOf(
"isDirectlyOrIndirectlyLocal", "isLocal", "packge", "getEnclosedElements"),
instanceMethod()
.onClass((t, s) -> isSubtype(MODULE_SYMBOL.get(s), t, s))
.namedAnyOf("isStatic"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2023 The Error Prone Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.errorprone.bugpatterns;

import com.google.errorprone.VisitorState;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.sun.source.tree.Tree;

/** An abstract class that detects use of the unsafe APIs. */
public abstract class AbstractBanUnsafeAPIChecker extends BugChecker {

protected <T extends Tree> Description matchHelper(
T tree, VisitorState state, Matcher<T> matcher) {
if (state.errorProneOptions().isTestOnlyTarget() || !matcher.matches(tree, state)) {
return Description.NO_MATCH;
}

Description.Builder description = buildDescription(tree);

return description.build();
}
}
Loading

0 comments on commit 2ecedd4

Please sign in to comment.