├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .idea ├── .name ├── GoogleStyle.xml ├── copyright │ ├── Google.xml │ └── profiles_settings.xml ├── google-java-format.xml ├── projectCodeStyle.xml └── vcs.xml ├── AUTHORS ├── CONTRIBUTING.md ├── COPYING ├── KEYS.txt ├── README.md ├── annotation ├── .classpath ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── google │ │ └── errorprone │ │ ├── BugPattern.java │ │ ├── BugPatternValidator.java │ │ └── ValidationException.java │ └── test │ └── java │ └── com │ └── google │ └── errorprone │ └── BugPatternValidatorTest.java ├── annotations ├── pom.xml └── src │ └── main │ └── java │ ├── com │ └── google │ │ └── errorprone │ │ └── annotations │ │ ├── CanIgnoreReturnValue.java │ │ ├── CheckReturnValue.java │ │ ├── CompatibleWith.java │ │ ├── CompileTimeConstant.java │ │ ├── DoNotCall.java │ │ ├── DoNotMock.java │ │ ├── ForOverride.java │ │ ├── FormatMethod.java │ │ ├── FormatString.java │ │ ├── Immutable.java │ │ ├── ImmutableTypeParameter.java │ │ ├── IncompatibleModifiers.java │ │ ├── InlineMe.java │ │ ├── InlineMeValidationDisabled.java │ │ ├── Keep.java │ │ ├── Modifier.java │ │ ├── MustBeClosed.java │ │ ├── NoAllocation.java │ │ ├── OverridingMethodsMustInvokeSuper.java │ │ ├── RequiredModifiers.java │ │ ├── RestrictedApi.java │ │ ├── SuppressPackageLocation.java │ │ ├── ThreadSafe.java │ │ ├── ThreadSafeTypeParameter.java │ │ ├── Var.java │ │ └── concurrent │ │ ├── GuardedBy.java │ │ ├── LazyInit.java │ │ ├── LockMethod.java │ │ └── UnlockMethod.java │ └── module-info.java ├── appveyor.yml ├── bnd.bnd ├── check_api ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── google │ │ │ └── errorprone │ │ │ ├── BaseErrorProneJavaCompiler.java │ │ │ ├── BugCheckerInfo.java │ │ │ ├── CodeTransformer.java │ │ │ ├── CompositeCodeTransformer.java │ │ │ ├── DescriptionListener.java │ │ │ ├── ErrorProneAnalyzer.java │ │ │ ├── ErrorProneError.java │ │ │ ├── ErrorProneFlags.java │ │ │ ├── ErrorProneOptions.java │ │ │ ├── ErrorPronePlugins.java │ │ │ ├── ErrorProneTimings.java │ │ │ ├── ErrorProneVersion.java │ │ │ ├── ImportOrderParser.java │ │ │ ├── InvalidCommandLineOptionException.java │ │ │ ├── JavacErrorDescriptionListener.java │ │ │ ├── JavacInvocationInstance.java │ │ │ ├── MaskedClassLoader.java │ │ │ ├── RefactoringCollection.java │ │ │ ├── StatisticsCollector.java │ │ │ ├── SubContext.java │ │ │ ├── SuppressionInfo.java │ │ │ ├── VisitorState.java │ │ │ ├── apply │ │ │ ├── AndroidImportOrganizer.java │ │ │ ├── BasicImportOrganizer.java │ │ │ ├── DescriptionBasedDiff.java │ │ │ ├── Diff.java │ │ │ ├── DiffApplier.java │ │ │ ├── DiffSupplier.java │ │ │ ├── DiscardingFileDestination.java │ │ │ ├── FileDestination.java │ │ │ ├── FileSource.java │ │ │ ├── FsFileDestination.java │ │ │ ├── FsFileSource.java │ │ │ ├── IdeaImportOrganizer.java │ │ │ ├── ImportOrganizer.java │ │ │ ├── ImportStatements.java │ │ │ ├── PatchFileDestination.java │ │ │ ├── SourceFile.java │ │ │ └── StaticOrder.java │ │ │ ├── bugpatterns │ │ │ └── BugChecker.java │ │ │ ├── dataflow │ │ │ ├── AccessPath.java │ │ │ ├── AccessPathStore.java │ │ │ ├── AccessPathValues.java │ │ │ ├── ConstantPropagationAnalysis.java │ │ │ ├── DataFlow.java │ │ │ └── nullnesspropagation │ │ │ │ ├── AbstractNullnessPropagationTransfer.java │ │ │ │ ├── MethodInfo.java │ │ │ │ ├── Nullness.java │ │ │ │ ├── NullnessAnalysis.java │ │ │ │ ├── NullnessAnnotations.java │ │ │ │ ├── NullnessPropagationTransfer.java │ │ │ │ ├── TrustingNullnessAnalysis.java │ │ │ │ ├── TrustingNullnessPropagation.java │ │ │ │ └── inference │ │ │ │ ├── InferenceVariable.java │ │ │ │ ├── InferredNullability.java │ │ │ │ ├── NullnessQualifierInference.java │ │ │ │ ├── ProperInferenceVar.java │ │ │ │ ├── TypeArgInferenceVar.java │ │ │ │ └── TypeVariableInferenceVar.java │ │ │ ├── errors.properties │ │ │ ├── fixes │ │ │ ├── AdjustedPosition.java │ │ │ ├── AppliedFix.java │ │ │ ├── BranchedSuggestedFixes.java │ │ │ ├── Fix.java │ │ │ ├── FixedPosition.java │ │ │ ├── IndexedPosition.java │ │ │ ├── Replacement.java │ │ │ ├── Replacements.java │ │ │ ├── SuggestedFix.java │ │ │ ├── SuggestedFixes.java │ │ │ └── package-info.java │ │ │ ├── matchers │ │ │ ├── AbstractTypeMatcher.java │ │ │ ├── AnnotationDoesNotHaveArgument.java │ │ │ ├── AnnotationHasArgumentWithValue.java │ │ │ ├── AnnotationMatcher.java │ │ │ ├── AnnotationMatcherUtils.java │ │ │ ├── AnnotationType.java │ │ │ ├── Asserts.java │ │ │ ├── ChildMultiMatcher.java │ │ │ ├── CompileTimeConstantExpressionMatcher.java │ │ │ ├── CompoundAssignment.java │ │ │ ├── ConstructorOfClass.java │ │ │ ├── Contains.java │ │ │ ├── Description.java │ │ │ ├── Enclosing.java │ │ │ ├── FieldMatchers.java │ │ │ ├── HasArguments.java │ │ │ ├── HasIdentifier.java │ │ │ ├── InjectMatchers.java │ │ │ ├── IsNonNullMatcher.java │ │ │ ├── IsSameType.java │ │ │ ├── IsSubtypeOf.java │ │ │ ├── IsSymbol.java │ │ │ ├── JUnitMatchers.java │ │ │ ├── Matcher.java │ │ │ ├── Matchers.java │ │ │ ├── MethodHasParameters.java │ │ │ ├── MethodInvocation.java │ │ │ ├── MethodInvocationArgument.java │ │ │ ├── MethodVisibility.java │ │ │ ├── MultiMatcher.java │ │ │ ├── NullnessMatcher.java │ │ │ ├── Returns.java │ │ │ ├── StringLiteral.java │ │ │ ├── Suppressible.java │ │ │ ├── TestNgMatchers.java │ │ │ ├── Throws.java │ │ │ ├── UnusedReturnValueMatcher.java │ │ │ ├── WaitMatchers.java │ │ │ ├── method │ │ │ │ ├── BaseMethodMatcher.java │ │ │ │ ├── ConstructorMatchState.java │ │ │ │ ├── MatchState.java │ │ │ │ ├── MethodInvocationMatcher.java │ │ │ │ ├── MethodMatchState.java │ │ │ │ ├── MethodMatcherImpl.java │ │ │ │ └── MethodMatchers.java │ │ │ └── package-info.java │ │ │ ├── names │ │ │ ├── LevenshteinEditDistance.java │ │ │ ├── NamingConventions.java │ │ │ ├── NeedlemanWunschEditDistance.java │ │ │ └── TermEditDistance.java │ │ │ ├── predicates │ │ │ ├── TypePredicate.java │ │ │ ├── TypePredicates.java │ │ │ └── type │ │ │ │ ├── Array.java │ │ │ │ ├── DescendantOf.java │ │ │ │ ├── DescendantOfAny.java │ │ │ │ ├── Exact.java │ │ │ │ └── ExactAny.java │ │ │ ├── scanner │ │ │ ├── ErrorProneInjector.java │ │ │ ├── ErrorProneScanner.java │ │ │ ├── ErrorProneScannerTransformer.java │ │ │ ├── InstanceReturningScannerSupplierImpl.java │ │ │ ├── Scanner.java │ │ │ ├── ScannerSupplier.java │ │ │ └── ScannerSupplierImpl.java │ │ │ ├── suppliers │ │ │ ├── Supplier.java │ │ │ ├── Suppliers.java │ │ │ └── package-info.java │ │ │ └── util │ │ │ ├── ASTHelpers.java │ │ │ ├── AnnotationNames.java │ │ │ ├── Commented.java │ │ │ ├── Comments.java │ │ │ ├── ErrorProneComment.java │ │ │ ├── ErrorProneLog.java │ │ │ ├── ErrorProneSignatureGenerator.java │ │ │ ├── ErrorProneToken.java │ │ │ ├── ErrorProneTokens.java │ │ │ ├── FindIdentifiers.java │ │ │ ├── MoreAnnotations.java │ │ │ ├── OperatorPrecedence.java │ │ │ ├── Reachability.java │ │ │ ├── Regexes.java │ │ │ ├── SideEffectAnalysis.java │ │ │ ├── Signatures.java │ │ │ ├── SourceCodeEscapers.java │ │ │ ├── SourceVersion.java │ │ │ ├── TargetType.java │ │ │ ├── Visibility.java │ │ │ └── package-info.java │ └── java24 │ │ └── com │ │ └── google │ │ └── errorprone │ │ └── util │ │ └── ErrorProneSignatureGenerator.java │ └── test │ └── java │ └── com │ └── google │ └── errorprone │ ├── ErrorProneFlagsTest.java │ ├── ErrorProneOptionsTest.java │ ├── apply │ ├── AndroidImportOrganizerTest.java │ ├── BasicImportOrganizerTest.java │ ├── IdeaImportOrganizerTest.java │ ├── OrganizedImportsTest.java │ └── SourceFileTest.java │ ├── dataflow │ ├── AccessPathStoreTest.java │ └── nullnesspropagation │ │ ├── NonNullAssumptionsTest.java │ │ └── NullnessTest.java │ ├── fixes │ ├── AppliedFixTest.java │ ├── BranchedSuggestedFixesTest.java │ └── ReplacementsTest.java │ ├── matchers │ ├── DescriptionTest.java │ └── StringLiteralTest.java │ ├── names │ ├── NamingConventionsTest.java │ ├── NeedlemanWunschEditDistanceTest.java │ └── TermEditDistanceTest.java │ ├── scanner │ └── ErrorProneInjectorTest.java │ └── util │ ├── ASTHelpersFindSuperMethodsTest.java │ ├── ASTHelpersTest.java │ ├── CommentsTest.java │ ├── FindIdentifiersTest.java │ ├── InheritedAnnotation.java │ ├── MoreAnnotationsTest.java │ ├── ReachabilityTest.java │ ├── RegexesTest.java │ ├── SignaturesTest.java │ ├── SourceVersionTest.java │ ├── TargetTypeTest.java │ └── testdata │ └── TargetTypeTest.java ├── core ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── google │ │ │ └── errorprone │ │ │ ├── ErrorProneJavaCompiler.java │ │ │ ├── ErrorProneJavacPlugin.java │ │ │ ├── bugpatterns │ │ │ ├── ASTHelpersSuggestions.java │ │ │ ├── AbstractAsKeyOfSetOrMap.java │ │ │ ├── AbstractAsyncTypeReturnsNull.java │ │ │ ├── AbstractBanUnsafeAPIChecker.java │ │ │ ├── AbstractJUnit4InitMethodNotRun.java │ │ │ ├── AbstractMethodReturnsNull.java │ │ │ ├── AbstractMockChecker.java │ │ │ ├── AbstractMustBeClosedChecker.java │ │ │ ├── AbstractPatternSyntaxChecker.java │ │ │ ├── AbstractReferenceEquality.java │ │ │ ├── AbstractReturnValueIgnored.java │ │ │ ├── AbstractToString.java │ │ │ ├── AbstractUseSwitch.java │ │ │ ├── AddressSelection.java │ │ │ ├── AlreadyChecked.java │ │ │ ├── AlwaysThrows.java │ │ │ ├── AmbiguousMethodReference.java │ │ │ ├── AnnotationMirrorToString.java │ │ │ ├── AnnotationPosition.java │ │ │ ├── AnnotationValueToString.java │ │ │ ├── ArrayAsKeyOfSetOrMap.java │ │ │ ├── ArrayEquals.java │ │ │ ├── ArrayFillIncompatibleType.java │ │ │ ├── ArrayHashCode.java │ │ │ ├── ArrayRecordComponent.java │ │ │ ├── ArrayToString.java │ │ │ ├── ArraysAsListPrimitiveArray.java │ │ │ ├── AssertFalse.java │ │ │ ├── AssertThrowsMultipleStatements.java │ │ │ ├── AssertThrowsUtils.java │ │ │ ├── AssertionFailureIgnored.java │ │ │ ├── AssignmentExpression.java │ │ │ ├── AsyncCallableReturnsNull.java │ │ │ ├── AsyncFunctionReturnsNull.java │ │ │ ├── AttemptedNegativeZero.java │ │ │ ├── AutoValueBoxedValues.java │ │ │ ├── AutoValueBuilderDefaultsInConstructor.java │ │ │ ├── AutoValueFinalMethods.java │ │ │ ├── AutoValueImmutableFields.java │ │ │ ├── AutoValueSubclassLeaked.java │ │ │ ├── AvoidObjectArrays.java │ │ │ ├── BadAnnotationImplementation.java │ │ │ ├── BadComparable.java │ │ │ ├── BadImport.java │ │ │ ├── BadInstanceof.java │ │ │ ├── BadShiftAmount.java │ │ │ ├── BanClassLoader.java │ │ │ ├── BanJNDI.java │ │ │ ├── BanSerializableRead.java │ │ │ ├── BareDotMetacharacter.java │ │ │ ├── BigDecimalEquals.java │ │ │ ├── BigDecimalLiteralDouble.java │ │ │ ├── BooleanLiteral.java │ │ │ ├── BooleanParameter.java │ │ │ ├── BoxedPrimitiveConstructor.java │ │ │ ├── BoxedPrimitiveEquality.java │ │ │ ├── BugPatternNaming.java │ │ │ ├── ByteBufferBackingArray.java │ │ │ ├── CacheLoaderNull.java │ │ │ ├── CanBeStaticAnalyzer.java │ │ │ ├── CannotMockFinalClass.java │ │ │ ├── CannotMockMethod.java │ │ │ ├── CanonicalDuration.java │ │ │ ├── CatchAndPrintStackTrace.java │ │ │ ├── CatchFail.java │ │ │ ├── CatchingUnchecked.java │ │ │ ├── ChainedAssertionLosesContext.java │ │ │ ├── ChainingConstructorIgnoresParameter.java │ │ │ ├── CharacterGetNumericValue.java │ │ │ ├── CheckNotNullMultipleTimes.java │ │ │ ├── CheckReturnValue.java │ │ │ ├── CheckedExceptionNotThrown.java │ │ │ ├── ClassCanBeStatic.java │ │ │ ├── ClassInitializationDeadlock.java │ │ │ ├── ClassName.java │ │ │ ├── ClassNamedLikeTypeParameter.java │ │ │ ├── ClassNewInstance.java │ │ │ ├── CloseableDecoratorTypes.java │ │ │ ├── ClosingStandardOutputStreams.java │ │ │ ├── CollectionToArraySafeParameter.java │ │ │ ├── CollectorShouldNotUseState.java │ │ │ ├── ComparableAndComparator.java │ │ │ ├── ComparableType.java │ │ │ ├── CompareToZero.java │ │ │ ├── ComparingThisWithNull.java │ │ │ ├── ComparisonContractViolated.java │ │ │ ├── ComparisonOutOfRange.java │ │ │ ├── CompileTimeConstantChecker.java │ │ │ ├── ComplexBooleanConstant.java │ │ │ ├── ComputeIfAbsentAmbiguousReference.java │ │ │ ├── ConditionalExpressionNumericPromotion.java │ │ │ ├── ConstantField.java │ │ │ ├── ConstantOverflow.java │ │ │ ├── ConstantPatternCompile.java │ │ │ ├── DangerousLiteralNullChecker.java │ │ │ ├── DateFormatConstant.java │ │ │ ├── DeadException.java │ │ │ ├── DeadThread.java │ │ │ ├── DeduplicateConstants.java │ │ │ ├── DeeplyNested.java │ │ │ ├── DefaultCharset.java │ │ │ ├── DefaultLocale.java │ │ │ ├── DefaultPackage.java │ │ │ ├── DepAnn.java │ │ │ ├── DeprecatedVariable.java │ │ │ ├── DifferentNameButSame.java │ │ │ ├── DirectInvocationOnMock.java │ │ │ ├── DiscardedPostfixExpression.java │ │ │ ├── DistinctVarargsChecker.java │ │ │ ├── DoNotCallChecker.java │ │ │ ├── DoNotCallSuggester.java │ │ │ ├── DoNotClaimAnnotations.java │ │ │ ├── DoNotMockAutoValue.java │ │ │ ├── DoNotMockChecker.java │ │ │ ├── DoubleBraceInitialization.java │ │ │ ├── DuplicateBranches.java │ │ │ ├── DuplicateDateFormatField.java │ │ │ ├── DuplicateMapKeys.java │ │ │ ├── EmptyCatch.java │ │ │ ├── EmptyIfStatement.java │ │ │ ├── EmptyTopLevelDeclaration.java │ │ │ ├── EnumOrdinal.java │ │ │ ├── EqualsGetClass.java │ │ │ ├── EqualsHashCode.java │ │ │ ├── EqualsIncompatibleType.java │ │ │ ├── EqualsNaN.java │ │ │ ├── EqualsNull.java │ │ │ ├── EqualsReference.java │ │ │ ├── EqualsUnsafeCast.java │ │ │ ├── EqualsUsingHashCode.java │ │ │ ├── EqualsWrongThing.java │ │ │ ├── ErroneousBitwiseExpression.java │ │ │ ├── ErroneousThreadPoolConstructorChecker.java │ │ │ ├── ExpectedExceptionChecker.java │ │ │ ├── ExtendingJUnitAssert.java │ │ │ ├── ExtendsAutoValue.java │ │ │ ├── FallThrough.java │ │ │ ├── FieldCanBeFinal.java │ │ │ ├── FieldCanBeLocal.java │ │ │ ├── FieldCanBeStatic.java │ │ │ ├── Finalize.java │ │ │ ├── Finally.java │ │ │ ├── FloatCast.java │ │ │ ├── FloatingPointAssertionWithinEpsilon.java │ │ │ ├── FloatingPointLiteralPrecision.java │ │ │ ├── ForEachIterable.java │ │ │ ├── ForOverrideChecker.java │ │ │ ├── FunctionalInterfaceClash.java │ │ │ ├── FunctionalInterfaceMethodChanged.java │ │ │ ├── FutureReturnValueIgnored.java │ │ │ ├── FutureTransformAsync.java │ │ │ ├── FuturesGetCheckedIllegalExceptionType.java │ │ │ ├── FuzzyEqualsShouldNotBeUsedInEqualsMethod.java │ │ │ ├── GetClassOnAnnotation.java │ │ │ ├── GetClassOnClass.java │ │ │ ├── GetClassOnEnum.java │ │ │ ├── GuiceNestedCombine.java │ │ │ ├── HashtableContains.java │ │ │ ├── HidingField.java │ │ │ ├── ICCProfileGetInstance.java │ │ │ ├── IdentifierName.java │ │ │ ├── IdentityBinaryExpression.java │ │ │ ├── IdentityHashMapBoxing.java │ │ │ ├── IdentityHashMapUsage.java │ │ │ ├── IgnoredPureGetter.java │ │ │ ├── ImmutableCollections.java │ │ │ ├── ImmutableMemberCollection.java │ │ │ ├── ImmutableSetForContains.java │ │ │ ├── ImplementAssertionWithChaining.java │ │ │ ├── ImpossibleNullComparison.java │ │ │ ├── Incomparable.java │ │ │ ├── IncompatibleModifiersChecker.java │ │ │ ├── InconsistentCapitalization.java │ │ │ ├── InconsistentHashCode.java │ │ │ ├── IncorrectMainMethod.java │ │ │ ├── IncrementInForLoopAndHeader.java │ │ │ ├── IndexOfChar.java │ │ │ ├── InexactVarargsConditional.java │ │ │ ├── InfiniteRecursion.java │ │ │ ├── InitializeInline.java │ │ │ ├── InjectOnBugCheckers.java │ │ │ ├── InlineTrivialConstant.java │ │ │ ├── InputStreamSlowMultibyteRead.java │ │ │ ├── InsecureCipherMode.java │ │ │ ├── InstanceOfAndCastMatchWrongType.java │ │ │ ├── IntFloatConversion.java │ │ │ ├── IntLiteralCast.java │ │ │ ├── IntLongMath.java │ │ │ ├── InterfaceWithOnlyStatics.java │ │ │ ├── InterruptedExceptionSwallowed.java │ │ │ ├── Interruption.java │ │ │ ├── InvalidPatternSyntax.java │ │ │ ├── InvalidTimeZoneID.java │ │ │ ├── InvalidZoneId.java │ │ │ ├── IsInstanceIncompatibleType.java │ │ │ ├── IsInstanceOfClass.java │ │ │ ├── IterableAndIterator.java │ │ │ ├── IterablePathParameter.java │ │ │ ├── JUnit3FloatingPointComparisonWithoutDelta.java │ │ │ ├── JUnit3TestNotRun.java │ │ │ ├── JUnit4ClassAnnotationNonStatic.java │ │ │ ├── JUnit4ClassUsedInJUnit3.java │ │ │ ├── JUnit4EmptyMethods.java │ │ │ ├── JUnit4SetUpNotRun.java │ │ │ ├── JUnit4TearDownNotRun.java │ │ │ ├── JUnit4TestNotRun.java │ │ │ ├── JUnit4TestsNotRunWithinEnclosed.java │ │ │ ├── JUnitAmbiguousTestClass.java │ │ │ ├── JUnitAssertSameCheck.java │ │ │ ├── JUnitParameterMethodNotFound.java │ │ │ ├── JavaLangClash.java │ │ │ ├── JavaUtilDateChecker.java │ │ │ ├── JdkObsolete.java │ │ │ ├── LabelledBreakTarget.java │ │ │ ├── LambdaFunctionalInterface.java │ │ │ ├── LiteByteStringUtf8.java │ │ │ ├── LiteEnumValueOf.java │ │ │ ├── LiteProtoToString.java │ │ │ ├── LockNotBeforeTry.java │ │ │ ├── LockOnBoxedPrimitive.java │ │ │ ├── LockOnNonEnclosingClassLiteral.java │ │ │ ├── LogicalAssignment.java │ │ │ ├── LongDoubleConversion.java │ │ │ ├── LongFloatConversion.java │ │ │ ├── LongLiteralLowerCaseSuffix.java │ │ │ ├── LoopConditionChecker.java │ │ │ ├── LoopOverCharArray.java │ │ │ ├── LossyPrimitiveCompare.java │ │ │ ├── MathAbsoluteNegative.java │ │ │ ├── MathRoundIntLong.java │ │ │ ├── MemoizeConstantVisitorStateLookups.java │ │ │ ├── MethodCanBeStatic.java │ │ │ ├── MisformattedTestData.java │ │ │ ├── MisleadingEmptyVarargs.java │ │ │ ├── MisleadingEscapedSpace.java │ │ │ ├── MissingBraces.java │ │ │ ├── MissingCasesInEnumSwitch.java │ │ │ ├── MissingDefault.java │ │ │ ├── MissingFail.java │ │ │ ├── MissingImplementsComparable.java │ │ │ ├── MissingOverride.java │ │ │ ├── MissingRefasterAnnotation.java │ │ │ ├── MissingSuperCall.java │ │ │ ├── MissingTestCall.java │ │ │ ├── MisusedDateFormat.java │ │ │ ├── MisusedDayOfYear.java │ │ │ ├── MisusedWeekYear.java │ │ │ ├── MixedArrayDimensions.java │ │ │ ├── MixedDescriptors.java │ │ │ ├── MixedMutabilityReturnType.java │ │ │ ├── MockIllegalThrows.java │ │ │ ├── MockNotUsedInProduction.java │ │ │ ├── MockitoDoSetup.java │ │ │ ├── MockitoUsage.java │ │ │ ├── ModifiedButNotUsed.java │ │ │ ├── ModifyCollectionInEnhancedForLoop.java │ │ │ ├── ModifySourceCollectionInStream.java │ │ │ ├── ModifyingCollectionWithItself.java │ │ │ ├── MultiVariableDeclaration.java │ │ │ ├── MultimapKeys.java │ │ │ ├── MultipleParallelOrSequentialCalls.java │ │ │ ├── MultipleTopLevelClasses.java │ │ │ ├── MultipleUnaryOperatorsInMethodCall.java │ │ │ ├── MustBeClosedChecker.java │ │ │ ├── MutableGuiceModule.java │ │ │ ├── MutablePublicArray.java │ │ │ ├── NCopiesOfChar.java │ │ │ ├── NamedLikeContextualKeyword.java │ │ │ ├── NarrowCalculation.java │ │ │ ├── NarrowingCompoundAssignment.java │ │ │ ├── NegativeBoolean.java │ │ │ ├── NegativeCharLiteral.java │ │ │ ├── NestedInstanceOfConditions.java │ │ │ ├── NewFileSystem.java │ │ │ ├── NoAllocationChecker.java │ │ │ ├── NonApiType.java │ │ │ ├── NonAtomicVolatileUpdate.java │ │ │ ├── NonCanonicalStaticImport.java │ │ │ ├── NonCanonicalStaticMemberImport.java │ │ │ ├── NonCanonicalType.java │ │ │ ├── NonFinalCompileTimeConstant.java │ │ │ ├── NonFinalStaticField.java │ │ │ ├── NonOverridingEquals.java │ │ │ ├── NonRuntimeAnnotation.java │ │ │ ├── NullOptional.java │ │ │ ├── NullTernary.java │ │ │ ├── NullableConstructor.java │ │ │ ├── NullableOnContainingClass.java │ │ │ ├── NullableOptional.java │ │ │ ├── NullableVoid.java │ │ │ ├── ObjectEqualsForPrimitives.java │ │ │ ├── ObjectToString.java │ │ │ ├── ObjectsHashCodePrimitive.java │ │ │ ├── OperatorPrecedence.java │ │ │ ├── OptionalEquality.java │ │ │ ├── OptionalMapToOptional.java │ │ │ ├── OptionalMapUnusedValue.java │ │ │ ├── OptionalNotPresent.java │ │ │ ├── OptionalOfRedundantMethod.java │ │ │ ├── OrphanedFormatString.java │ │ │ ├── OutlineNone.java │ │ │ ├── OverrideThrowableToString.java │ │ │ ├── Overrides.java │ │ │ ├── OverridingMethodInconsistentArgumentNamesChecker.java │ │ │ ├── PackageInfo.java │ │ │ ├── PackageLocation.java │ │ │ ├── ParameterComment.java │ │ │ ├── ParameterName.java │ │ │ ├── ParametersButNotParameterized.java │ │ │ ├── PatternMatchingInstanceof.java │ │ │ ├── PreconditionsCheckNotNullRepeated.java │ │ │ ├── PreconditionsExpensiveString.java │ │ │ ├── PreconditionsInvalidPlaceholder.java │ │ │ ├── PreferInstanceofOverGetKind.java │ │ │ ├── PreferredInterfaceType.java │ │ │ ├── PrimitiveArrayPassedToVarargsMethod.java │ │ │ ├── PrimitiveAtomicReference.java │ │ │ ├── PrivateConstructorForUtilityClass.java │ │ │ ├── PrivateSecurityContractProtoAccess.java │ │ │ ├── ProtectedMembersInFinalClass.java │ │ │ ├── ProtoBuilderReturnValueIgnored.java │ │ │ ├── ProtoStringFieldReferenceEquality.java │ │ │ ├── ProtoTruthMixedDescriptors.java │ │ │ ├── ProtocolBufferOrdinal.java │ │ │ ├── PublicApiNamedStreamShouldReturnStream.java │ │ │ ├── RandomCast.java │ │ │ ├── RandomModInteger.java │ │ │ ├── ReachabilityFenceUsage.java │ │ │ ├── RedundantControlFlow.java │ │ │ ├── RedundantOverride.java │ │ │ ├── RedundantSetterCall.java │ │ │ ├── RedundantThrows.java │ │ │ ├── ReferenceEquality.java │ │ │ ├── RemoveUnusedImports.java │ │ │ ├── ReplacementVariableFinder.java │ │ │ ├── RequiredModifiersChecker.java │ │ │ ├── RestrictedApiChecker.java │ │ │ ├── RethrowReflectiveOperationExceptionAsLinkageError.java │ │ │ ├── ReturnAtTheEndOfVoidFunction.java │ │ │ ├── ReturnValueIgnored.java │ │ │ ├── ReturnsNullCollection.java │ │ │ ├── RobolectricShadowDirectlyOn.java │ │ │ ├── RuleNotRun.java │ │ │ ├── RxReturnValueIgnored.java │ │ │ ├── SameNameButDifferent.java │ │ │ ├── SelfAlwaysReturnsThis.java │ │ │ ├── SelfAssertion.java │ │ │ ├── SelfAssignment.java │ │ │ ├── SelfComparison.java │ │ │ ├── SelfEquals.java │ │ │ ├── SelfSet.java │ │ │ ├── SerializableReads.java │ │ │ ├── SetUnrecognized.java │ │ │ ├── ShortCircuitBoolean.java │ │ │ ├── ShouldHaveEvenArgs.java │ │ │ ├── SizeGreaterThanOrEqualsZero.java │ │ │ ├── StatementSwitchToExpressionSwitch.java │ │ │ ├── StaticAssignmentInConstructor.java │ │ │ ├── StaticAssignmentOfThrowable.java │ │ │ ├── StaticImports.java │ │ │ ├── StaticMockMember.java │ │ │ ├── StaticQualifiedUsingExpression.java │ │ │ ├── StreamResourceLeak.java │ │ │ ├── StreamToIterable.java │ │ │ ├── StreamToString.java │ │ │ ├── StringBuilderInitWithChar.java │ │ │ ├── StringCaseLocaleUsage.java │ │ │ ├── StringCharset.java │ │ │ ├── StringConcatToTextBlock.java │ │ │ ├── StringFormatWithLiteral.java │ │ │ ├── StringSplitter.java │ │ │ ├── StronglyType.java │ │ │ ├── StronglyTypeByteString.java │ │ │ ├── SubstringOfZero.java │ │ │ ├── SunApi.java │ │ │ ├── SuperCallToObjectMethod.java │ │ │ ├── SuppressWarningsDeprecated.java │ │ │ ├── SuppressWarningsWithoutExplanation.java │ │ │ ├── SwigMemoryLeak.java │ │ │ ├── SwitchDefault.java │ │ │ ├── Switches.java │ │ │ ├── SymbolToString.java │ │ │ ├── SystemConsoleNull.java │ │ │ ├── SystemExitOutsideMain.java │ │ │ ├── SystemOut.java │ │ │ ├── TestExceptionChecker.java │ │ │ ├── TestParametersNotInitialized.java │ │ │ ├── TheoryButNoTheories.java │ │ │ ├── ThreadJoinLoop.java │ │ │ ├── ThreadLocalUsage.java │ │ │ ├── ThreeLetterTimeZoneID.java │ │ │ ├── ThrowIfUncheckedKnownChecked.java │ │ │ ├── ThrowIfUncheckedKnownUnchecked.java │ │ │ ├── ThrowNull.java │ │ │ ├── ThrowSpecificExceptions.java │ │ │ ├── ThrowsUncheckedException.java │ │ │ ├── ToStringReturnsNull.java │ │ │ ├── TooManyParameters.java │ │ │ ├── TraditionalSwitchExpression.java │ │ │ ├── TransientMisuse.java │ │ │ ├── TreeToString.java │ │ │ ├── TruthAssertExpected.java │ │ │ ├── TruthConstantAsserts.java │ │ │ ├── TruthContainsExactlyElementsInUsage.java │ │ │ ├── TruthGetOrDefault.java │ │ │ ├── TryFailRefactoring.java │ │ │ ├── TryFailThrowable.java │ │ │ ├── TryWithResourcesVariable.java │ │ │ ├── TypeCompatibility.java │ │ │ ├── TypeEqualsChecker.java │ │ │ ├── TypeNameShadowing.java │ │ │ ├── TypeParameterNaming.java │ │ │ ├── TypeParameterQualifier.java │ │ │ ├── TypeParameterShadowing.java │ │ │ ├── TypeParameterUnusedInFormals.java │ │ │ ├── TypeToString.java │ │ │ ├── TypesWithUndefinedEquality.java │ │ │ ├── URLEqualsHashCode.java │ │ │ ├── UndefinedEquals.java │ │ │ ├── UngroupedOverloads.java │ │ │ ├── UnicodeDirectionalityCharacters.java │ │ │ ├── UnicodeEscape.java │ │ │ ├── UnicodeInCode.java │ │ │ ├── UnnecessarilyFullyQualified.java │ │ │ ├── UnnecessarilyVisible.java │ │ │ ├── UnnecessaryAnonymousClass.java │ │ │ ├── UnnecessaryAssignment.java │ │ │ ├── UnnecessaryAsync.java │ │ │ ├── UnnecessaryBoxedAssignment.java │ │ │ ├── UnnecessaryBoxedVariable.java │ │ │ ├── UnnecessaryBreakInSwitch.java │ │ │ ├── UnnecessaryCopy.java │ │ │ ├── UnnecessaryDefaultInEnumSwitch.java │ │ │ ├── UnnecessaryFinal.java │ │ │ ├── UnnecessaryLambda.java │ │ │ ├── UnnecessaryLongToIntConversion.java │ │ │ ├── UnnecessaryMethodInvocationMatcher.java │ │ │ ├── UnnecessaryMethodReference.java │ │ │ ├── UnnecessaryOptionalGet.java │ │ │ ├── UnnecessaryParentheses.java │ │ │ ├── UnnecessaryQualifier.java │ │ │ ├── UnnecessarySetDefault.java │ │ │ ├── UnnecessaryStaticImport.java │ │ │ ├── UnnecessaryStringBuilder.java │ │ │ ├── UnnecessaryTestMethodPrefix.java │ │ │ ├── UnnecessaryTypeArgument.java │ │ │ ├── UnsafeFinalization.java │ │ │ ├── UnsafeLocaleUsage.java │ │ │ ├── UnsafeReflectiveConstructionCast.java │ │ │ ├── UnsynchronizedOverridesSynchronized.java │ │ │ ├── UnusedAnonymousClass.java │ │ │ ├── UnusedCollectionModifiedInPlace.java │ │ │ ├── UnusedException.java │ │ │ ├── UnusedLabel.java │ │ │ ├── UnusedMethod.java │ │ │ ├── UnusedNestedClass.java │ │ │ ├── UnusedTypeParameter.java │ │ │ ├── UnusedVariable.java │ │ │ ├── UseCorrectAssertInTests.java │ │ │ ├── UseEnumSwitch.java │ │ │ ├── VarChecker.java │ │ │ ├── VarTypeName.java │ │ │ ├── VariableNameSameAsType.java │ │ │ ├── Varifier.java │ │ │ ├── VoidUsed.java │ │ │ ├── WaitNotInLoop.java │ │ │ ├── WildcardImport.java │ │ │ ├── WithSignatureDiscouraged.java │ │ │ ├── WrongOneof.java │ │ │ ├── XorPower.java │ │ │ ├── YodaCondition.java │ │ │ ├── android │ │ │ │ ├── BinderIdentityRestoredDangerously.java │ │ │ │ ├── BundleDeserializationCast.java │ │ │ │ ├── FragmentInjection.java │ │ │ │ ├── FragmentNotInstantiable.java │ │ │ │ ├── HardCodedSdCardPath.java │ │ │ │ ├── IsLoggableTagLength.java │ │ │ │ ├── MislabeledAndroidString.java │ │ │ │ ├── ParcelableCreator.java │ │ │ │ ├── RectIntersectReturnValueIgnored.java │ │ │ │ ├── StaticOrDefaultInterfaceMethod.java │ │ │ │ └── WakelockReleasedDangerously.java │ │ │ ├── apidiff │ │ │ │ ├── 8to11diff.binarypb │ │ │ │ ├── AndroidJdkLibsChecker.java │ │ │ │ ├── ApiDiff.java │ │ │ │ ├── ApiDiffChecker.java │ │ │ │ ├── Java8ApiChecker.java │ │ │ │ ├── android.binarypb │ │ │ │ └── android_java8.binarypb │ │ │ ├── argumentselectiondefects │ │ │ │ ├── ArgumentChangeFinder.java │ │ │ │ ├── ArgumentSelectionDefectChecker.java │ │ │ │ ├── AssertEqualsArgumentOrderChecker.java │ │ │ │ ├── AutoValueConstructorOrderChecker.java │ │ │ │ ├── Changes.java │ │ │ │ ├── Costs.java │ │ │ │ ├── CreatesDuplicateCallHeuristic.java │ │ │ │ ├── EnclosedByReverseHeuristic.java │ │ │ │ ├── Heuristic.java │ │ │ │ ├── InvocationInfo.java │ │ │ │ ├── LowInformationNameHeuristic.java │ │ │ │ ├── Matchers.java │ │ │ │ ├── NameInCommentHeuristic.java │ │ │ │ ├── NamedParameterComment.java │ │ │ │ ├── Parameter.java │ │ │ │ ├── ParameterPair.java │ │ │ │ └── PenaltyThresholdHeuristic.java │ │ │ ├── build_defs.bzl │ │ │ ├── checkreturnvalue │ │ │ │ ├── Api.java │ │ │ │ ├── ApiFactory.java │ │ │ │ ├── AutoValueRules.java │ │ │ │ ├── BuilderReturnThis.java │ │ │ │ ├── CanIgnoreReturnValueSuggester.java │ │ │ │ ├── DaggerRules.java │ │ │ │ ├── ErrorMessages.java │ │ │ │ ├── ExternalCanIgnoreReturnValue.java │ │ │ │ ├── NoCanIgnoreReturnValueOnClasses.java │ │ │ │ ├── PackagesRule.java │ │ │ │ ├── ProtoRules.java │ │ │ │ ├── ResultUsePolicy.java │ │ │ │ ├── ResultUsePolicyAnalyzer.java │ │ │ │ ├── ResultUsePolicyEvaluator.java │ │ │ │ ├── ResultUseRule.java │ │ │ │ ├── Rules.java │ │ │ │ ├── UnnecessarilyUsedValue.java │ │ │ │ └── UsingJsr305CheckReturnValue.java │ │ │ ├── collectionincompatibletype │ │ │ │ ├── AbstractCollectionIncompatibleTypeMatcher.java │ │ │ │ ├── BinopMatcher.java │ │ │ │ ├── CollectionIncompatibleType.java │ │ │ │ ├── CollectionUndefinedEquality.java │ │ │ │ ├── CompatibleWithMisuse.java │ │ │ │ ├── ContainmentMatchers.java │ │ │ │ ├── IgnoringCasts.java │ │ │ │ ├── IncompatibleArgumentType.java │ │ │ │ ├── JUnitIncompatibleType.java │ │ │ │ ├── MethodArgMatcher.java │ │ │ │ ├── TruthIncompatibleType.java │ │ │ │ └── TypeArgOfMethodArgMatcher.java │ │ │ ├── flogger │ │ │ │ ├── FloggerArgumentToString.java │ │ │ │ ├── FloggerFormatString.java │ │ │ │ ├── FloggerHelpers.java │ │ │ │ ├── FloggerLogString.java │ │ │ │ ├── FloggerLogVarargs.java │ │ │ │ ├── FloggerLogWithCause.java │ │ │ │ ├── FloggerMessageFormat.java │ │ │ │ ├── FloggerRedundantIsEnabled.java │ │ │ │ ├── FloggerRequiredModifiers.java │ │ │ │ ├── FloggerSplitLogStatement.java │ │ │ │ ├── FloggerStringConcatenation.java │ │ │ │ ├── FloggerWithCause.java │ │ │ │ └── FloggerWithoutCause.java │ │ │ ├── formatstring │ │ │ │ ├── AnnotateFormatMethod.java │ │ │ │ ├── FormatString.java │ │ │ │ ├── FormatStringAnnotationChecker.java │ │ │ │ ├── FormatStringUtils.java │ │ │ │ ├── FormatStringValidation.java │ │ │ │ ├── InlineFormatString.java │ │ │ │ ├── LenientFormatStringUtils.java │ │ │ │ ├── LenientFormatStringValidation.java │ │ │ │ └── StrictFormatStringValidation.java │ │ │ ├── inject │ │ │ │ ├── AssistedInjectAndInjectOnConstructors.java │ │ │ │ ├── AssistedInjectAndInjectOnSameConstructor.java │ │ │ │ ├── AutoFactoryAtInject.java │ │ │ │ ├── CloseableProvides.java │ │ │ │ ├── ElementPredicates.java │ │ │ │ ├── InjectOnConstructorOfAbstractClass.java │ │ │ │ ├── InjectOnMemberAndConstructor.java │ │ │ │ ├── InjectedConstructorAnnotations.java │ │ │ │ ├── InvalidTargetingOnScopingAnnotation.java │ │ │ │ ├── JavaxInjectOnAbstractMethod.java │ │ │ │ ├── JavaxInjectOnFinalField.java │ │ │ │ ├── MisplacedScopeAnnotations.java │ │ │ │ ├── MissingRuntimeRetention.java │ │ │ │ ├── MoreThanOneInjectableConstructor.java │ │ │ │ ├── MoreThanOneQualifier.java │ │ │ │ ├── MoreThanOneScopeAnnotationOnClass.java │ │ │ │ ├── OverlappingQualifierAndScopeAnnotation.java │ │ │ │ ├── QualifierOrScopeOnInjectMethod.java │ │ │ │ ├── QualifierWithTypeUse.java │ │ │ │ ├── ScopeAnnotationOnInterfaceOrAbstractClass.java │ │ │ │ ├── dagger │ │ │ │ │ ├── AndroidInjectionBeforeSuper.java │ │ │ │ │ ├── DaggerAnnotations.java │ │ │ │ │ ├── EmptySetMultibindingContributions.java │ │ │ │ │ ├── PrivateConstructorForNoninstantiableModule.java │ │ │ │ │ ├── ProvidesNull.java │ │ │ │ │ ├── RefersToDaggerCodegen.java │ │ │ │ │ ├── ScopeOnModule.java │ │ │ │ │ ├── UseBinds.java │ │ │ │ │ ├── Util.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── guice │ │ │ │ │ ├── AssistedInjectScoping.java │ │ │ │ │ ├── AssistedParameters.java │ │ │ │ │ ├── BindingToUnqualifiedCommonType.java │ │ │ │ │ ├── InjectOnFinalField.java │ │ │ │ │ ├── OverridesGuiceInjectableMethod.java │ │ │ │ │ ├── OverridesJavaxInjectableMethod.java │ │ │ │ │ ├── ProvidesMethodOutsideOfModule.java │ │ │ │ │ └── package-info.java │ │ │ │ └── package-info.java │ │ │ ├── inlineme │ │ │ │ ├── InlinabilityResult.java │ │ │ │ ├── InlineMeData.java │ │ │ │ ├── Inliner.java │ │ │ │ ├── Suggester.java │ │ │ │ └── Validator.java │ │ │ ├── javadoc │ │ │ │ ├── AlmostJavadoc.java │ │ │ │ ├── EmptyBlockTag.java │ │ │ │ ├── EscapedEntity.java │ │ │ │ ├── InheritDoc.java │ │ │ │ ├── InvalidBlockTag.java │ │ │ │ ├── InvalidInlineTag.java │ │ │ │ ├── InvalidLink.java │ │ │ │ ├── InvalidParam.java │ │ │ │ ├── InvalidSnippet.java │ │ │ │ ├── InvalidThrows.java │ │ │ │ ├── InvalidThrowsLink.java │ │ │ │ ├── JavadocTag.java │ │ │ │ ├── MalformedInlineTag.java │ │ │ │ ├── MissingSummary.java │ │ │ │ ├── NotJavadoc.java │ │ │ │ ├── ReturnFromVoid.java │ │ │ │ ├── UnescapedEntity.java │ │ │ │ ├── UnrecognisedJavadocTag.java │ │ │ │ ├── UrlInSee.java │ │ │ │ └── Utils.java │ │ │ ├── nullness │ │ │ │ ├── AddNullMarkedToPackageInfo.java │ │ │ │ ├── DereferenceWithNullBranch.java │ │ │ │ ├── EqualsBrokenForNull.java │ │ │ │ ├── EqualsMissingNullable.java │ │ │ │ ├── ExtendsObject.java │ │ │ │ ├── FieldMissingNullable.java │ │ │ │ ├── MultipleNullnessAnnotations.java │ │ │ │ ├── NullArgumentForNonNullParameter.java │ │ │ │ ├── NullablePrimitive.java │ │ │ │ ├── NullablePrimitiveArray.java │ │ │ │ ├── NullableTypeParameter.java │ │ │ │ ├── NullableWildcard.java │ │ │ │ ├── NullnessUtils.java │ │ │ │ ├── ParameterMissingNullable.java │ │ │ │ ├── ReturnMissingNullable.java │ │ │ │ ├── UnnecessaryCheckNotNull.java │ │ │ │ ├── UnsafeWildcard.java │ │ │ │ └── VoidMissingNullable.java │ │ │ ├── overloading │ │ │ │ ├── InconsistentOverloads.java │ │ │ │ ├── ParameterOrderingViolation.java │ │ │ │ ├── ParameterTree.java │ │ │ │ └── ParameterTrie.java │ │ │ ├── package-info.java │ │ │ ├── threadsafety │ │ │ │ ├── AnnotationInfo.java │ │ │ │ ├── ConstantExpressions.java │ │ │ │ ├── DoubleCheckedLocking.java │ │ │ │ ├── GuardedByBinder.java │ │ │ │ ├── GuardedByChecker.java │ │ │ │ ├── GuardedByExpression.java │ │ │ │ ├── GuardedByFlags.java │ │ │ │ ├── GuardedBySymbolResolver.java │ │ │ │ ├── GuardedByUtils.java │ │ │ │ ├── HeldLockAnalyzer.java │ │ │ │ ├── HeldLockSet.java │ │ │ │ ├── IllegalGuardedBy.java │ │ │ │ ├── ImmutableAnalysis.java │ │ │ │ ├── ImmutableAnnotationChecker.java │ │ │ │ ├── ImmutableChecker.java │ │ │ │ ├── ImmutableEnumChecker.java │ │ │ │ ├── ImmutableRefactoring.java │ │ │ │ ├── StaticGuardedByInstance.java │ │ │ │ ├── SynchronizeOnNonFinalField.java │ │ │ │ ├── ThreadPriorityCheck.java │ │ │ │ ├── ThreadSafeAnalysis.java │ │ │ │ ├── ThreadSafeChecker.java │ │ │ │ ├── ThreadSafety.java │ │ │ │ ├── ThreadSafetyKnownTypes.java │ │ │ │ ├── WellKnownMutability.java │ │ │ │ └── WellKnownThreadSafety.java │ │ │ └── time │ │ │ │ ├── DateChecker.java │ │ │ │ ├── DurationFrom.java │ │ │ │ ├── DurationGetTemporalUnit.java │ │ │ │ ├── DurationTemporalUnit.java │ │ │ │ ├── DurationToLongTimeUnit.java │ │ │ │ ├── FromTemporalAccessor.java │ │ │ │ ├── InstantTemporalUnit.java │ │ │ │ ├── InvalidJavaTimeConstant.java │ │ │ │ ├── JavaDurationGetSecondsGetNano.java │ │ │ │ ├── JavaDurationGetSecondsToToSeconds.java │ │ │ │ ├── JavaDurationWithNanos.java │ │ │ │ ├── JavaDurationWithSeconds.java │ │ │ │ ├── JavaInstantGetSecondsGetNano.java │ │ │ │ ├── JavaLocalDateTimeGetNano.java │ │ │ │ ├── JavaLocalTimeGetNano.java │ │ │ │ ├── JavaPeriodGetDays.java │ │ │ │ ├── JavaTimeDefaultTimeZone.java │ │ │ │ ├── JodaConstructors.java │ │ │ │ ├── JodaDateTimeConstants.java │ │ │ │ ├── JodaDurationWithMillis.java │ │ │ │ ├── JodaInstantWithMillis.java │ │ │ │ ├── JodaNewPeriod.java │ │ │ │ ├── JodaPlusMinusLong.java │ │ │ │ ├── JodaTimeConverterManager.java │ │ │ │ ├── JodaToSelf.java │ │ │ │ ├── JodaWithDurationAddedLong.java │ │ │ │ ├── LocalDateTemporalAmount.java │ │ │ │ ├── NearbyCallers.java │ │ │ │ ├── PeriodFrom.java │ │ │ │ ├── PeriodGetTemporalUnit.java │ │ │ │ ├── PeriodTimeMath.java │ │ │ │ ├── PreferJavaTimeOverload.java │ │ │ │ ├── ProtoDurationGetSecondsGetNano.java │ │ │ │ ├── ProtoTimestampGetSecondsGetNano.java │ │ │ │ ├── StronglyTypeTime.java │ │ │ │ ├── TemporalAccessorGetChronoField.java │ │ │ │ ├── TimeInStaticInitializer.java │ │ │ │ ├── TimeUnitConversionChecker.java │ │ │ │ ├── TimeUnitMismatch.java │ │ │ │ └── ZoneIdOfZ.java │ │ │ ├── refaster │ │ │ ├── Bindings.java │ │ │ ├── BlockTemplate.java │ │ │ ├── BlockTemplateMatch.java │ │ │ ├── Choice.java │ │ │ ├── ControlFlowVisitor.java │ │ │ ├── CouldNotResolveImportException.java │ │ │ ├── ExpressionTemplate.java │ │ │ ├── ExpressionTemplateMatch.java │ │ │ ├── ImportPolicy.java │ │ │ ├── Inlineable.java │ │ │ ├── Inliner.java │ │ │ ├── LocalVarBinding.java │ │ │ ├── PlaceholderMethod.java │ │ │ ├── PlaceholderUnificationVisitor.java │ │ │ ├── PlaceholderVerificationVisitor.java │ │ │ ├── Refaster.java │ │ │ ├── RefasterRule.java │ │ │ ├── RefasterRuleBuilderScanner.java │ │ │ ├── RefasterScanner.java │ │ │ ├── RefasterSuppressionHelper.java │ │ │ ├── StringName.java │ │ │ ├── Template.java │ │ │ ├── TemplateMatch.java │ │ │ ├── UAnnotatedType.java │ │ │ ├── UAnnotation.java │ │ │ ├── UAnyOf.java │ │ │ ├── UArrayAccess.java │ │ │ ├── UArrayType.java │ │ │ ├── UArrayTypeTree.java │ │ │ ├── UAssert.java │ │ │ ├── UAssign.java │ │ │ ├── UAssignOp.java │ │ │ ├── UBinary.java │ │ │ ├── UBlank.java │ │ │ ├── UBlock.java │ │ │ ├── UBreak.java │ │ │ ├── UCatch.java │ │ │ ├── UClassDecl.java │ │ │ ├── UClassIdent.java │ │ │ ├── UClassType.java │ │ │ ├── UConditional.java │ │ │ ├── UContinue.java │ │ │ ├── UDoWhileLoop.java │ │ │ ├── UEnhancedForLoop.java │ │ │ ├── UExpression.java │ │ │ ├── UExpressionStatement.java │ │ │ ├── UForAll.java │ │ │ ├── UForLoop.java │ │ │ ├── UFreeIdent.java │ │ │ ├── UIdent.java │ │ │ ├── UIf.java │ │ │ ├── UInstanceOf.java │ │ │ ├── UIntersectionClassType.java │ │ │ ├── UIntersectionType.java │ │ │ ├── ULabeledStatement.java │ │ │ ├── ULambda.java │ │ │ ├── ULiteral.java │ │ │ ├── ULocalVarIdent.java │ │ │ ├── UMatches.java │ │ │ ├── UMemberReference.java │ │ │ ├── UMemberSelect.java │ │ │ ├── UMethodDecl.java │ │ │ ├── UMethodIdent.java │ │ │ ├── UMethodInvocation.java │ │ │ ├── UMethodType.java │ │ │ ├── UModifiers.java │ │ │ ├── UNewArray.java │ │ │ ├── UNewClass.java │ │ │ ├── UOfKind.java │ │ │ ├── UParens.java │ │ │ ├── UPlaceholderExpression.java │ │ │ ├── UPlaceholderStatement.java │ │ │ ├── UPrimitiveType.java │ │ │ ├── UPrimitiveTypeTree.java │ │ │ ├── URepeated.java │ │ │ ├── UReturn.java │ │ │ ├── USimpleStatement.java │ │ │ ├── USkip.java │ │ │ ├── UStatement.java │ │ │ ├── UStaticIdent.java │ │ │ ├── USynchronized.java │ │ │ ├── UTemplater.java │ │ │ ├── UThrow.java │ │ │ ├── UTree.java │ │ │ ├── UTry.java │ │ │ ├── UType.java │ │ │ ├── UTypeApply.java │ │ │ ├── UTypeCast.java │ │ │ ├── UTypeParameter.java │ │ │ ├── UTypeVar.java │ │ │ ├── UTypeVarIdent.java │ │ │ ├── UUnary.java │ │ │ ├── UUnionType.java │ │ │ ├── UVariableDecl.java │ │ │ ├── UWhileLoop.java │ │ │ ├── UWildcard.java │ │ │ ├── UWildcardType.java │ │ │ ├── Unifiable.java │ │ │ ├── Unifier.java │ │ │ └── annotation │ │ │ │ ├── AfterTemplate.java │ │ │ │ ├── AllowCodeBetweenLines.java │ │ │ │ ├── AlsoNegation.java │ │ │ │ ├── BeforeTemplate.java │ │ │ │ ├── Matches.java │ │ │ │ ├── MayOptionallyUse.java │ │ │ │ ├── NoAutoboxing.java │ │ │ │ ├── NotMatches.java │ │ │ │ ├── OfKind.java │ │ │ │ ├── Placeholder.java │ │ │ │ ├── Repeated.java │ │ │ │ ├── RequiredAnnotation.java │ │ │ │ ├── RequiredAnnotationProcessor.java │ │ │ │ └── UseImportPolicy.java │ │ │ └── scanner │ │ │ └── BuiltInCheckerSuppliers.java │ └── proto │ │ └── api_diff.proto │ └── test │ ├── java │ └── com │ │ └── google │ │ └── errorprone │ │ ├── CommandLineFlagTest.java │ │ ├── DiagnosticKindTest.java │ │ ├── ErrorProneCompilerIntegrationTest.java │ │ ├── ErrorProneJavaCompilerTest.java │ │ ├── ErrorProneJavacPluginTest.java │ │ ├── ErrorProneTestCompiler.java │ │ ├── MatcherChecker.java │ │ ├── NullAnnotationProcessor.java │ │ ├── SubContextTest.java │ │ ├── VisitorStateTest.java │ │ ├── apply │ │ └── ImportStatementsTest.java │ │ ├── bugpatterns │ │ ├── ASTHelpersSuggestionsTest.java │ │ ├── AddressSelectionTest.java │ │ ├── AlreadyCheckedTest.java │ │ ├── AlwaysThrowsTest.java │ │ ├── AmbiguousMethodReferenceTest.java │ │ ├── AnnotationMirrorToStringTest.java │ │ ├── AnnotationPositionTest.java │ │ ├── AnnotationValueToStringTest.java │ │ ├── ArrayAsKeyOfSetOrMapTest.java │ │ ├── ArrayEqualsTest.java │ │ ├── ArrayFillIncompatibleTypeTest.java │ │ ├── ArrayHashCodeTest.java │ │ ├── ArrayRecordComponentTest.java │ │ ├── ArrayToStringTest.java │ │ ├── ArraysAsListPrimitiveArrayTest.java │ │ ├── AssertFalseTest.java │ │ ├── AssertThrowsMultipleStatementsTest.java │ │ ├── AssertionFailureIgnoredTest.java │ │ ├── AssignmentExpressionTest.java │ │ ├── AsyncFunctionReturnsNullTest.java │ │ ├── AttemptedNegativeZeroTest.java │ │ ├── AutoValueBoxedValuesTest.java │ │ ├── AutoValueBuilderDefaultsInConstructorTest.java │ │ ├── AutoValueFinalMethodsTest.java │ │ ├── AutoValueImmutableFieldsTest.java │ │ ├── AutoValueSubclassLeakedTest.java │ │ ├── AvoidObjectArraysTest.java │ │ ├── BadAnnotationImplementationTest.java │ │ ├── BadComparableTest.java │ │ ├── BadImportTest.java │ │ ├── BadInstanceofTest.java │ │ ├── BadShiftAmountTest.java │ │ ├── BanClassLoaderTest.java │ │ ├── BanJNDITest.java │ │ ├── BanSerializableReadTest.java │ │ ├── BareDotMetacharacterTest.java │ │ ├── BigDecimalEqualsTest.java │ │ ├── BigDecimalLiteralDoubleTest.java │ │ ├── BooleanLiteralTest.java │ │ ├── BooleanParameterTest.java │ │ ├── BoxedPrimitiveConstructorTest.java │ │ ├── BoxedPrimitiveEqualityTest.java │ │ ├── BugCheckerTest.java │ │ ├── BugPatternNamingTest.java │ │ ├── ByteBufferBackingArrayTest.java │ │ ├── CacheLoaderNullTest.java │ │ ├── CannotMockFinalClassTest.java │ │ ├── CannotMockMethodTest.java │ │ ├── CanonicalDurationTest.java │ │ ├── CatchAndPrintStackTraceTest.java │ │ ├── CatchFailTest.java │ │ ├── CatchingUncheckedTest.java │ │ ├── ChainedAssertionLosesContextTest.java │ │ ├── ChainingConstructorIgnoresParameterTest.java │ │ ├── CharacterGetNumericValueTest.java │ │ ├── CheckNotNullMultipleTimesTest.java │ │ ├── CheckReturnValueTest.java │ │ ├── CheckedExceptionNotThrownTest.java │ │ ├── ClassCanBeStaticTest.java │ │ ├── ClassInitializationDeadlockTest.java │ │ ├── ClassNameTest.java │ │ ├── ClassNamedLikeTypeParameterTest.java │ │ ├── ClassNewInstanceTest.java │ │ ├── ClosingStandardOutputStreamsTest.java │ │ ├── CollectionToArraySafeParameterTest.java │ │ ├── CollectorShouldNotUseStateTest.java │ │ ├── ComparableAndComparatorTest.java │ │ ├── ComparableTypeTest.java │ │ ├── CompareToZeroTest.java │ │ ├── ComparingThisWithNullTest.java │ │ ├── ComparisonContractViolatedTest.java │ │ ├── ComparisonOutOfRangeTest.java │ │ ├── CompileTimeConstantCheckerTest.java │ │ ├── ComplexBooleanConstantTest.java │ │ ├── ComputeIfAbsentAmbiguousReferenceTest.java │ │ ├── ConditionalExpressionNumericPromotionTest.java │ │ ├── ConstantFieldTest.java │ │ ├── ConstantOverflowTest.java │ │ ├── ConstantPatternCompileTest.java │ │ ├── DangerousLiteralNullCheckerTest.java │ │ ├── DateFormatConstantTest.java │ │ ├── DeadExceptionTest.java │ │ ├── DeadThreadTest.java │ │ ├── DeduplicateConstantsTest.java │ │ ├── DeeplyNestedTest.java │ │ ├── DefaultCharsetTest.java │ │ ├── DefaultLocaleTest.java │ │ ├── DefaultPackageTest.java │ │ ├── DepAnnTest.java │ │ ├── DeprecatedVariableTest.java │ │ ├── DifferentNameButSameTest.java │ │ ├── DirectInvocationOnMockTest.java │ │ ├── DiscardedPostfixExpressionTest.java │ │ ├── DistinctVarargsCheckerTest.java │ │ ├── DoNotCallCheckerTest.java │ │ ├── DoNotCallSuggesterTest.java │ │ ├── DoNotClaimAnnotationsTest.java │ │ ├── DoNotMockAutoValueTest.java │ │ ├── DoNotMockCheckerTest.java │ │ ├── DoubleBraceInitializationTest.java │ │ ├── DuplicateBranchesTest.java │ │ ├── DuplicateDateFormatFieldTest.java │ │ ├── DuplicateMapKeysTest.java │ │ ├── EmptyCatchTest.java │ │ ├── EmptyIfStatementTest.java │ │ ├── EmptyTopLevelDeclarationTest.java │ │ ├── EnumOrdinalTest.java │ │ ├── EqualsGetClassTest.java │ │ ├── EqualsHashCodeTest.java │ │ ├── EqualsIncompatibleTypeTest.java │ │ ├── EqualsNaNTest.java │ │ ├── EqualsNullTest.java │ │ ├── EqualsReferenceTest.java │ │ ├── EqualsUnsafeCastTest.java │ │ ├── EqualsUsingHashCodeTest.java │ │ ├── EqualsWrongThingTest.java │ │ ├── ErroneousBitwiseExpressionTest.java │ │ ├── ErroneousThreadPoolConstructorCheckerTest.java │ │ ├── ExpectedExceptionCheckerTest.java │ │ ├── ExtendingJUnitAssertTest.java │ │ ├── ExtendsAutoValueTest.java │ │ ├── FallThroughTest.java │ │ ├── FieldCanBeFinalTest.java │ │ ├── FieldCanBeLocalTest.java │ │ ├── FieldCanBeStaticTest.java │ │ ├── FinalizeTest.java │ │ ├── FinallyTest.java │ │ ├── FloatCastTest.java │ │ ├── FloatingPointAssertionWithinEpsilonTest.java │ │ ├── FloatingPointLiteralPrecisionTest.java │ │ ├── ForEachIterableTest.java │ │ ├── ForOverrideCheckerTest.java │ │ ├── FunctionalInterfaceClashTest.java │ │ ├── FunctionalInterfaceMethodChangedTest.java │ │ ├── FutureReturnValueIgnoredTest.java │ │ ├── FutureTransformAsyncTest.java │ │ ├── FuturesGetCheckedIllegalExceptionTypeTest.java │ │ ├── FuzzyEqualsShouldNotBeUsedInEqualsMethodTest.java │ │ ├── GetClassOnAnnotationTest.java │ │ ├── GetClassOnClassTest.java │ │ ├── GetClassOnEnumTest.java │ │ ├── GuiceNestedCombineTest.java │ │ ├── HashtableContainsTest.java │ │ ├── HidingFieldTest.java │ │ ├── ICCProfileGetInstanceTest.java │ │ ├── IdentifierNameTest.java │ │ ├── IdentityBinaryExpressionTest.java │ │ ├── IdentityHashMapBoxingTest.java │ │ ├── IdentityHashMapUsageTest.java │ │ ├── IgnoredPureGetterTest.java │ │ ├── ImmutableMemberCollectionTest.java │ │ ├── ImmutableSetForContainsTest.java │ │ ├── ImplementAssertionWithChainingTest.java │ │ ├── ImpossibleNullComparisonTest.java │ │ ├── IncomparableTest.java │ │ ├── IncompatibleModifiersCheckerTest.java │ │ ├── InconsistentCapitalizationTest.java │ │ ├── InconsistentHashCodeTest.java │ │ ├── IncorrectMainMethodTest.java │ │ ├── IncrementInForLoopAndHeaderTest.java │ │ ├── IndexOfCharTest.java │ │ ├── InexactVarargsConditionalTest.java │ │ ├── InfiniteRecursionTest.java │ │ ├── InitializeInlineTest.java │ │ ├── InjectOnBugCheckersTest.java │ │ ├── InlineTrivialConstantTest.java │ │ ├── InputStreamSlowMultibyteReadTest.java │ │ ├── InsecureCipherModeTest.java │ │ ├── InstanceOfAndCastMatchWrongTypeTest.java │ │ ├── IntFloatConversionTest.java │ │ ├── IntLiteralCastTest.java │ │ ├── IntLongMathTest.java │ │ ├── InterfaceWithOnlyStaticsTest.java │ │ ├── InterruptedExceptionSwallowedTest.java │ │ ├── InterruptionTest.java │ │ ├── InvalidPatternSyntaxTest.java │ │ ├── InvalidTimeZoneIDTest.java │ │ ├── InvalidZoneIdTest.java │ │ ├── IsInstanceIncompatibleTypeTest.java │ │ ├── IsInstanceOfClassTest.java │ │ ├── IterableAndIteratorTest.java │ │ ├── IterablePathParameterTest.java │ │ ├── JUnit3FloatingPointComparisonWithoutDeltaTest.java │ │ ├── JUnit3TestNotRunTest.java │ │ ├── JUnit4ClassAnnotationNonStaticTest.java │ │ ├── JUnit4ClassUsedInJUnit3Test.java │ │ ├── JUnit4EmptyMethodsTest.java │ │ ├── JUnit4SetUpNotRunTest.java │ │ ├── JUnit4TearDownNotRunTest.java │ │ ├── JUnit4TestNotRunTest.java │ │ ├── JUnit4TestsNotRunWithinEnclosedTest.java │ │ ├── JUnitAmbiguousTestClassTest.java │ │ ├── JUnitAssertSameCheckTest.java │ │ ├── JUnitParameterMethodNotFoundTest.java │ │ ├── JavaLangClashTest.java │ │ ├── JavaUtilDateCheckerTest.java │ │ ├── JdkObsoleteTest.java │ │ ├── LabelledBreakTargetTest.java │ │ ├── LambdaFunctionalInterfaceTest.java │ │ ├── LiteByteStringUtf8Test.java │ │ ├── LiteEnumValueOfTest.java │ │ ├── LiteProtoToStringTest.java │ │ ├── LockNotBeforeTryTest.java │ │ ├── LockOnBoxedPrimitiveTest.java │ │ ├── LockOnNonEnclosingClassLiteralTest.java │ │ ├── LogicalAssignmentTest.java │ │ ├── LongDoubleConversionTest.java │ │ ├── LongFloatConversionTest.java │ │ ├── LongLiteralLowerCaseSuffixTest.java │ │ ├── LoopConditionCheckerTest.java │ │ ├── LoopOverCharArrayTest.java │ │ ├── LossyPrimitiveCompareTest.java │ │ ├── MathAbsoluteNegativeTest.java │ │ ├── MathRoundIntLongTest.java │ │ ├── MemoizeConstantVisitorStateLookupsTest.java │ │ ├── MethodCanBeStaticTest.java │ │ ├── MisformattedTestDataTest.java │ │ ├── MisleadingEmptyVarargsTest.java │ │ ├── MisleadingEscapedSpaceTest.java │ │ ├── MissingBracesTest.java │ │ ├── MissingCasesInEnumSwitchTest.java │ │ ├── MissingDefaultTest.java │ │ ├── MissingFailTest.java │ │ ├── MissingImplementsComparableTest.java │ │ ├── MissingOverrideTest.java │ │ ├── MissingRefasterAnnotationTest.java │ │ ├── MissingSuperCallTest.java │ │ ├── MissingTestCallTest.java │ │ ├── MisusedDayOfYearTest.java │ │ ├── MisusedWeekYearTest.java │ │ ├── MixedArrayDimensionsTest.java │ │ ├── MixedDescriptorsTest.java │ │ ├── MixedMutabilityReturnTypeTest.java │ │ ├── MockIllegalThrowsTest.java │ │ ├── MockNotUsedInProductionTest.java │ │ ├── MockitoDoSetupTest.java │ │ ├── MockitoUsageTest.java │ │ ├── ModifiedButNotUsedTest.java │ │ ├── ModifyCollectionInEnhancedForLoopTest.java │ │ ├── ModifySourceCollectionInStreamTest.java │ │ ├── ModifyingCollectionWithItselfTest.java │ │ ├── MultiVariableDeclarationTest.java │ │ ├── MultimapKeysTest.java │ │ ├── MultipleParallelOrSequentialCallsTest.java │ │ ├── MultipleTopLevelClassesTest.java │ │ ├── MultipleUnaryOperatorsInMethodCallTest.java │ │ ├── MustBeClosedCheckerTest.java │ │ ├── MutableGuiceModuleTest.java │ │ ├── MutablePublicArrayTest.java │ │ ├── NCopiesOfCharTest.java │ │ ├── NamedLikeContextualKeywordTest.java │ │ ├── NarrowCalculationTest.java │ │ ├── NarrowingCompoundAssignmentTest.java │ │ ├── NegativeBooleanTest.java │ │ ├── NegativeCharLiteralTest.java │ │ ├── NestedInstanceOfConditionsTest.java │ │ ├── NewFileSystemTest.java │ │ ├── NoAllocationCheckerTest.java │ │ ├── NonApiTypeTest.java │ │ ├── NonAtomicVolatileUpdateTest.java │ │ ├── NonCanonicalStaticImportTest.java │ │ ├── NonCanonicalStaticMemberImportTest.java │ │ ├── NonCanonicalTypeTest.java │ │ ├── NonFinalCompileTimeConstantTest.java │ │ ├── NonFinalStaticFieldTest.java │ │ ├── NonOverridingEqualsTest.java │ │ ├── NonRuntimeAnnotationTest.java │ │ ├── NullOptionalTest.java │ │ ├── NullTernaryTest.java │ │ ├── NullableConstructorTest.java │ │ ├── NullableOnContainingClassTest.java │ │ ├── NullableOptionalTest.java │ │ ├── NullableVoidTest.java │ │ ├── ObjectEqualsForPrimitivesTest.java │ │ ├── ObjectToStringTest.java │ │ ├── ObjectsHashCodePrimitiveTest.java │ │ ├── OperatorPrecedenceTest.java │ │ ├── OptionalEqualityTest.java │ │ ├── OptionalMapToOptionalTest.java │ │ ├── OptionalMapUnusedValueTest.java │ │ ├── OptionalNotPresentTest.java │ │ ├── OptionalOfRedundantMethodTest.java │ │ ├── OrphanedFormatStringTest.java │ │ ├── OutlineNoneTest.java │ │ ├── OverrideThrowableToStringTest.java │ │ ├── OverridesTest.java │ │ ├── OverridingMethodInconsistentArgumentNamesCheckerTest.java │ │ ├── PackageInfoTest.java │ │ ├── PackageLocationTest.java │ │ ├── ParameterCommentTest.java │ │ ├── ParameterNameTest.java │ │ ├── ParametersButNotParameterizedTest.java │ │ ├── PatternMatchingInstanceofTest.java │ │ ├── PreconditionsCheckNotNullRepeatedTest.java │ │ ├── PreconditionsExpensiveStringTest.java │ │ ├── PreconditionsInvalidPlaceholderTest.java │ │ ├── PreferInstanceofOverGetKindTest.java │ │ ├── PreferredInterfaceTypeTest.java │ │ ├── PrimitiveArrayPassedToVarargsMethodTest.java │ │ ├── PrimitiveAtomicReferenceTest.java │ │ ├── PrivateConstructorForUtilityClassTest.java │ │ ├── PrivateSecurityContractProtoAccessTest.java │ │ ├── ProtectedMembersInFinalClassTest.java │ │ ├── ProtoBuilderReturnValueIgnoredTest.java │ │ ├── ProtoStringFieldReferenceEqualityTest.java │ │ ├── ProtoTruthMixedDescriptorsTest.java │ │ ├── ProtocolBufferOrdinalTest.java │ │ ├── PublicApiNamedStreamShouldReturnStreamTest.java │ │ ├── RandomCastTest.java │ │ ├── RandomModIntegerTest.java │ │ ├── ReachabilityFenceUsageTest.java │ │ ├── RedundantControlFlowTest.java │ │ ├── RedundantOverrideTest.java │ │ ├── RedundantSetterCallTest.java │ │ ├── RedundantThrowsTest.java │ │ ├── ReferenceEqualityTest.java │ │ ├── RemoveUnusedImportsTest.java │ │ ├── RequiredModifiersCheckerTest.java │ │ ├── RestrictedApiCheckerTest.java │ │ ├── RethrowReflectiveOperationExceptionAsLinkageErrorTest.java │ │ ├── ReturnAtTheEndOfVoidFunctionTest.java │ │ ├── ReturnValueIgnoredTest.java │ │ ├── ReturnsNullCollectionTest.java │ │ ├── RobolectricShadowDirectlyOnTest.java │ │ ├── RuleNotRunTest.java │ │ ├── RxReturnValueIgnoredTest.java │ │ ├── SameNameButDifferentTest.java │ │ ├── SelfAlwaysReturnsThisTest.java │ │ ├── SelfAssertionTest.java │ │ ├── SelfAssignmentTest.java │ │ ├── SelfComparisonTest.java │ │ ├── SelfEqualsTest.java │ │ ├── SelfSetTest.java │ │ ├── SetUnrecognizedTest.java │ │ ├── ShortCircuitBooleanTest.java │ │ ├── ShouldHaveEvenArgsTest.java │ │ ├── SizeGreaterThanOrEqualsZeroTest.java │ │ ├── StatementSwitchToExpressionSwitchTest.java │ │ ├── StaticAssignmentInConstructorTest.java │ │ ├── StaticAssignmentOfThrowableTest.java │ │ ├── StaticMockMemberTest.java │ │ ├── StaticQualifiedUsingExpressionTest.java │ │ ├── StreamResourceLeakTest.java │ │ ├── StreamToIterableTest.java │ │ ├── StreamToStringTest.java │ │ ├── StringBuilderInitWithCharTest.java │ │ ├── StringCaseLocaleUsageTest.java │ │ ├── StringCharsetTest.java │ │ ├── StringConcatToTextBlockTest.java │ │ ├── StringFormatWithLiteralTest.java │ │ ├── StringSplitterTest.java │ │ ├── StronglyTypeByteStringTest.java │ │ ├── SubstringOfZeroTest.java │ │ ├── SunApiTest.java │ │ ├── SuperCallToObjectMethodTest.java │ │ ├── SuppressWarningsDeprecatedTest.java │ │ ├── SuppressWarningsWithoutExplanationTest.java │ │ ├── SwigMemoryLeakTest.java │ │ ├── SwitchDefaultTest.java │ │ ├── SymbolToStringTest.java │ │ ├── SystemConsoleNullTest.java │ │ ├── SystemExitOutsideMainTest.java │ │ ├── SystemOutTest.java │ │ ├── TestExceptionCheckerTest.java │ │ ├── TestParametersNotInitializedTest.java │ │ ├── TheoryButNoTheoriesTest.java │ │ ├── ThreadJoinLoopTest.java │ │ ├── ThreadLocalUsageTest.java │ │ ├── ThreeLetterTimeZoneIDTest.java │ │ ├── ThrowIfUncheckedKnownCheckedTest.java │ │ ├── ThrowIfUncheckedKnownUncheckedTest.java │ │ ├── ThrowNullTest.java │ │ ├── ThrowSpecificExceptionsTest.java │ │ ├── ThrowsUncheckedExceptionTest.java │ │ ├── ToStringReturnsNullTest.java │ │ ├── TooManyParametersTest.java │ │ ├── TraditionalSwitchExpressionTest.java │ │ ├── TransientMisuseTest.java │ │ ├── TreeToStringTest.java │ │ ├── TruthAssertExpectedTest.java │ │ ├── TruthConstantAssertsTest.java │ │ ├── TruthContainsExactlyElementsInUsageTest.java │ │ ├── TruthGetOrDefaultTest.java │ │ ├── TryFailRefactoringTest.java │ │ ├── TryFailThrowableTest.java │ │ ├── TryWithResourcesVariableTest.java │ │ ├── TypeEqualsCheckerTest.java │ │ ├── TypeNameShadowingTest.java │ │ ├── TypeParameterNamingTest.java │ │ ├── TypeParameterQualifierTest.java │ │ ├── TypeParameterShadowingTest.java │ │ ├── TypeParameterUnusedInFormalsTest.java │ │ ├── TypeToStringTest.java │ │ ├── URLEqualsHashCodeTest.java │ │ ├── UndefinedEqualsTest.java │ │ ├── UngroupedOverloadsTest.java │ │ ├── UnicodeDirectionalityCharactersTest.java │ │ ├── UnicodeEscapeTest.java │ │ ├── UnicodeInCodeTest.java │ │ ├── UnnecessarilyFullyQualifiedTest.java │ │ ├── UnnecessarilyVisibleTest.java │ │ ├── UnnecessaryAnonymousClassTest.java │ │ ├── UnnecessaryAssignmentTest.java │ │ ├── UnnecessaryAsyncTest.java │ │ ├── UnnecessaryBoxedAssignmentTest.java │ │ ├── UnnecessaryBoxedVariableTest.java │ │ ├── UnnecessaryBreakInSwitchTest.java │ │ ├── UnnecessaryCopyTest.java │ │ ├── UnnecessaryDefaultInEnumSwitchTest.java │ │ ├── UnnecessaryFinalTest.java │ │ ├── UnnecessaryLambdaTest.java │ │ ├── UnnecessaryLongToIntConversionTest.java │ │ ├── UnnecessaryMethodInvocationMatcherTest.java │ │ ├── UnnecessaryMethodReferenceTest.java │ │ ├── UnnecessaryOptionalGetTest.java │ │ ├── UnnecessaryParenthesesTest.java │ │ ├── UnnecessaryQualifierTest.java │ │ ├── UnnecessarySetDefaultTest.java │ │ ├── UnnecessaryStaticImportTest.java │ │ ├── UnnecessaryStringBuilderTest.java │ │ ├── UnnecessaryTestMethodPrefixTest.java │ │ ├── UnnecessaryTypeArgumentTest.java │ │ ├── UnsafeFinalizationTest.java │ │ ├── UnsafeLocaleUsageTest.java │ │ ├── UnsafeReflectiveConstructionCastTest.java │ │ ├── UnsynchronizedOverridesSynchronizedTest.java │ │ ├── UnusedAnonymousClassTest.java │ │ ├── UnusedCollectionModifiedInPlaceTest.java │ │ ├── UnusedExceptionTest.java │ │ ├── UnusedLabelTest.java │ │ ├── UnusedMethodTest.java │ │ ├── UnusedNestedClassTest.java │ │ ├── UnusedTypeParameterTest.java │ │ ├── UnusedVariableTest.java │ │ ├── UseCorrectAssertInTestsTest.java │ │ ├── UseEnumSwitchTest.java │ │ ├── VarCheckerTest.java │ │ ├── VarTypeNameTest.java │ │ ├── VariableNameSameAsTypeTest.java │ │ ├── VarifierTest.java │ │ ├── VoidUsedTest.java │ │ ├── WaitNotInLoopTest.java │ │ ├── WildcardImportTest.java │ │ ├── WithSignatureDiscouragedTest.java │ │ ├── XorPowerTest.java │ │ ├── YodaConditionTest.java │ │ ├── android │ │ │ ├── BinderIdentityRestoredDangerouslyTest.java │ │ │ ├── BundleDeserializationCastTest.java │ │ │ ├── FragmentInjectionTest.java │ │ │ ├── FragmentNotInstantiableTest.java │ │ │ ├── HardCodedSdCardPathTest.java │ │ │ ├── IsLoggableTagLengthTest.java │ │ │ ├── MislabeledAndroidStringTest.java │ │ │ ├── ParcelableCreatorTest.java │ │ │ ├── RectIntersectReturnValueIgnoredTest.java │ │ │ ├── StaticOrDefaultInterfaceMethodTest.java │ │ │ ├── WakelockReleasedDangerouslyTest.java │ │ │ └── testdata │ │ │ │ ├── CustomFragment.java │ │ │ │ ├── CustomParcelableList.java │ │ │ │ ├── ParcelableCreatorNegativeCases.java │ │ │ │ ├── ParcelableCreatorPositiveCases.java │ │ │ │ └── stubs │ │ │ │ └── android │ │ │ │ ├── R.java │ │ │ │ ├── app │ │ │ │ └── Fragment.java │ │ │ │ ├── graphics │ │ │ │ └── Rect.java │ │ │ │ ├── os │ │ │ │ ├── Binder.java │ │ │ │ ├── Bundle.java │ │ │ │ ├── Parcel.java │ │ │ │ ├── Parcelable.java │ │ │ │ └── PowerManager.java │ │ │ │ ├── preference │ │ │ │ └── PreferenceActivity.java │ │ │ │ ├── support │ │ │ │ └── v4 │ │ │ │ │ └── app │ │ │ │ │ └── Fragment.java │ │ │ │ └── util │ │ │ │ └── Log.java │ │ ├── apidiff │ │ │ ├── AndroidJdkLibsCheckerTest.java │ │ │ ├── ApiDiffCheckerTest.java │ │ │ ├── CompilationBuilderHelpers.java │ │ │ └── Java8ApiCheckerTest.java │ │ ├── argumentselectiondefects │ │ │ ├── ArgumentSelectionDefectCheckerTest.java │ │ │ ├── AssertEqualsArgumentOrderCheckerTest.java │ │ │ ├── AutoValueConstructorOrderCheckerTest.java │ │ │ ├── CreatesDuplicateCallHeuristicTest.java │ │ │ ├── EnclosedByReverseHeuristicTest.java │ │ │ ├── NameInCommentHeuristicTest.java │ │ │ └── ParameterTest.java │ │ ├── checkreturnvalue │ │ │ ├── ApiTest.java │ │ │ ├── BuilderReturnThisTest.java │ │ │ ├── CanIgnoreReturnValueSuggesterTest.java │ │ │ ├── CheckReturnValueWellKnownLibrariesTest.java │ │ │ ├── NoCanIgnoreReturnValueOnClassesTest.java │ │ │ ├── UnnecessarilyUsedValueTest.java │ │ │ └── UsingJsr305CheckReturnValueTest.java │ │ ├── collectionincompatibletype │ │ │ ├── CollectionIncompatibleTypeTest.java │ │ │ ├── CollectionUndefinedEqualityTest.java │ │ │ ├── CompatibleWithMisuseTest.java │ │ │ ├── IncompatibleArgumentTypeTest.java │ │ │ ├── JUnitIncompatibleTypeTest.java │ │ │ ├── TruthIncompatibleTypeTest.java │ │ │ └── something.proto │ │ ├── flogger │ │ │ ├── FloggerArgumentToStringTest.java │ │ │ ├── FloggerFormatStringTest.java │ │ │ ├── FloggerLogStringTest.java │ │ │ ├── FloggerLogVarargsTest.java │ │ │ ├── FloggerLogWithCauseTest.java │ │ │ ├── FloggerMessageFormatTest.java │ │ │ ├── FloggerRedundantIsEnabledTest.java │ │ │ ├── FloggerRequiredModifiersTest.java │ │ │ ├── FloggerSplitLogStatementTest.java │ │ │ ├── FloggerStringConcatenationTest.java │ │ │ ├── FloggerWithCauseTest.java │ │ │ └── FloggerWithoutCauseTest.java │ │ ├── formatstring │ │ │ ├── AnnotateFormatMethodTest.java │ │ │ ├── FormatStringAnnotationCheckerTest.java │ │ │ ├── FormatStringTest.java │ │ │ ├── InlineFormatStringTest.java │ │ │ └── LenientFormatStringValidationTest.java │ │ ├── inject │ │ │ ├── AssistedInjectAndInjectOnConstructorsTest.java │ │ │ ├── AssistedInjectAndInjectOnSameConstructorTest.java │ │ │ ├── AutoFactoryAtInjectTest.java │ │ │ ├── CloseableProvidesTest.java │ │ │ ├── InjectOnConstructorOfAbstractClassTest.java │ │ │ ├── InjectOnMemberAndConstructorTest.java │ │ │ ├── InjectedConstructorAnnotationsTest.java │ │ │ ├── InvalidTargetingOnScopingAnnotationTest.java │ │ │ ├── JavaxInjectOnAbstractMethodTest.java │ │ │ ├── JavaxInjectOnFinalFieldTest.java │ │ │ ├── MisplacedScopeAnnotationsTest.java │ │ │ ├── MissingRuntimeRetentionTest.java │ │ │ ├── MoreThanOneInjectableConstructorTest.java │ │ │ ├── MoreThanOneQualifierTest.java │ │ │ ├── MoreThanOneScopeAnnotationOnClassTest.java │ │ │ ├── OverlappingQualifierAndScopeAnnotationTest.java │ │ │ ├── QualifierOrScopeOnInjectMethodTest.java │ │ │ ├── QualifierWithTypeUseTest.java │ │ │ ├── ScopeAnnotationOnInterfaceOrAbstractClassTest.java │ │ │ ├── dagger │ │ │ │ ├── AndroidInjectionBeforeSuperTest.java │ │ │ │ ├── EmptySetMultibindingContributionsTest.java │ │ │ │ ├── PrivateConstructorForNoninstantiableModuleTest.java │ │ │ │ ├── ProvidesNullTest.java │ │ │ │ ├── ScopeOnModuleTest.java │ │ │ │ └── UseBindsTest.java │ │ │ └── guice │ │ │ │ ├── AssistedInjectScopingTest.java │ │ │ │ ├── AssistedParametersTest.java │ │ │ │ ├── BindingToUnqualifiedCommonTypeTest.java │ │ │ │ ├── InjectOnFinalFieldTest.java │ │ │ │ ├── OverridesGuiceInjectableMethodTest.java │ │ │ │ ├── OverridesJavaxInjectableMethodTest.java │ │ │ │ └── ProvidesMethodOutsideOfModuleTest.java │ │ ├── inlineme │ │ │ ├── InlinerTest.java │ │ │ ├── SuggesterTest.java │ │ │ └── ValidatorTest.java │ │ ├── javadoc │ │ │ ├── AlmostJavadocTest.java │ │ │ ├── EmptyBlockTagTest.java │ │ │ ├── EscapedEntityTest.java │ │ │ ├── InheritDocTest.java │ │ │ ├── InvalidBlockTagTest.java │ │ │ ├── InvalidInlineTagTest.java │ │ │ ├── InvalidLinkTest.java │ │ │ ├── InvalidParamTest.java │ │ │ ├── InvalidSnippetTest.java │ │ │ ├── InvalidThrowsLinkTest.java │ │ │ ├── InvalidThrowsTest.java │ │ │ ├── MalformedInlineTagTest.java │ │ │ ├── MissingSummaryTest.java │ │ │ ├── NotJavadocTest.java │ │ │ ├── ReturnFromVoidTest.java │ │ │ ├── UnescapedEntityTest.java │ │ │ ├── UnrecognisedJavadocTagTest.java │ │ │ └── UrlInSeeTest.java │ │ ├── nullness │ │ │ ├── AddNullMarkedToPackageInfoTest.java │ │ │ ├── DereferenceWithNullBranchTest.java │ │ │ ├── EqualsBrokenForNullTest.java │ │ │ ├── EqualsMissingNullableTest.java │ │ │ ├── ExtendsObjectTest.java │ │ │ ├── FieldMissingNullableTest.java │ │ │ ├── MultipleNullnessAnnotationsTest.java │ │ │ ├── NullArgumentForNonNullParameterTest.java │ │ │ ├── NullablePrimitiveArrayTest.java │ │ │ ├── NullablePrimitiveTest.java │ │ │ ├── NullableTypeParameterTest.java │ │ │ ├── NullableWildcardTest.java │ │ │ ├── ParameterMissingNullableTest.java │ │ │ ├── ReturnMissingNullableTest.java │ │ │ ├── UnnecessaryCheckNotNullTest.java │ │ │ ├── UnsafeWildcardTest.java │ │ │ └── VoidMissingNullableTest.java │ │ ├── overloading │ │ │ └── InconsistentOverloadsTest.java │ │ ├── testdata │ │ │ ├── Allowlist.java │ │ │ ├── ArrayEqualsPositiveCases.java │ │ │ ├── ArrayHashCodePositiveCases2.java │ │ │ ├── BadShiftAmountPositiveCases.java │ │ │ ├── BanSerializableReadNegativeCases.java │ │ │ ├── BanSerializableReadPositiveCases.java │ │ │ ├── BanSerializableReadPositiveCases_expected.java │ │ │ ├── ChainingConstructorIgnoresParameterPositiveCases.java │ │ │ ├── EmptyIfStatementNegativeCases.java │ │ │ ├── EmptyIfStatementPositiveCases.java │ │ │ ├── NonAtomicVolatileUpdatePositiveCases.java │ │ │ ├── OrderingFromPositiveCases.java │ │ │ ├── RestrictedApiMethods.java │ │ │ ├── SelfAssignmentPositiveCases1.java │ │ │ └── WaitNotInLoopPositiveCases.java │ │ ├── threadsafety │ │ │ ├── DoubleCheckedLockingTest.java │ │ │ ├── GuardedByBinderTest.java │ │ │ ├── GuardedByCheckerTest.java │ │ │ ├── GuardedByValidatorTest.java │ │ │ ├── HeldLockAnalyzerTest.java │ │ │ ├── ImmutableAnnotationCheckerTest.java │ │ │ ├── ImmutableCheckerTest.java │ │ │ ├── ImmutableEnumCheckerTest.java │ │ │ ├── ImmutableRefactoringTest.java │ │ │ ├── StaticGuardedByInstanceTest.java │ │ │ ├── SynchronizeOnNonFinalFieldTest.java │ │ │ ├── ThreadPriorityCheckTest.java │ │ │ ├── ThreadSafeCheckerTest.java │ │ │ └── test.proto │ │ └── time │ │ │ ├── DateCheckerTest.java │ │ │ ├── DurationFromTest.java │ │ │ ├── DurationGetTemporalUnitTest.java │ │ │ ├── DurationTemporalUnitTest.java │ │ │ ├── DurationToLongTimeUnitTest.java │ │ │ ├── FromTemporalAccessorTest.java │ │ │ ├── InstantTemporalUnitTest.java │ │ │ ├── InvalidJavaTimeConstantTest.java │ │ │ ├── JavaDurationGetSecondsGetNanoTest.java │ │ │ ├── JavaDurationGetSecondsToToSecondsTest.java │ │ │ ├── JavaDurationWithNanosTest.java │ │ │ ├── JavaDurationWithSecondsTest.java │ │ │ ├── JavaInstantGetSecondsGetNanoTest.java │ │ │ ├── JavaLocalDateTimeGetNanoTest.java │ │ │ ├── JavaLocalTimeGetNanoTest.java │ │ │ ├── JavaPeriodGetDaysTest.java │ │ │ ├── JavaTimeDefaultTimeZoneTest.java │ │ │ ├── JodaConstructorsTest.java │ │ │ ├── JodaDateTimeConstantsTest.java │ │ │ ├── JodaDurationWithMillisTest.java │ │ │ ├── JodaInstantWithMillisTest.java │ │ │ ├── JodaNewPeriodTest.java │ │ │ ├── JodaPlusMinusLongTest.java │ │ │ ├── JodaTimeConverterManagerTest.java │ │ │ ├── JodaToSelfTest.java │ │ │ ├── JodaWithDurationAddedLongTest.java │ │ │ ├── LocalDateTemporalAmountTest.java │ │ │ ├── PeriodFromTest.java │ │ │ ├── PeriodGetTemporalUnitTest.java │ │ │ ├── PeriodTimeMathTest.java │ │ │ ├── PreferJavaTimeOverloadTest.java │ │ │ ├── ProtoDurationGetSecondsGetNanoTest.java │ │ │ ├── ProtoTimestampGetSecondsGetNanoTest.java │ │ │ ├── StronglyTypeTimeTest.java │ │ │ ├── TemporalAccessorGetChronoFieldTest.java │ │ │ ├── TimeInStaticInitializerTest.java │ │ │ ├── TimeUnitConversionCheckerTest.java │ │ │ ├── TimeUnitMismatchTest.java │ │ │ └── ZoneIdOfZTest.java │ │ ├── dataflow │ │ └── nullnesspropagation │ │ │ ├── NullnessInferenceTest.java │ │ │ └── NullnessPropagationTest.java │ │ ├── fixes │ │ └── SuggestedFixesTest.java │ │ ├── matchers │ │ ├── AnnotationDoesNotHaveArgumentTest.java │ │ ├── AnnotationHasArgumentWithValueTest.java │ │ ├── AnnotationMatcherTest.java │ │ ├── CompileTimeConstantExpressionMatcherTest.java │ │ ├── CompilerBasedAbstractTest.java │ │ ├── CompoundAssignmentTest.java │ │ ├── ConstructorOfClassTest.java │ │ ├── EnclosingTest.java │ │ ├── HasIdentifierTest.java │ │ ├── JUnitMatchersTest.java │ │ ├── MatchersTest.java │ │ ├── MethodHasParametersTest.java │ │ ├── MethodMatchersTest.java │ │ ├── MethodReturnsNonNullNextTokenTest.java │ │ ├── MethodReturnsNonNullStringTest.java │ │ ├── MethodReturnsNonNullToStringTest.java │ │ ├── MethodReturnsTest.java │ │ ├── NextStatementTest.java │ │ ├── NonNullLiteralTest.java │ │ ├── UnusedReturnValueMatcherTest.java │ │ └── method │ │ │ └── MethodInvocationMatcherTest.java │ │ ├── refaster │ │ ├── AbstractUTreeTest.java │ │ ├── BindingsTest.java │ │ ├── ChoiceTest.java │ │ ├── CodeTransformerTestHelper.java │ │ ├── CompilerBasedTest.java │ │ ├── DescriptionBasedDiffTest.java │ │ ├── Match.java │ │ ├── RefasterRuleTest.java │ │ ├── TemplateIntegrationTest.java │ │ ├── TemplatingTest.java │ │ ├── UAnnotationTest.java │ │ ├── UArrayAccessTest.java │ │ ├── UArrayTypeTest.java │ │ ├── UArrayTypeTreeTest.java │ │ ├── UAssignOpTest.java │ │ ├── UAssignTest.java │ │ ├── UBinaryTest.java │ │ ├── UBlockTest.java │ │ ├── UBreakTest.java │ │ ├── UClassIdentTest.java │ │ ├── UClassTypeTest.java │ │ ├── UConditionalTest.java │ │ ├── UContinueTest.java │ │ ├── UDoWhileLoopTest.java │ │ ├── UEnhancedForLoopTest.java │ │ ├── UExpressionStatementTest.java │ │ ├── UForAllTest.java │ │ ├── UForLoopTest.java │ │ ├── UFreeIdentTest.java │ │ ├── UIfTest.java │ │ ├── UInstanceOfTest.java │ │ ├── UIntersectionTypeTest.java │ │ ├── ULabeledStatementTest.java │ │ ├── ULiteralTest.java │ │ ├── ULocalVarIdentTest.java │ │ ├── UMemberSelectTest.java │ │ ├── UMethodInvocationTest.java │ │ ├── UMethodTypeTest.java │ │ ├── UNewClassTest.java │ │ ├── UParensTest.java │ │ ├── UPrimitiveTypeTest.java │ │ ├── UPrimitiveTypeTreeTest.java │ │ ├── URepeatedTest.java │ │ ├── UReturnTest.java │ │ ├── USkipTest.java │ │ ├── UStaticIdentTest.java │ │ ├── USynchronizedTest.java │ │ ├── UTemplaterTest.java │ │ ├── UThrowTest.java │ │ ├── UTypeApplyTest.java │ │ ├── UTypeCastTest.java │ │ ├── UTypeParameterTest.java │ │ ├── UTypeVarIdentTest.java │ │ ├── UTypeVarTest.java │ │ ├── UUnaryTest.java │ │ ├── UUnionTypeTest.java │ │ ├── UVariableDeclTest.java │ │ ├── UWhileLoopTest.java │ │ ├── UWildcardTest.java │ │ ├── UWildcardTypeTest.java │ │ ├── UnificationTest.java │ │ └── testdata │ │ │ ├── input │ │ │ ├── AnonymousClassTemplateExample.java │ │ │ ├── AnyOfTemplateExample.java │ │ │ ├── ArrayTemplateExample.java │ │ │ ├── AsVarargsTemplateExample.java │ │ │ ├── AssertTemplateExample.java │ │ │ ├── AutoboxingTemplateExample.java │ │ │ ├── BinaryTemplateExample.java │ │ │ ├── BlockPlaceholderTemplateExample.java │ │ │ ├── ComparisonChainTemplateExample.java │ │ │ ├── DiamondTemplateExample.java │ │ │ ├── EmitCommentBeforeTemplateExample.java │ │ │ ├── EmitCommentTemplateExample.java │ │ │ ├── ExplicitTypesPreservedTemplateExample.java │ │ │ ├── GenericPlaceholderTemplateExample.java │ │ │ ├── IfFallthroughTemplateExample.java │ │ │ ├── IfTemplateExample.java │ │ │ ├── ImplicitTypesInlinedTemplateExample.java │ │ │ ├── ImportClassDirectlyTemplateExample.java │ │ │ ├── InferLambdaBodyTypeExample.java │ │ │ ├── InferLambdaTypeExample.java │ │ │ ├── InferredThisTemplateExample.java │ │ │ ├── IsInstanceTemplateExample.java │ │ │ ├── LabelTemplateExample.java │ │ │ ├── LambdaImplicitTypeExample.java │ │ │ ├── LiteralTemplateExample.java │ │ │ ├── MayOptionallyUseTemplateExample.java │ │ │ ├── MemberSelectAndMethodParameterDisambiguationTemplateExample.java │ │ │ ├── MethodInvocationTemplateExample.java │ │ │ ├── MultiBoundTemplateExample.java │ │ │ ├── MultipleReferencesToIdentifierTemplateExample.java │ │ │ ├── NestedClassTemplateExample.java │ │ │ ├── NonJdkTypeTemplateExample.java │ │ │ ├── OneLineToTwoTemplateExample.java │ │ │ ├── ParenthesesOptionalTemplateExample.java │ │ │ ├── PlaceholderAllowedVarsTemplateExample.java │ │ │ ├── PlaceholderAllowsIdentityTemplateExample.java │ │ │ ├── PlaceholderTemplateExample.java │ │ │ ├── PrecedenceSensitiveTemplateExample.java │ │ │ ├── ReturnPlaceholderTemplateExample.java │ │ │ ├── SamePackageImportsTemplateExample.java │ │ │ ├── StaticFieldTemplateExample.java │ │ │ ├── StaticImportClassTokenTemplateExample.java │ │ │ ├── SuppressWarningsTemplateExample.java │ │ │ ├── TopLevelTemplateExample.java │ │ │ ├── TryMultiCatchTemplateExample.java │ │ │ ├── TryTemplateExample.java │ │ │ ├── TwoLinesToOneTemplateExample.java │ │ │ ├── TypeArgumentsMethodInvocationTemplateExample.java │ │ │ ├── UnnecessaryLambdaParensExample.java │ │ │ ├── UnqualifiedMethodTemplateExample.java │ │ │ ├── VarargTemplateExample.java │ │ │ ├── VariableDeclTemplateExample.java │ │ │ ├── VoidExpressionPlaceholderTemplateExample.java │ │ │ ├── WildcardTemplateExample.java │ │ │ └── WildcardUnificationTemplateExample.java │ │ │ ├── output │ │ │ ├── AnonymousClassTemplateExample.java │ │ │ ├── AnyOfTemplateExample.java │ │ │ ├── ArrayTemplateExample.java │ │ │ ├── AsVarargsTemplateExample.java │ │ │ ├── AssertTemplateExample.java │ │ │ ├── AutoboxingTemplateExample.java │ │ │ ├── BinaryTemplateExample.java │ │ │ ├── BlockPlaceholderTemplateExample.java │ │ │ ├── ComparisonChainTemplateExample.java │ │ │ ├── DiamondTemplateExample.java │ │ │ ├── EmitCommentBeforeTemplateExample.java │ │ │ ├── EmitCommentTemplateExample.java │ │ │ ├── ExplicitTypesPreservedTemplateExample.java │ │ │ ├── GenericPlaceholderTemplateExample.java │ │ │ ├── IfFallthroughTemplateExample.java │ │ │ ├── IfTemplateExample.java │ │ │ ├── ImplicitTypesInlinedTemplateExample.java │ │ │ ├── ImportClassDirectlyTemplateExample.java │ │ │ ├── InferLambdaBodyTypeExample.java │ │ │ ├── InferLambdaTypeExample.java │ │ │ ├── InferredThisTemplateExample.java │ │ │ ├── IsInstanceTemplateExample.java │ │ │ ├── LabelTemplateExample.java │ │ │ ├── LambdaImplicitTypeExample.java │ │ │ ├── LiteralTemplateExample.java │ │ │ ├── MayOptionallyUseTemplateExample.java │ │ │ ├── MemberSelectAndMethodParameterDisambiguationTemplateExample.java │ │ │ ├── MethodInvocationTemplateExample.java │ │ │ ├── MultiBoundTemplateExample.java │ │ │ ├── MultipleReferencesToIdentifierTemplateExample.java │ │ │ ├── NestedClassTemplateExample.java │ │ │ ├── NonJdkTypeTemplateExample.java │ │ │ ├── OneLineToTwoTemplateExample.java │ │ │ ├── ParenthesesOptionalTemplateExample.java │ │ │ ├── PlaceholderAllowedVarsTemplateExample.java │ │ │ ├── PlaceholderAllowsIdentityTemplateExample.java │ │ │ ├── PlaceholderTemplateExample.java │ │ │ ├── PrecedenceSensitiveTemplateExample.java │ │ │ ├── ReturnPlaceholderTemplateExample.java │ │ │ ├── SamePackageImportsTemplateExample.java │ │ │ ├── StaticFieldTemplateExample.java │ │ │ ├── StaticImportClassTokenTemplateExample.java │ │ │ ├── SuppressWarningsTemplateExample.java │ │ │ ├── TopLevelTemplateExample.java │ │ │ ├── TryMultiCatchTemplateExample.java │ │ │ ├── TryTemplateExample.java │ │ │ ├── TwoLinesToOneTemplateExample.java │ │ │ ├── TypeArgumentsMethodInvocationTemplateExample.java │ │ │ ├── UnnecessaryLambdaParensExample.java │ │ │ ├── UnqualifiedMethodTemplateExample.java │ │ │ ├── VarargTemplateExample.java │ │ │ ├── VariableDeclTemplateExample.java │ │ │ ├── VoidExpressionPlaceholderTemplateExample.java │ │ │ ├── WildcardTemplateExample.java │ │ │ └── WildcardUnificationTemplateExample.java │ │ │ └── template │ │ │ ├── AnonymousClassTemplate.java │ │ │ ├── AnyOfTemplate.java │ │ │ ├── ArrayTemplate.java │ │ │ ├── AsVarargsTemplate.java │ │ │ ├── AssertTemplate.java │ │ │ ├── AutoboxingTemplate.java │ │ │ ├── BinaryTemplate.java │ │ │ ├── BlockPlaceholderTemplate.java │ │ │ ├── ComparisonChainTemplate.java │ │ │ ├── DiamondTemplate.java │ │ │ ├── EmitCommentBeforeTemplate.java │ │ │ ├── EmitCommentTemplate.java │ │ │ ├── ExplicitTypesPreservedTemplate.java │ │ │ ├── ExpressionForbidsAllowCodeBetweenLinesTemplate.java │ │ │ ├── GenericPlaceholderTemplate.java │ │ │ ├── IfFallthroughTemplate.java │ │ │ ├── IfTemplate.java │ │ │ ├── ImplicitTypesInlinedTemplate.java │ │ │ ├── ImportClassDirectlyTemplate.java │ │ │ ├── InferLambdaBodyType.java │ │ │ ├── InferLambdaType.java │ │ │ ├── InferredThisTemplate.java │ │ │ ├── IsInstanceTemplate.java │ │ │ ├── KeyBindingErrorTemplate.java │ │ │ ├── LabelTemplate.java │ │ │ ├── LambdaImplicitType.java │ │ │ ├── LiteralTemplate.java │ │ │ ├── MayOptionallyUseTemplate.java │ │ │ ├── MemberSelectAndMethodParameterDisambiguationTemplate.java │ │ │ ├── MethodInvocationTemplate.java │ │ │ ├── MultiBoundTemplate.java │ │ │ ├── MultipleReferencesToIdentifierTemplate.java │ │ │ ├── NestedClassTemplate.java │ │ │ ├── NonJdkTypeTemplate.java │ │ │ ├── OneLineToTwoTemplate.java │ │ │ ├── ParenthesesOptionalTemplate.java │ │ │ ├── PlaceholderAllowedVarsTemplate.java │ │ │ ├── PlaceholderAllowsIdentityTemplate.java │ │ │ ├── PlaceholderTemplate.java │ │ │ ├── PrecedenceSensitiveTemplate.java │ │ │ ├── ReturnPlaceholderTemplate.java │ │ │ ├── SamePackageImportsTemplate.java │ │ │ ├── StaticFieldTemplate.java │ │ │ ├── StaticImportClassTokenTemplate.java │ │ │ ├── SuppressWarningsTemplate.java │ │ │ ├── TopLevelTemplate.java │ │ │ ├── TryMultiCatchTemplate.java │ │ │ ├── TryTemplate.java │ │ │ ├── TwoLinesToOneTemplate.java │ │ │ ├── TypeArgumentsMethodInvocationTemplate.java │ │ │ ├── UnnecessaryLambdaParens.java │ │ │ ├── UnqualifiedMethodTemplate.java │ │ │ ├── VarargTemplate.java │ │ │ ├── VariableDeclTemplate.java │ │ │ ├── VoidExpressionPlaceholderTemplate.java │ │ │ ├── WildcardTemplate.java │ │ │ └── WildcardUnificationTemplate.java │ │ ├── scanner │ │ ├── ScannerSupplierTest.java │ │ └── ScannerTest.java │ │ ├── suppress │ │ ├── CustomSuppressionTest.java │ │ ├── SuppressLintTest.java │ │ ├── SuppressWarningsTest.java │ │ ├── UnsuppressibleTest.java │ │ └── testdata │ │ │ ├── SuppressLintNegativeCases.java │ │ │ ├── SuppressWarningsNegativeCases.java │ │ │ └── UnsuppressiblePositiveCases.java │ │ └── testdata │ │ ├── CommandLineFlagTestFile.java │ │ ├── DeleteGeneratedConstructorTestCase.java │ │ ├── ExtendedMultipleTopLevelClassesWithErrors.java │ │ ├── ExtendedMultipleTopLevelClassesWithNoErrors.java │ │ ├── FlowConstants.java │ │ ├── FlowSub.java │ │ ├── FlowSuper.java │ │ ├── MultipleTopLevelClassesWithErrors.java │ │ ├── MultipleTopLevelClassesWithNoErrors.java │ │ └── UsesAnnotationProcessor.java │ └── proto │ ├── durationtimestamp.proto │ ├── proto3_test.proto │ ├── proto_test.proto │ └── test.proto ├── docgen ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── google │ │ └── errorprone │ │ ├── BugPatternFileGenerator.java │ │ ├── BugPatternIndexWriter.java │ │ ├── DocGenTool.java │ │ └── resources │ │ ├── bugpattern.mustache │ │ ├── bugpatterns_external.mustache │ │ └── bugpatterns_internal.mustache │ └── test │ └── java │ └── com │ └── google │ └── errorprone │ ├── BugPatternFileGeneratorTest.java │ ├── BugPatternIndexWriterTest.java │ └── testdata │ ├── DeadException_frontmatter_pygments.md │ ├── DeadException_nofrontmatter_gfm.md │ └── DontDoThis_nofrontmatter_gfm.md ├── docgen_processor ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── google │ └── errorprone │ ├── BugPatternInstance.java │ └── DocGenProcessor.java ├── docs └── bugpattern │ ├── AddressSelection.md │ ├── AlreadyChecked.md │ ├── AmbiguousMethodReference.md │ ├── AndroidInjectionBeforeSuper.md │ ├── AndroidJdkLibsChecker.md │ ├── AnnotateFormatMethod.md │ ├── AnnotationMirrorToString.md │ ├── AnnotationPosition.md │ ├── AnnotationValueToString.md │ ├── ArgumentSelectionDefectChecker.md │ ├── ArrayEquals.md │ ├── ArrayFillIncompatibleType.md │ ├── ArrayHashCode.md │ ├── ArrayRecordComponent.md │ ├── ArrayToString.md │ ├── ArraysAsListPrimitiveArray.md │ ├── AssertEqualsArgumentOrderChecker.md │ ├── AssertFalse.md │ ├── AssertThrowsMultipleStatements.md │ ├── AssertionFailureIgnored.md │ ├── AssignmentExpression.md │ ├── AssistedInjectAndInjectOnConstructors.md │ ├── AssistedInjectAndInjectOnSameConstructor.md │ ├── AsyncCallableReturnsNull.md │ ├── AsyncFunctionReturnsNull.md │ ├── AttemptedNegativeZero.md │ ├── AutoFactoryAtInject.md │ ├── AutoValueBoxedValues.md │ ├── AutoValueConstructorOrderChecker.md │ ├── AutoValueFinalMethods.md │ ├── AutoValueImmutableFields.md │ ├── AvoidObjectArrays.md │ ├── BadAnnotationImplementation.md │ ├── BadComparable.md │ ├── BadInstanceof.md │ ├── BadShiftAmount.md │ ├── BanClassLoader.md │ ├── BanJNDI.md │ ├── BanSerializableRead.md │ ├── BigDecimalEquals.md │ ├── BigDecimalLiteralDouble.md │ ├── BindingToUnqualifiedCommonType.md │ ├── BooleanParameter.md │ ├── BoxedPrimitiveConstructor.md │ ├── BoxedPrimitiveEquality.md │ ├── BuilderReturnThis.md │ ├── ByteBufferBackingArray.md │ ├── CannotMockFinalClass.md │ ├── CannotMockMethod.md │ ├── CanonicalDuration.md │ ├── CatchAndPrintStackTrace.md │ ├── CatchFail.md │ ├── ChainedAssertionLosesContext.md │ ├── ChainingConstructorIgnoresParameter.md │ ├── CharacterGetNumericValue.md │ ├── CheckReturnValue.md │ ├── CheckedExceptionNotThrown.md │ ├── ClassCanBeStatic.md │ ├── ClassInitializationDeadlock.md │ ├── ClassName.md │ ├── ClassNamedLikeTypeParameter.md │ ├── ClassNewInstance.md │ ├── CloseableProvides.md │ ├── ClosingStandardOutputStreams.md │ ├── CollectionIncompatibleType.md │ ├── CollectionUndefinedEquality.md │ ├── ComparableAndComparator.md │ ├── ComparableType.md │ ├── CompareToZero.md │ ├── ComparisonContractViolated.md │ ├── CompatibleWithAnnotationMisuse.md │ ├── CompileTimeConstant.md │ ├── ComplexBooleanConstant.md │ ├── ComputeIfAbsentAmbiguousReference.md │ ├── ConditionalExpressionNumericPromotion.md │ ├── ConstantField.md │ ├── ConstantOverflow.md │ ├── ConstantPatternCompile.md │ ├── DaggerProvidesNull.md │ ├── DateFormatConstant.md │ ├── DeadException.md │ ├── DeadThread.md │ ├── DeeplyNested.md │ ├── DefaultCharset.md │ ├── DefaultPackage.md │ ├── DepAnn.md │ ├── DeprecatedVariable.md │ ├── DirectInvocationOnMock.md │ ├── DistinctVarargsChecker.md │ ├── DoNotCall.md │ ├── DoNotClaimAnnotations.md │ ├── DoNotMockAutoValue.md │ ├── DoubleBraceInitialization.md │ ├── DoubleCheckedLocking.md │ ├── DuplicateBranches.md │ ├── DuplicateMapKeys.md │ ├── EmptyCatch.md │ ├── EmptyIf.md │ ├── EmptySetMultibindingContributions.md │ ├── EmptyTopLevelDeclaration.md │ ├── EnumOrdinal.md │ ├── EqualsGetClass.md │ ├── EqualsHashCode.md │ ├── EqualsIncompatibleType.md │ ├── EqualsNaN.md │ ├── EqualsNull.md │ ├── EqualsReference.md │ ├── EqualsUnsafeCast.md │ ├── EqualsUsingHashCode.md │ ├── EqualsWrongThing.md │ ├── ErroneousThreadPoolConstructorChecker.md │ ├── ExpectedExceptionChecker.md │ ├── ExtendsAutoValue.md │ ├── ExtendsObject.md │ ├── FallThrough.md │ ├── FieldCanBeLocal.md │ ├── FieldCanBeStatic.md │ ├── FieldMissingNullable.md │ ├── Finalize.md │ ├── Finally.md │ ├── FloatCast.md │ ├── FloatingPointAssertionWithinEpsilon.md │ ├── FloatingPointLiteralPrecision.md │ ├── FloggerArgumentToString.md │ ├── FloggerStringConcatenation.md │ ├── ForEachIterable.md │ ├── ForOverride.md │ ├── FormatString.md │ ├── FormatStringAnnotation.md │ ├── FunctionalInterfaceClash.md │ ├── FunctionalInterfaceMethodChanged.md │ ├── FutureReturnValueIgnored.md │ ├── FutureTransformAsync.md │ ├── FuturesGetCheckedIllegalExceptionType.md │ ├── FuzzyEqualsShouldNotBeUsedInEqualsMethod.md │ ├── GetClassOnAnnotation.md │ ├── GetClassOnClass.md │ ├── GetClassOnEnum.md │ ├── GuardedBy.md │ ├── GuiceAssistedInjectScoping.md │ ├── GuiceAssistedParameters.md │ ├── GuiceInjectOnFinalField.md │ ├── HashtableContains.md │ ├── HidingField.md │ ├── ICCProfileGetInstance.md │ ├── IdentifierName.md │ ├── IdentityBinaryExpression.md │ ├── IdentityHashMapBoxing.md │ ├── IdentityHashMapUsage.md │ ├── Immutable.md │ ├── ImmutableAnnotationChecker.md │ ├── ImmutableEnumChecker.md │ ├── ImpossibleNullComparison.md │ ├── IncompatibleArgumentType.md │ ├── IncompatibleModifiers.md │ ├── InconsistentCapitalization.md │ ├── InconsistentHashCode.md │ ├── InconsistentOverloads.md │ ├── IncorrectMainMethod.md │ ├── InexactVarargsConditional.md │ ├── InfiniteRecursion.md │ ├── InjectInvalidTargetingOnScopingAnnotation.md │ ├── InjectMoreThanOneQualifier.md │ ├── InjectMoreThanOneScopeAnnotationOnClass.md │ ├── InjectOnConstructorOfAbstractClass.md │ ├── InjectScopeAnnotationOnInterfaceOrAbstractClass.md │ ├── InjectedConstructorAnnotations.md │ ├── InlineFormatString.md │ ├── InlineTrivialConstant.md │ ├── InputStreamSlowMultibyteRead.md │ ├── InsecureCryptoUsage.md │ ├── IntFloatConversion.md │ ├── IntLongMath.md │ ├── InterfaceWithOnlyStatics.md │ ├── InterruptedExceptionSwallowed.md │ ├── Interruption.md │ ├── InvalidLink.md │ ├── InvalidPatternSyntax.md │ ├── InvalidTimeZoneID.md │ ├── IsInstanceOfClass.md │ ├── IsLoggableTagLength.md │ ├── IterableAndIterator.md │ ├── IterablePathParameter.md │ ├── JUnit3FloatingPointComparisonWithoutDelta.md │ ├── JUnit3TestNotRun.md │ ├── JUnit4ClassAnnotationNonStatic.md │ ├── JUnit4SetUpNotRun.md │ ├── JUnit4TearDownNotRun.md │ ├── JUnit4TestNotRun.md │ ├── JUnitAmbiguousTestClass.md │ ├── JavaLangClash.md │ ├── JavaUtilDate.md │ ├── JavaxInjectOnAbstractMethod.md │ ├── JavaxInjectOnFinalField.md │ ├── JdkObsolete.md │ ├── LabelledBreakTarget.md │ ├── LambdaFunctionalInterface.md │ ├── LeakingForkedAndroidBundle.md │ ├── LenientFormatStringValidation.md │ ├── LiteByteStringUtf8.md │ ├── LiteEnumValueOf.md │ ├── LiteProtoToString.md │ ├── LockNotBeforeTry.md │ ├── LockOnBoxedPrimitive.md │ ├── LockOnNonEnclosingClassLiteral.md │ ├── LogicalAssignment.md │ ├── LongDoubleConversion.md │ ├── LongFloatConversion.md │ ├── LongLiteralLowerCaseSuffix.md │ ├── LoopOverCharArray.md │ ├── MathAbsoluteNegative.md │ ├── MethodCanBeStatic.md │ ├── MislabeledAndroidString.md │ ├── MisleadingEscapedSpace.md │ ├── MissingCasesInEnumSwitch.md │ ├── MissingDefault.md │ ├── MissingFail.md │ ├── MissingOverride.md │ ├── MissingRefasterAnnotation.md │ ├── MissingRuntimeRetention.md │ ├── MissingSuperCall.md │ ├── MissingTestCall.md │ ├── MisusedWeekYear.md │ ├── MixedArrayDimensions.md │ ├── MixedDescriptors.md │ ├── MixedMutabilityReturnType.md │ ├── MockitoDoSetup.md │ ├── MockitoUsage.md │ ├── ModifiedButNotUsed.md │ ├── ModifyCollectionInEnhancedForLoop.md │ ├── ModifySourceCollectionInStream.md │ ├── ModifyingCollectionWithItself.md │ ├── MoreThanOneInjectableConstructor.md │ ├── MoveToSafeHtmlResponse.md │ ├── MultipleTopLevelClasses.md │ ├── MultipleUnaryOperatorsInMethodCall.md │ ├── MustBeClosedChecker.md │ ├── MutableGuiceModule.md │ ├── MutablePublicArray.md │ ├── NCopiesOfChar.md │ ├── NamedLikeContextualKeyword.md │ ├── NarrowCalculation.md │ ├── NarrowingCompoundAssignment.md │ ├── NewFileSystem.md │ ├── NoAllocation.md │ ├── NonAtomicVolatileUpdate.md │ ├── NonCanonicalStaticImport.md │ ├── NonCanonicalStaticMemberImport.md │ ├── NonCanonicalType.md │ ├── NonFinalCompileTimeConstant.md │ ├── NonFinalStaticField.md │ ├── NonOverridingEquals.md │ ├── NonRuntimeAnnotation.md │ ├── NullOptional.md │ ├── NullTernary.md │ ├── NullableConstructor.md │ ├── NullableOnContainingClass.md │ ├── NullableOptional.md │ ├── NullablePrimitive.md │ ├── NullablePrimitiveArray.md │ ├── NullableTypeParameter.md │ ├── NullableVoid.md │ ├── NullableWildcard.md │ ├── ObjectToString.md │ ├── ObjectsHashCodePrimitive.md │ ├── OperatorPrecedence.md │ ├── OptionalEquality.md │ ├── OptionalMapToOptional.md │ ├── OptionalNotPresent.md │ ├── OrphanedFormatString.md │ ├── OutlineNone.md │ ├── OverlappingQualifierAndScopeAnnotation.md │ ├── OverrideThrowableToString.md │ ├── Overrides.md │ ├── OverridesGuiceInjectableMethod.md │ ├── OverridesJavaxInjectableMethod.md │ ├── OverridingMethodInconsistentArgumentNamesChecker.md │ ├── PackageInfo.md │ ├── PackageLocation.md │ ├── ParameterComment.md │ ├── ParameterName.md │ ├── PatternMatchingInstanceof.md │ ├── PreconditionsExpensiveString.md │ ├── PreconditionsInvalidPlaceholder.md │ ├── PreferJavaTimeOverload.md │ ├── PreferredInterfaceType.md │ ├── PrimitiveArrayPassedToVarargsMethod.md │ ├── PrivateConstructorForNoninstantiableModule.md │ ├── PrivateConstructorForUtilityClass.md │ ├── ProtoStringFieldReferenceEquality.md │ ├── ProtoTruthMixedDescriptors.md │ ├── ProtocolBufferOrdinal.md │ ├── ProvidesMethodOutsideOfModule.md │ ├── QualifierOrScopeOnInjectMethod.md │ ├── QualifierWithTypeUse.md │ ├── RandomCast.md │ ├── RandomModInteger.md │ ├── RectIntersectReturnValueIgnored.md │ ├── RedundantControlFlow.md │ ├── RedundantOverride.md │ ├── RedundantSetterCall.md │ ├── ReferenceEquality.md │ ├── RemoveUnusedImports.md │ ├── RequiredModifiers.md │ ├── RestrictedApi.md │ ├── RethrowReflectiveOperationExceptionAsLinkageError.md │ ├── ReturnAtTheEndOfVoidFunction.md │ ├── ReturnMissingNullable.md │ ├── ReturnValueIgnored.md │ ├── ScopeOnModule.md │ ├── SelfAlwaysReturnsThis.md │ ├── SelfAssertion.md │ ├── SelfAssignment.md │ ├── SelfComparison.md │ ├── SelfEquals.md │ ├── SelfSet.md │ ├── ShortCircuitBoolean.md │ ├── SizeGreaterThanOrEqualsZero.md │ ├── StatementSwitchToExpressionSwitch.md │ ├── StaticAssignmentInConstructor.md │ ├── StaticAssignmentOfThrowable.md │ ├── StaticGuardedByInstance.md │ ├── StaticMockMember.md │ ├── StaticOrDefaultInterfaceMethod.md │ ├── StaticProtoFuzzer.md │ ├── StaticQualifiedUsingExpression.md │ ├── StreamResourceLeak.md │ ├── StreamToIterable.md │ ├── StreamToString.md │ ├── StringBuilderInitWithChar.md │ ├── StringCaseLocaleUsage.md │ ├── StringConcatToTextBlock.md │ ├── StringSplitter.md │ ├── SunApi.md │ ├── SuperCallToObjectMethod.md │ ├── SuppressWarningsDeprecated.md │ ├── SuppressWarningsWithoutExplanation.md │ ├── SwigMemoryLeak.md │ ├── SynchronizeOnNonFinalField.md │ ├── SystemConsoleNull.md │ ├── SystemExitOutsideMain.md │ ├── TestExceptionChecker.md │ ├── ThreadJoinLoop.md │ ├── ThreadLocalUsage.md │ ├── ThreadPriorityCheck.md │ ├── ThreeLetterTimeZoneID.md │ ├── ThrowIfUncheckedKnownChecked.md │ ├── ThrowsUncheckedException.md │ ├── TooManyParameters.md │ ├── TraditionalSwitchExpression.md │ ├── TreeToString.md │ ├── TruthAssertExpected.md │ ├── TruthConstantAsserts.md │ ├── TruthGetOrDefault.md │ ├── TruthIncompatibleType.md │ ├── TryFailThrowable.md │ ├── TryWithResourcesVariable.md │ ├── TypeEquals.md │ ├── TypeNameShadowing.md │ ├── TypeParameterQualifier.md │ ├── TypeParameterShadowing.md │ ├── TypeParameterUnusedInFormals.md │ ├── TypeToString.md │ ├── URLEqualsHashCode.md │ ├── UndefinedEquals.md │ ├── UngroupedOverloads.md │ ├── UnicodeEscape.md │ ├── UnicodeInCode.md │ ├── UnnecessarilyVisible.md │ ├── UnnecessaryAnonymousClass.md │ ├── UnnecessaryAssignment.md │ ├── UnnecessaryBoxedAssignment.md │ ├── UnnecessaryBreakInSwitch.md │ ├── UnnecessaryDefaultInEnumSwitch.md │ ├── UnnecessaryLambda.md │ ├── UnnecessaryMethodReference.md │ ├── UnnecessaryQualifier.md │ ├── UnnecessarySetDefault.md │ ├── UnnecessaryStaticImport.md │ ├── UnnecessaryTestMethodPrefix.md │ ├── UnnecessaryTypeArgument.md │ ├── UnsafeFinalization.md │ ├── UnsafeLocaleUsage.md │ ├── UnsafeReflectiveConstructionCast.md │ ├── UnsynchronizedOverridesSynchronized.md │ ├── UnusedAnonymousClass.md │ ├── UnusedCollectionModifiedInPlace.md │ ├── UnusedException.md │ ├── UnusedMethod.md │ ├── UnusedVariable.md │ ├── UseBinds.md │ ├── UseCorrectAssertInTests.md │ ├── UseEnumSwitch.md │ ├── Var.md │ ├── VarTypeName.md │ ├── VariableNameSameAsType.md │ ├── WaitNotInLoop.md │ ├── WildcardImport.md │ ├── WithSignatureDiscouraged.md │ ├── WrongOneof.md │ ├── XorPower.md │ ├── android │ ├── BinderIdentityRestoredDangerously.md │ ├── BundleDeserializationCast.md │ ├── FragmentInjection.md │ ├── FragmentNotInstantiable.md │ ├── HardCodedSdCardPath.md │ ├── ParcelableCreator.md │ └── WakelockReleasedDangerously.md │ ├── flogger │ ├── FloggerLogString.md │ ├── FloggerLogWithCause.md │ ├── FloggerRedundantIsEnabled.md │ └── FloggerWithoutCause.md │ ├── inject │ └── InjectOnMemberAndConstructor.md │ ├── javadoc │ ├── AlmostJavadoc.md │ ├── EmptyBlockTag.md │ ├── EscapedEntity.md │ ├── InheritDoc.md │ ├── InvalidBlockTag.md │ ├── InvalidInlineTag.md │ ├── InvalidParam.md │ ├── InvalidThrows.md │ ├── InvalidThrowsLink.md │ ├── MalformedInlineTag.md │ ├── MissingSummary.md │ ├── NotJavadoc.md │ ├── ReturnFromVoid.md │ ├── UnescapedEntity.md │ └── UnrecognisedJavadocTag.md │ ├── nullness │ ├── EqualsBrokenForNull.md │ └── UnnecessaryCheckNotNull.md │ └── time │ ├── JavaPeriodGetDays.md │ └── StronglyTypeTime.md ├── examples └── plugin │ └── bazel │ ├── java │ └── com │ │ └── google │ │ └── errorprone │ │ └── sample │ │ └── BUILD │ └── third_party │ └── java │ └── auto_service │ └── BUILD ├── pom.xml ├── refaster ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── google │ └── errorprone │ └── refaster │ ├── RefasterRuleCompiler.java │ └── RefasterRuleCompilerAnalyzer.java ├── test_helpers ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── google │ │ └── errorprone │ │ ├── BugCheckerRefactoringTestHelper.java │ │ ├── CompilationTestHelper.java │ │ ├── DiagnosticTestHelper.java │ │ ├── FileManagers.java │ │ └── FileObjects.java │ └── test │ └── java │ └── com │ └── google │ └── errorprone │ ├── BugCheckerRefactoringTestHelperTest.java │ └── CompilationTestHelperTest.java ├── type_annotations └── pom.xml └── util └── generate-latest-docs.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.gitignore 3 | **/.project 4 | **/.settings 5 | **/target/* 6 | *.iml 7 | .java-version 8 | 9 | # intellij 10 | .idea/ant.xml 11 | .idea/codestream.xml 12 | .idea/codeStyleSettings.xml 13 | .idea/compiler.xml 14 | .idea/copyright 15 | .idea/dataSources.ids 16 | .idea/dataSources.local.xml 17 | .idea/dictionaries 18 | .idea/encodings.xml 19 | .idea/inspectionProfiles/ 20 | .idea/jarRepositories.xml 21 | .idea/libraries 22 | .idea/misc.xml 23 | .idea/modules.xml 24 | .idea/shelf 25 | .idea/tasks.xml 26 | .idea/uiDesigner.xml 27 | .idea/vcs.xml 28 | .idea/workspace.xml 29 | 30 | # bazel 31 | bazel-bazel 32 | bazel-bin 33 | bazel-error-prone 34 | bazel-genfiles 35 | bazel-out 36 | bazel-testlogs 37 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | error_prone -------------------------------------------------------------------------------- /.idea/copyright/Google.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/google-java-format.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the list of Error Prone authors for copyright purposes. 2 | # 3 | # This does not necessarily list everyone who has contributed code, since in 4 | # some cases, their employer may be the copyright holder. To see the full list 5 | # of contributors, see the revision history in source control. 6 | Google Inc. 7 | Two Sigma Open Source 8 | Picnic Technologies 9 | -------------------------------------------------------------------------------- /annotations/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | open module com.google.errorprone.annotations { 18 | requires java.compiler; 19 | 20 | exports com.google.errorprone.annotations; 21 | exports com.google.errorprone.annotations.concurrent; 22 | } 23 | -------------------------------------------------------------------------------- /bnd.bnd: -------------------------------------------------------------------------------- 1 | -fixupmessages: "Classes found in the wrong directory"; restrict:=error; is:=warning 2 | -------------------------------------------------------------------------------- /check_api/src/main/java/com/google/errorprone/InvalidCommandLineOptionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.errorprone; 18 | 19 | public class InvalidCommandLineOptionException extends RuntimeException { 20 | 21 | public InvalidCommandLineOptionException(String message) { 22 | super(message); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /check_api/src/main/java/com/google/errorprone/apply/FileSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.errorprone.apply; 18 | 19 | import java.io.IOException; 20 | 21 | /** 22 | * @author sjnickerson@google.com (Simon Nickerson) 23 | */ 24 | public interface FileSource { 25 | 26 | SourceFile readFile(String path) throws IOException; 27 | } 28 | -------------------------------------------------------------------------------- /check_api/src/main/java/com/google/errorprone/fixes/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** Support code for providing automated corrections for defects we find. */ 18 | package com.google.errorprone.fixes; 19 | -------------------------------------------------------------------------------- /check_api/src/main/java/com/google/errorprone/matchers/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * A predicate DSL for matching javac AST nodes. This allows concise, readable declarative code for 19 | * describing a match, by composing generic-type-safe matchers on the inspected AST subtree. 20 | */ 21 | package com.google.errorprone.matchers; 22 | -------------------------------------------------------------------------------- /check_api/src/main/java/com/google/errorprone/suppliers/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Supports matchers, but rather than giving Matcher implementations which are predicates on 19 | * individual AST nodes, a supplier gives contextual information from the traversal of the AST. 20 | */ 21 | package com.google.errorprone.suppliers; 22 | -------------------------------------------------------------------------------- /check_api/src/main/java/com/google/errorprone/util/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** Utility code. */ 18 | package com.google.errorprone.util; 19 | -------------------------------------------------------------------------------- /check_api/src/test/java/com/google/errorprone/util/InheritedAnnotation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.errorprone.util; 18 | 19 | import java.lang.annotation.Inherited; 20 | 21 | @Inherited 22 | public @interface InheritedAnnotation {} 23 | -------------------------------------------------------------------------------- /core/src/main/java/com/google/errorprone/bugpatterns/apidiff/8to11diff.binarypb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/error-prone/962f83aac3193dca53129e8e3b34740176bc0bde/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/8to11diff.binarypb -------------------------------------------------------------------------------- /core/src/main/java/com/google/errorprone/bugpatterns/apidiff/android.binarypb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/error-prone/962f83aac3193dca53129e8e3b34740176bc0bde/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/android.binarypb -------------------------------------------------------------------------------- /core/src/main/java/com/google/errorprone/bugpatterns/apidiff/android_java8.binarypb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/error-prone/962f83aac3193dca53129e8e3b34740176bc0bde/core/src/main/java/com/google/errorprone/bugpatterns/apidiff/android_java8.binarypb -------------------------------------------------------------------------------- /core/src/main/java/com/google/errorprone/bugpatterns/inject/dagger/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** Bug patterns related to Dagger. */ 18 | package com.google.errorprone.bugpatterns.inject.dagger; 19 | -------------------------------------------------------------------------------- /core/src/main/java/com/google/errorprone/bugpatterns/inject/guice/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** Bug patterns related to Guice. */ 18 | package com.google.errorprone.bugpatterns.inject.guice; 19 | -------------------------------------------------------------------------------- /core/src/main/java/com/google/errorprone/bugpatterns/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** Checks added to the java compiler which detect common bug patterns. */ 18 | package com.google.errorprone.bugpatterns; 19 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/bugpatterns/android/testdata/CustomFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.errorprone.bugpatterns.android.testdata; 18 | 19 | /** 20 | * @author jasonlong@google.com (Jason Long) 21 | */ 22 | public class CustomFragment {} 23 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/bugpatterns/android/testdata/stubs/android/R.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package android; 17 | 18 | public class R { 19 | public static final class string { 20 | public static final int yes = 0; 21 | public static final int no = 1; 22 | public static final int copy = 2; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/bugpatterns/android/testdata/stubs/android/app/Fragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.app; 18 | 19 | public class Fragment {} 20 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/bugpatterns/android/testdata/stubs/android/os/Binder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.os; 18 | 19 | public class Binder { 20 | public static final long clearCallingIdentity() { 21 | return 1; 22 | } 23 | 24 | public static final void restoreCallingIdentity(long token) {} 25 | } 26 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/bugpatterns/android/testdata/stubs/android/os/Parcel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package android.os; 17 | 18 | public interface Parcel {} 19 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/bugpatterns/android/testdata/stubs/android/preference/PreferenceActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.preference; 18 | 19 | @SuppressWarnings("FragmentInjection") 20 | public class PreferenceActivity { 21 | protected boolean isValidFragment(String className) { 22 | return true; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/bugpatterns/android/testdata/stubs/android/support/v4/app/Fragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.support.v4.app; 18 | 19 | public class Fragment {} 20 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/bugpatterns/android/testdata/stubs/android/util/Log.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.util; 18 | 19 | public class Log { 20 | public static boolean isLoggable(String tag, int level) { 21 | return false; 22 | } 23 | 24 | public static final int INFO = 0; 25 | } 26 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/bugpatterns/collectionincompatibletype/something.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | syntax = "proto2"; 18 | 19 | option java_enable_dual_generate_mutable_api = true; 20 | option java_package = "com.google.errorprone.bugpatterns.collectionincompatibletype.testdata"; 21 | 22 | message Something {} 23 | 24 | message SomethingElse {} 25 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/bugpatterns/testdata/Allowlist.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.errorprone.bugpatterns.testdata; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Target; 20 | 21 | @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) 22 | public @interface Allowlist {} 23 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/bugpatterns/threadsafety/test.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | syntax = "proto2"; 18 | 19 | package test; 20 | 21 | option java_package = "com.google.errorprone.bugpatterns.threadsafety.proto"; 22 | option java_mutable_api = true; 23 | 24 | message User { 25 | optional string name = 1; 26 | optional int64 uid = 2; 27 | } 28 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/refaster/testdata/input/EmitCommentBeforeTemplateExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.google.errorprone.refaster.testdata; 16 | 17 | public class EmitCommentBeforeTemplateExample { 18 | public void example() { 19 | System.out.println("foobar".length()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/refaster/testdata/input/EmitCommentTemplateExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.google.errorprone.refaster.testdata; 16 | 17 | public class EmitCommentTemplateExample { 18 | public void example() { 19 | System.out.println("foobar"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/refaster/testdata/input/UnqualifiedMethodTemplateExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.google.errorprone.refaster.testdata; 16 | 17 | /** Test data for {@code UnqualifiedMethodTemplate}. */ 18 | public class UnqualifiedMethodTemplateExample { 19 | public int example() { 20 | return hashCode(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/refaster/testdata/output/EmitCommentBeforeTemplateExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.google.errorprone.refaster.testdata; 16 | 17 | public class EmitCommentBeforeTemplateExample { 18 | public void example() { 19 | System.out.println(/* comment here */ "foobar".length()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/refaster/testdata/output/EmitCommentTemplateExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package com.google.errorprone.refaster.testdata; 16 | 17 | public class EmitCommentTemplateExample { 18 | public void example() { 19 | // comment 20 | System.out.println("foobar"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/testdata/CommandLineFlagTestFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.errorprone.testdata; 18 | 19 | public class CommandLineFlagTestFile { 20 | public void foo() { 21 | return; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/testdata/DeleteGeneratedConstructorTestCase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.errorprone.testdata; 18 | 19 | public class DeleteGeneratedConstructorTestCase { 20 | // generated constructor goes here 21 | } 22 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/testdata/ExtendedMultipleTopLevelClassesWithErrors.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.errorprone.testdata; 18 | 19 | public class ExtendedMultipleTopLevelClassesWithErrors extends MultipleTopLevelClassesWithErrors {} 20 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/testdata/FlowConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.errorprone.testdata; 18 | 19 | public final class FlowConstants { 20 | public static final byte SOME_BYTE = 32; 21 | } 22 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/testdata/FlowSub.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.errorprone.testdata; 18 | 19 | public class FlowSub extends FlowSuper {} 20 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/testdata/FlowSuper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.errorprone.testdata; 18 | 19 | import static com.google.errorprone.testdata.FlowConstants.*; 20 | 21 | public class FlowSuper { 22 | byte myByte = SOME_BYTE; 23 | } 24 | -------------------------------------------------------------------------------- /core/src/test/java/com/google/errorprone/testdata/UsesAnnotationProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.errorprone.testdata; 18 | 19 | public class UsesAnnotationProcessor {} 20 | -------------------------------------------------------------------------------- /core/src/test/proto/test.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Error Prone Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | syntax = "proto2"; 18 | package test; 19 | 20 | option java_package = "com.google.errorprone.testdata.proto"; 21 | 22 | message User { 23 | optional string name = 1; 24 | optional int64 uid = 2; 25 | } 26 | -------------------------------------------------------------------------------- /docgen/src/main/java/com/google/errorprone/resources/bugpattern.mustache: -------------------------------------------------------------------------------- 1 | {{#frontmatter}} 2 | {{{frontmatter}}} 3 | {{/frontmatter}} 4 | 8 | 9 | {{^frontmatter}} 10 | # {{name}} 11 | {{#baseUrl}} 12 | 13 | {{baseUrl}}/{{name}} 14 | 15 | {{/baseUrl}} 16 | 17 | __{{summary}}__ 18 | 19 |
20 | 21 | {{#tags}} 22 | 23 | {{/tags}} 24 |
Severity{{severity}}
Tags{{tags}}
25 | 26 | {{/frontmatter}} 27 | {{#altNames}} 28 | _Alternate names: {{altNames}}_ 29 | {{/altNames}} 30 | 31 | {{#explanation}} 32 | ## The problem 33 | {{{explanation}}} 34 | {{/explanation}} 35 | 36 | {{#suppression}} 37 | ## Suppression 38 | {{{suppression}}} 39 | {{/suppression}} 40 | -------------------------------------------------------------------------------- /docgen/src/main/java/com/google/errorprone/resources/bugpatterns_external.mustache: -------------------------------------------------------------------------------- 1 | {{#frontmatter}} 2 | {{{frontmatter}}} 3 | {{/frontmatter}} 4 | 5 | # Bug patterns 6 | 7 | This list is auto-generated from our sources. 8 | 9 | Patterns which are marked __Experimental__ will not be evaluated against your 10 | code, unless you specifically configure Error Prone. The default checks are 11 | marked __On by default__, and each release promotes some experimental checks 12 | after we've vetted them against Google's codebase. 13 | 14 | {{#bugpatterns}} 15 | ## {{category}} 16 | 17 | {{#checks}} 18 | __[{{name}}](bugpattern/{{name}})__
19 | {{summary}} 20 | 21 | {{/checks}} 22 | {{/bugpatterns}} 23 | -------------------------------------------------------------------------------- /docgen/src/main/java/com/google/errorprone/resources/bugpatterns_internal.mustache: -------------------------------------------------------------------------------- 1 | # Bug patterns 2 | 3 | [TOC] 4 | 5 | This list is auto-generated from our sources. 6 | 7 | Patterns which are marked __Experimental__ will not be evaluated against your 8 | code, unless you specifically configure Error Prone. The default checks are 9 | marked __On by default__, and each release promotes some experimental checks 10 | after we've vetted them against Google's codebase. 11 | 12 | {{#bugpatterns}} 13 | ## {{category}} 14 | 15 | {{#checks}} 16 | __[{{name}}](bugpattern/{{name}}.md)__ \ 17 | {{summary}} 18 | 19 | {{/checks}} 20 | {{/bugpatterns}} 21 | -------------------------------------------------------------------------------- /docgen/src/test/java/com/google/errorprone/testdata/DeadException_frontmatter_pygments.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: DeadException 3 | summary: Exception created but not thrown 4 | layout: bugpattern 5 | tags: LikelyError 6 | severity: ERROR 7 | --- 8 | 9 | 13 | 14 | _Alternate names: ThrowableInstanceNeverThrown_ 15 | 16 | ## The problem 17 | The exception is created with new, but is not thrown, and the reference is lost. 18 | 19 | ## Suppression 20 | Suppress false positives by adding the suppression annotation `@SuppressWarnings("DeadException")` to the enclosing element. 21 | -------------------------------------------------------------------------------- /docgen/src/test/java/com/google/errorprone/testdata/DeadException_nofrontmatter_gfm.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | # DeadException 7 | 8 | __Exception created but not thrown__ 9 | 10 |
11 | 12 | 13 |
SeverityERROR
TagsLikelyError
14 | 15 | _Alternate names: ThrowableInstanceNeverThrown_ 16 | 17 | ## The problem 18 | The exception is created with new, but is not thrown, and the reference is lost. 19 | 20 | ## Suppression 21 | Suppress false positives by adding the suppression annotation `@SuppressWarnings("DeadException")` to the enclosing element. 22 | -------------------------------------------------------------------------------- /docgen/src/test/java/com/google/errorprone/testdata/DontDoThis_nofrontmatter_gfm.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | # DontDoThis 7 | 8 | __Don't do this; do List<Foo> instead__ 9 | 10 |
11 | 12 | 13 |
SeverityERROR
TagsLikelyError
14 | 15 | 16 | ## The problem 17 | This is a bad idea, you want `List` instead 18 | 19 | ## Suppression 20 | Suppress false positives by adding the suppression annotation `@SuppressWarnings("DontDoThis")` to the enclosing element. 21 | -------------------------------------------------------------------------------- /docs/bugpattern/AlreadyChecked.md: -------------------------------------------------------------------------------- 1 | Checking a provably-identical condition twice can be a sign of a logic error. 2 | 3 | For example: 4 | 5 | ```java 6 | public Optional first(Optional a, Optional b) { 7 | if (a.isPresent()) { 8 | return a; 9 | } else if (a.isPresent()) { // Oops--should be checking `b`. 10 | return b; 11 | } else { 12 | return Optional.empty(); 13 | } 14 | } 15 | ``` 16 | 17 | It can also be a sign of redundancy, which can just be removed. 18 | 19 | ```java 20 | public void act() { 21 | if (enabled) { 22 | frobnicate(); 23 | } else if (!enabled) { // !enabled is guaranteed to be true here, so the check can be removed 24 | doSomethingElse(); 25 | } 26 | } 27 | 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/bugpattern/AmbiguousMethodReference.md: -------------------------------------------------------------------------------- 1 | The following code is fine in Java 7, but poses a problem in Java 8. 2 | 3 | ```java 4 | static class A { 5 | B c(D d) { return null; } 6 | static B c(A a, D d) { return null; } 7 | } 8 | ``` 9 | 10 | The method reference `A::c` of the instance method `c` has an implicit first 11 | parameter for the `this` pointer. So both methods that `A::c` could resolve to 12 | are compatible with `BiFunction`, and the method reference is 13 | ambiguous. 14 | 15 | ```java 16 | void f(BiFunction f) { ... } 17 | ``` 18 | 19 | ``` 20 | error: incompatible types: invalid method reference 21 | f(A::c); 22 | ^ 23 | reference to c is ambiguous 24 | both method c(A,D) in A and method c(D) in A match 25 | ``` 26 | 27 | Consider renaming one of the methods to avoid the ambiguity. 28 | -------------------------------------------------------------------------------- /docs/bugpattern/AndroidInjectionBeforeSuper.md: -------------------------------------------------------------------------------- 1 | Members injection should always be called as early as possible to avoid 2 | uninitialized @Inject members. This is also crucial to protect against bugs 3 | during configuration changes and reattached Fragments to make sure that each 4 | framework type is injected in the appropriate order. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/AndroidJdkLibsChecker.md: -------------------------------------------------------------------------------- 1 | Code that needs to be compatible with Android cannot use types or members that 2 | only the latest or unreleased devices can handle 3 | 4 | ## Suppression 5 | 6 | WARNING: We *strongly* recommend checking your code with Android Lint if 7 | suppressing or disabling this check. 8 | 9 | The check can be suppressed in code that deliberately only targets newer Android 10 | SDK versions. 11 | 12 | To suppress for a particular statement, method, or class, use 13 | `@SuppressWarnings`: 14 | 15 | ``` 16 | @SuppressWarnings("AndroidJdkLibsChecker") // TODO(user): document suppression 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/bugpattern/AnnotationPosition.md: -------------------------------------------------------------------------------- 1 | Per the [style guide][style-guide], `TYPE_USE` annotations should appear 2 | immediately before the type being annotated, and after any modifiers: 3 | 4 | ```java 5 | public @Nullable V getOrNull(final Map map, final @Nullable K key) { 6 | return map.get(key); 7 | } 8 | ``` 9 | 10 | Non-`TYPE_USE` annotations should appear before modifiers, as they annotate the 11 | entire element (method, variable, class): 12 | 13 | ```java 14 | @VisibleForTesting 15 | public void reset() { 16 | // ... 17 | } 18 | ``` 19 | 20 | Javadoc must appear before any annotations, or the compiler will fail to 21 | recognise it as Javadoc: 22 | 23 | ```java 24 | @Nullable 25 | /** Might return a frobnicator. */ 26 | Frobnicator getFrobnicator(); 27 | ``` 28 | 29 | [style-guide]: https://google.github.io/styleguide/javaguide.html#s4.8.5.1-type-use-annotation-style 30 | -------------------------------------------------------------------------------- /docs/bugpattern/ArgumentSelectionDefectChecker.md: -------------------------------------------------------------------------------- 1 | If permuting the arguments of a method call means that the argument names are a 2 | better match for the parameter names than the original ordering then this might 3 | indicate that they have been accidentally swapped. There are also legitimate 4 | reasons for the names not to match such as when rotating an image (swap width 5 | and height). In this case we suggest annotating the names with a comment to make 6 | the deliberate swap clear to future readers of the code. Argument names 7 | annotated with a comment containing the parameter name will not generate a 8 | warning. 9 | -------------------------------------------------------------------------------- /docs/bugpattern/ArrayEquals.md: -------------------------------------------------------------------------------- 1 | Generally when comparing arrays for equality, the programmer intends to check 2 | that the contents of the arrays are equal rather than that they are actually the 3 | same object. But many commonly used equals methods compare arrays for reference 4 | equality rather than content equality. These include the instance `.equals()` 5 | method, Guava's `com.google.common.base.Objects#equal()`, JDK's 6 | `java.util.Objects#equals()`, and Android's 7 | `androidx.core.ObjectsCompat#equals()`. 8 | 9 | If reference equality is needed, `==` should be used instead for clarity. 10 | Otherwise, use `java.util.Arrays#equals()` to compare the contents of the 11 | arrays. 12 | -------------------------------------------------------------------------------- /docs/bugpattern/ArrayRecordComponent.md: -------------------------------------------------------------------------------- 1 | There are two main problems with having a component of a record be an array. 2 | 3 | 1. By default, the generated `equals` and `hashCode` will just call `equals` or 4 | `hashCode` on the array. Two distinct arrays are never considered equal by 5 | `equals` even if their contents are the same. The generated `toString` is 6 | similarly not useful, since it will be something like `[B@723279cf`. 7 | 8 | 2. Arrays are mutable, but records should not be mutable. A client of a record 9 | with an array component can change the contents of the array. 10 | 11 | Instead of an array component, consider something like `ImmutableList`, 12 | or, for primitive arrays, something like `ByteString` or `ImmutableIntArray`. 13 | -------------------------------------------------------------------------------- /docs/bugpattern/ArrayToString.md: -------------------------------------------------------------------------------- 1 | The `toString` method on an array will print its identity, such as 2 | `[I@4488aabb`. This is almost never needed. Use `Arrays.toString` to print a 3 | human-readable summary. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/ArraysAsListPrimitiveArray.md: -------------------------------------------------------------------------------- 1 | Arrays.asList does not autobox primitive arrays, as one might expect. If you 2 | intended to autobox the primitive array, use an asList method from Guava that 3 | does autobox. If you intended to create a singleton list containing the 4 | primitive array, use Collections.singletonList to make your intent clearer. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/AssertEqualsArgumentOrderChecker.md: -------------------------------------------------------------------------------- 1 | JUnit's assertEquals (and similar) are defined to take the expected value first 2 | and the actual value second. Getting these the wrong way round will cause a 3 | confusing error message if the assertion fails. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/AssertFalse.md: -------------------------------------------------------------------------------- 1 | Java assertions do not necessarily execute at runtime; they may be enabled and 2 | disabled depending on which options are passed to the JVM invocation. An assert 3 | false statement may be intended to ensure that the program never proceeds beyond 4 | that statement. If the correct execution of the program depends on that being 5 | the case, consider throwing an exception instead, so that execution is halted 6 | regardless of runtime configuration. 7 | -------------------------------------------------------------------------------- /docs/bugpattern/AssertionFailureIgnored.md: -------------------------------------------------------------------------------- 1 | JUnit's `fail()` and `assert*` methods throw an `AssertionError`, so using the 2 | try/fail/catch pattern to test for `AssertionError` (or any of its super-types) 3 | is incorrect. The following example will never fail: 4 | 5 | ```java 6 | try { 7 | doSomething(); 8 | fail("expected doSomething to throw AssertionError"); 9 | } catch (AssertionError expected) { 10 | // expected exception 11 | } 12 | ``` 13 | 14 | To avoid this issue, prefer JUnit's `assertThrows()` API: 15 | 16 | ```java 17 | import static com.google.common.truth.Truth.assertThat; 18 | import static org.junit.Assert.assertThrows; 19 | 20 | @Test 21 | public void testFailsWithAssertionError() { 22 | AssertionError thrown = assertThrows( 23 | AssertionError.class, 24 | () -> { 25 | doSomething(); 26 | }); 27 | assertThat(thrown).hasMessageThat().contains("something went terribly wrong"); 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/bugpattern/AssignmentExpression.md: -------------------------------------------------------------------------------- 1 | Using the result of an assignment expression can be quite unclear, except for 2 | simple cases where the result is used to initialise another variable, such as 3 | `x = y = 0`. 4 | 5 | Consider a common pattern of lazily initialising a field: 6 | 7 | ```java 8 | class Lazy { 9 | private T t = null; 10 | 11 | abstract T create(); 12 | 13 | public T get() { 14 | if (t != null) { 15 | return t; 16 | } 17 | return t = create(); 18 | } 19 | } 20 | ``` 21 | 22 | ```java 23 | class Lazy { 24 | private T t = null; 25 | 26 | abstract T create(); 27 | 28 | public T get() { 29 | if (t != null) { 30 | return t; 31 | } 32 | t = create(); 33 | return t; 34 | } 35 | } 36 | ``` 37 | 38 | At the cost of another line, it's now clearer what's happening. (Note that 39 | neither the before nor the after are thread-safe; this particular example would 40 | be better served with `Suppliers.memoizing`.) 41 | -------------------------------------------------------------------------------- /docs/bugpattern/AssistedInjectAndInjectOnConstructors.md: -------------------------------------------------------------------------------- 1 | Mixing @Inject and @AssistedInject leads to confusing code and the documentation 2 | specifies not to do it. See 3 | https://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/assistedinject/AssistedInject.html 4 | -------------------------------------------------------------------------------- /docs/bugpattern/AssistedInjectAndInjectOnSameConstructor.md: -------------------------------------------------------------------------------- 1 | Using @AssistedInject and @Inject on the same constructor is a runtimeerror in 2 | Guice. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/AsyncCallableReturnsNull.md: -------------------------------------------------------------------------------- 1 | Methods like Futures.whenAllComplete(...).callAsync(...) will throw a 2 | NullPointerException if the provided AsyncCallable returns a null Future. To 3 | produce a Future with an output of null, instead return immediateFuture(null). 4 | -------------------------------------------------------------------------------- /docs/bugpattern/AsyncFunctionReturnsNull.md: -------------------------------------------------------------------------------- 1 | Methods like Futures.transformAsync and Futures.catchingAsync will throw a 2 | NullPointerException if the provided AsyncFunction returns a null Future. To 3 | produce a Future with an output of null, instead return immediateFuture(null). 4 | -------------------------------------------------------------------------------- /docs/bugpattern/AttemptedNegativeZero.md: -------------------------------------------------------------------------------- 1 | Because `0` is an integer constant, `-0` is an integer, too. Integers have no 2 | concept of "negative zero," so it is the same as plain `0`. 3 | 4 | The value is then widened to a floating-point number. And while floating-point 5 | numbers have a concept of "negative zero," the integral `0` is widened to the 6 | floating-point "positive" zero. 7 | 8 | To write a negative zero, you have to write a constant that is a floating-point 9 | number. One simple way to do that is to write `-0.0`. 10 | -------------------------------------------------------------------------------- /docs/bugpattern/AutoFactoryAtInject.md: -------------------------------------------------------------------------------- 1 | @AutoFactory classes should not be @Inject-ed, inject the generated factory 2 | instead. Classes that are annotated with @AutoFactory are intended to be 3 | constructed by invoking the factory method on the generated factory. Typically 4 | this is because some of the necessary constructor arguments are not part of the 5 | binding graph. Generated @AutoFactory classes are automatically marked @Inject - 6 | prefer to inject that instead. 7 | -------------------------------------------------------------------------------- /docs/bugpattern/AutoValueBoxedValues.md: -------------------------------------------------------------------------------- 1 | AutoValue classes reject `null` values, unless the property is annotated with 2 | `@Nullable`. For this reason, the usage of boxed primitives (e.g. `Long`) is 3 | discouraged, except when annotated as `@Nullable`. Otherwise they can be 4 | replaced with the corresponding primitive. There could be some cases where the 5 | usage of a boxed primitive might be intentional to avoid boxing the value again 6 | after invoking the getter. 7 | 8 | ## Suppression 9 | 10 | Suppress violations by using `@SuppressWarnings("AutoValueBoxedValues")` on the 11 | relevant `abstract` getter and/or setter. 12 | -------------------------------------------------------------------------------- /docs/bugpattern/AutoValueConstructorOrderChecker.md: -------------------------------------------------------------------------------- 1 | AutoValue constructors are synthesized with their parameters in the same order 2 | as the abstract accessor methods. Calls to the constructor need to match this 3 | ordering. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/AutoValueFinalMethods.md: -------------------------------------------------------------------------------- 1 | Consider that other developers will try to read and understand your value class 2 | while looking only at your hand-written class, not the actual (generated) 3 | implementation class. If you mark your concrete methods final, they won't have 4 | to wonder whether the generated subclass might be overriding them. This is 5 | especially helpful if you are underriding equals, hashCode or toString! 6 | 7 | Reference: 8 | https://github.com/google/auto/blob/master/value/userguide/practices.md#mark-all-concrete-methods-final 9 | 10 | NOTE: 11 | [Since `@Memoized` methods can't be final](https://github.com/google/auto/blob/master/value/userguide/howto.md#memoize_hash_tostring), 12 | the check doesn't flag them. 13 | -------------------------------------------------------------------------------- /docs/bugpattern/AutoValueImmutableFields.md: -------------------------------------------------------------------------------- 1 | [AutoValue](https://github.com/google/auto/tree/master/value) instances should 2 | be deeply immutable. Therefore, we recommend using immutable types for fields. 3 | E.g., use `ImmutableMap` instead of `Map`, `ImmutableSet` instead of `Set`, etc. 4 | 5 | Read more at: 6 | 7 | * https://github.com/google/auto/blob/master/value/userguide/practices.md#avoid-mutable-property-types 8 | * https://github.com/google/auto/blob/master/value/userguide/builders-howto.md#-use-a-collection-valued-property 9 | 10 | Suppress violations by using `@SuppressWarnings("AutoValueImmutableFields")` on 11 | the relevant `abstract` getter. 12 | -------------------------------------------------------------------------------- /docs/bugpattern/BadComparable.md: -------------------------------------------------------------------------------- 1 | A narrowing integral conversion can cause a sign flip, since it simply discards 2 | all but the n lowest order bits, where n is the number of bits used to represent 3 | the target type (JLS 5.1.3). In a compare or compareTo method, this can cause 4 | incorrect and unstable sort orders. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/BadInstanceof.md: -------------------------------------------------------------------------------- 1 | Flags `instanceof` checks where the expression can be determined to be a 2 | supertype of the type it is compared to. 3 | 4 | [JLS 15.28](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28) 5 | specifically calls `instanceof` out as *not* being a compile-time constant 6 | expression, so the usage of this pattern can lead to unreachable code that won't 7 | be flagged by the compiler: 8 | 9 | ```java 10 | class Foo { 11 | void doSomething() { 12 | if (this instanceof Foo) { // BAD: always true 13 | return; 14 | } 15 | interestingProcessing(); 16 | } 17 | } 18 | ``` 19 | 20 | In general, an `instanceof` comparison against a superclass is equivalent to a 21 | null check: 22 | 23 | ```java 24 | foo instanceof Foo 25 | ``` 26 | 27 | ```java 28 | foo != null 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/bugpattern/BadShiftAmount.md: -------------------------------------------------------------------------------- 1 | For shift operations on int types, only the five lowest-order bits of the shift 2 | amount are used as the shift distance. This means that shift amounts that are 3 | not in the range 0 to 31, inclusive, are silently mapped to values in that 4 | range. For example, a shift of an int by 32 is equivalent to shifting by 0, 5 | i.e., a no-op. 6 | 7 | See JLS 15.19, "Shift Operators", for more details. 8 | -------------------------------------------------------------------------------- /docs/bugpattern/BanClassLoader.md: -------------------------------------------------------------------------------- 1 | The Java class loading APIs can lead to remote code execution vulnerabilities if 2 | not used carefully. Interpreting potentially untrusted input as bytecode can 3 | give an attacker control of the application. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/BanSerializableRead.md: -------------------------------------------------------------------------------- 1 | The Java `Serializable` API is very powerful, and very dangerous. Any 2 | consumption of a serialized object that cannot be explicitly trusted will likely 3 | result in a critical remote code execution bug that will give an attacker 4 | control of the application. (See 5 | [Effective Java 3rd Edition §85][ej3e-85]) 6 | 7 | [ej3e-85]: https://www.google.co.uk/books/edition/Effective_Java/ka2VUBqHiWkC 8 | 9 | Consider using less powerful serialization methods, such as JSON or XML. 10 | -------------------------------------------------------------------------------- /docs/bugpattern/BigDecimalEquals.md: -------------------------------------------------------------------------------- 1 | `BigDecimal`'s equals method compares the scale of the representation as well as 2 | the numeric value, which may not be expected. 3 | 4 | ```java 5 | BigDecimal a = new BigDecimal("1.0"); 6 | BigDecimal b = new BigDecimal("1.00"); 7 | a.equals(b); // false! 8 | ``` 9 | -------------------------------------------------------------------------------- /docs/bugpattern/BigDecimalLiteralDouble.md: -------------------------------------------------------------------------------- 1 | BigDecimal's `double` can lose precision in surprising ways. 2 | 3 | ```java 4 | // these are the same: 5 | new BigDecimal(0.1) 6 | new BigDecimal("0.1000000000000000055511151231257827021181583404541015625") 7 | ``` 8 | 9 | Prefer the `BigDecimal.valueOf(double)` method or the `new BigDecimal(String)` 10 | constructor. 11 | 12 | NOTE `BigDecimal.valueOf(double)` does not suffer from the same problem; it is 13 | equivalent to `new BigDecimal(Double.valueOf(double))`, and while `0.1` is not 14 | exactly representable, `Double.valueOf(0.1)` yields `"0.1"`. As long as 15 | [FloatingPointLiteralPrecision](./FloatingPointLiteralPrecision) doesn't 16 | generate a warning, `BigDecimal.valueOf` is safe. 17 | -------------------------------------------------------------------------------- /docs/bugpattern/BooleanParameter.md: -------------------------------------------------------------------------------- 1 | Providing parameter comments for boolean literals has some advantages: 2 | 3 | * Readability is generally improved, as the parameter name will likely provide 4 | some context on what the boolean literal means 5 | * [https://errorprone.info/bugpattern/ParameterName](ParameterName) checks at compile-time that the 6 | comments match the formal argument names to avoid accidentally transposing 7 | parameters 8 | -------------------------------------------------------------------------------- /docs/bugpattern/BoxedPrimitiveConstructor.md: -------------------------------------------------------------------------------- 1 | Constructors of primitive wrapper objects (e.g. `new Boolean(true)` will be 2 | [deprecated][8145468] in Java 9. The `valueOf` factory methods (e.g. 3 | `Boolean.valueOf(true)`) should always be preferred. Those methods are called 4 | implicitly by autoboxing, which is often more convenient than an explicit call. 5 | `Integer x = Integer.valueOf(23);` and `Integer x = 23;` are equivalent. 6 | 7 | [8145468]: https://bugs.openjdk.java.net/browse/JDK-8145468 8 | 9 | The explicit constructors always return a fresh instance, resulting in 10 | unnecessary allocations. The `valueOf` methods return cached instances for 11 | frequently requested values, offering significantly better space and time 12 | performance. 13 | 14 | Relying on the unique reference identity of the instances returned by the 15 | explicit constructors is extremely bad practice. Primitives should always be 16 | treated as identity-less value types, even in their boxed representations. 17 | -------------------------------------------------------------------------------- /docs/bugpattern/BoxedPrimitiveEquality.md: -------------------------------------------------------------------------------- 1 | Comparison using reference equality instead of value equality. The inputs to 2 | this comparison are boxed primitive types, where reference equality is 3 | particularly bug-prone: Primitive wrapper classes cache instances for some (but 4 | usually not all) values, so == may be equivalent to equals() for some values but 5 | not others. Additionally, not all versions of the runtime and other libraries 6 | use the cache in the same cases, so upgrades may change behavior. Furthermore, 7 | reference identity is usually not useful for primitive wrappers, as they are 8 | immutable types whose equals() method fully compares their values. 9 | -------------------------------------------------------------------------------- /docs/bugpattern/CannotMockFinalClass.md: -------------------------------------------------------------------------------- 1 | Mockito cannot mock final classes. See https://github.com/mockito/mockito/wiki/FAQ 2 | for details. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/CannotMockMethod.md: -------------------------------------------------------------------------------- 1 | Mockito cannot mock `final` or `static` methods, and cannot tell at runtime that 2 | this is attempted and fail with an error (as mocking `final` classes does). 3 | 4 | `when(mock.finalMethod())` will invoke the real implementation of `finalMethod`. 5 | In some cases, this may wind up accidentally doing what's intended: 6 | 7 | ```java 8 | when(converter.convert(a)).thenReturn(b); 9 | ``` 10 | 11 | `convert` is final, but under the hood, calls `doForward`, so we wind up mocking 12 | that method instead. 13 | -------------------------------------------------------------------------------- /docs/bugpattern/CanonicalDuration.md: -------------------------------------------------------------------------------- 1 | Prefer to express durations using the largest possible unit, e.g. 2 | `Duration.ofDays(1)` instead of `Duration.ofSeconds(86400)`. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/CatchAndPrintStackTrace.md: -------------------------------------------------------------------------------- 1 | Discarding an exception after calling `printStackTrace` should usually be 2 | avoided. 3 | 4 | ```java 5 | try { 6 | // ... 7 | } catch (IOException e) { 8 | logger.log(INFO, "something has gone terribly wrong", e); 9 | } 10 | ``` 11 | 12 | ```java 13 | try { 14 | // ... 15 | } catch (IOException e) { 16 | throw new UncheckedIOException(e); // New in Java 8 17 | } 18 | ``` 19 | 20 | ```java 21 | try { 22 | // ... 23 | } catch (IOException e) { 24 | e.printStackTrace(); 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/bugpattern/ChainingConstructorIgnoresParameter.md: -------------------------------------------------------------------------------- 1 | When a class exposes multiple constructors, they're generally used as a means of 2 | initializing default parameters. If a chaining constructor ignores a parameter, 3 | it's likely the parameter needed to be plumbed to the chained constructor. 4 | 5 | ```java 6 | MissileLauncher(Location target) { 7 | this(target, false); 8 | } 9 | MissileLauncher(boolean askForConfirmation) { 10 | this(TEST_TARGET, false); // should be askForConfirmation 11 | } 12 | MissileLauncher(Location target, boolean askForConfirmation) { 13 | ... 14 | } 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/bugpattern/CheckedExceptionNotThrown.md: -------------------------------------------------------------------------------- 1 | Java allows methods to declare that they throw checked exceptions even when they 2 | don't. This can lead to call sites being forced to explicitly handle or 3 | propagate exceptions which provably can never occur. It may also lead readers of 4 | the code to search for possibly throwing paths where none exist. 5 | 6 | ```java 7 | private static void validateRequest(Request request) throws IOException { 8 | checkArgument(request.hasFoo(), "foo must be specified"); 9 | } 10 | 11 | Response handle(Request request) { 12 | try { 13 | validateRequest(request); 14 | } catch (IOException e) { // Required, but unreachable. 15 | return failedResponse(); 16 | } 17 | // ... 18 | } 19 | ``` 20 | 21 | Including unthrown exceptions can be reasonable where the method is overridable, 22 | as overriding methods will not be able to declare that they throw any exceptions 23 | not included. 24 | -------------------------------------------------------------------------------- /docs/bugpattern/ClassCanBeStatic.md: -------------------------------------------------------------------------------- 1 | An inner class should be static unless it references members of its enclosing 2 | class. An inner class that is made non-static unnecessarily uses more memory and 3 | does not make the intent of the class clear. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/ClassName.md: -------------------------------------------------------------------------------- 1 | While the Java programming language requires that `public` top-level classes are 2 | declared in a source file matching their name (e.g.: `Foo.java` for `public 3 | class Foo {}`, it is possible to declare a non-public top-level class in a file 4 | with a different name (e.g.: `Bar.java` for `class Foo {}`). 5 | 6 | The Google Java Style Guide §2.1 states, "The source file name consists of the 7 | case-sensitive name of the top-level class it contains, plus the .java 8 | extension." 9 | 10 | ## Suppression 11 | 12 | Since `@SuppressWarnings` cannot be applied to package declarations, this 13 | warning can be suppressed by annotating any top-level class in the compilation 14 | unit with `@SuppressWarnings("ClassName")`. 15 | -------------------------------------------------------------------------------- /docs/bugpattern/ClassNamedLikeTypeParameter.md: -------------------------------------------------------------------------------- 1 | In the [Google Style Guide][gsg], type parameters are named in one of two 2 | patterns: 3 | 4 | > * A single capital letter, optionally followed by a single numeral (such as 5 | > E, T, X, T2) 6 | > * A name in the form used for classes..., followed by the capital letter T 7 | > (examples: RequestT, FooBarT). 8 | 9 | If a regular class is named like this, then it might be confusing for users of 10 | your API: 11 | 12 | ```java 13 | class Bar { 14 | ... 15 | public void doSomething(T object) { 16 | // Here, object is the static class T in this file 17 | } 18 | 19 | public void doSomethingElse(T object) { 20 | // Here, object is a generic T 21 | } 22 | ... 23 | public static class T {...} 24 | } 25 | ``` 26 | 27 | Looking at `T`, it's very likely to be confused as a type parameter instead of a 28 | class. 29 | 30 | [gsg]: https://google.github.io/styleguide/javaguide.html#s5.2.8-type-variable-names 31 | -------------------------------------------------------------------------------- /docs/bugpattern/ComparableAndComparator.md: -------------------------------------------------------------------------------- 1 | A `Comparator` is an object that knows how to compare other objects, whereas an 2 | object implementing `Comparable` knows how to compare itself to other objects of 3 | the same type. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/ComparableType.md: -------------------------------------------------------------------------------- 1 | The type argument of `Comparable` should always be the type of the current 2 | class. 3 | 4 | For example, do this: 5 | 6 | ```java 7 | class Foo implements Comparable { 8 | public int compareTo(Foo other) { ... } 9 | } 10 | ``` 11 | 12 | not this: 13 | 14 | ```java 15 | class Foo implements Comparable { 16 | public int compareTo(Bar other) { ... } 17 | } 18 | ``` 19 | 20 | Implementing `Comparable` for a different type breaks the API contract, which 21 | requires `x.compareTo(y) == -y.compareTo(x)` for all `x` and `y`. If `x` and `y` 22 | are different types, this behaviour can't be guaranteed. 23 | -------------------------------------------------------------------------------- /docs/bugpattern/ComparisonContractViolated.md: -------------------------------------------------------------------------------- 1 | The comparison contract states that `sgn(compare(x, y)) == -sgn(compare(y, x))`. 2 | (An immediate corollary is that `compare(x, x) == 0`.) This comparison 3 | implementation either a) cannot return 0, b) cannot return a negative value but 4 | may return a positive value, or c) cannot return a positive value but may return 5 | a negative value. 6 | 7 | The results of violating this contract can include `TreeSet.contains` never 8 | returning true or `Collections.sort` failing with an IllegalArgumentException 9 | arbitrarily. 10 | 11 | In the long term, essentially all Comparators should be rewritten to use the 12 | Java 8 Comparator factory methods, but our automated migration tools will, of 13 | course, only work for correctly implemented Comparators. 14 | -------------------------------------------------------------------------------- /docs/bugpattern/CompatibleWithAnnotationMisuse.md: -------------------------------------------------------------------------------- 1 | The `@CompatibleWith` annotation is used to mark parameters that need extra type 2 | checking on arguments passed to the method. The annotation was not appropriately 3 | placed on a parameter with a valid type argument. See the javadoc for more 4 | details. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/ComputeIfAbsentAmbiguousReference.md: -------------------------------------------------------------------------------- 1 | With ambiguous constructor references used in `java.util.Map#computeIfAbsent` 2 | function parameter, it becomes unclear what the code intends to do. 3 | 4 | ```java 5 | map.computeIfAbsent(someLong, AtomicLong::new).incrementAndGet() 6 | ``` 7 | 8 | Code of this form can seemingly look like it's trying to make a counter, 9 | creating the key if absent. Unfortunately the code is surprising, because it 10 | will call the wrong `AtomicLong` constructor. Instead, it will create the 11 | counter initialized with the key value, which is probably not desired. 12 | -------------------------------------------------------------------------------- /docs/bugpattern/ConstantField.md: -------------------------------------------------------------------------------- 1 | The [Google Java Style Guide §5.2.4][style] requires constant names to use 2 | `CONSTANT_CASE`. 3 | 4 | [style]: https://google.github.io/styleguide/javaguide.html#s5.2.4-constant-names 5 | 6 | When naming a field with `CONSTANT_CASE`, make sure the field is `static`, 7 | `final`, and of immutable type. If the field doesn't meet those criteria, use 8 | `lowerCamelCase` instead. 9 | 10 | The check recognizes all primitive, `String`, and `enum` fields as deeply 11 | immutable. It is possible to create mutable enums, but doing so is 12 | strongly discouraged. 13 | -------------------------------------------------------------------------------- /docs/bugpattern/ConstantOverflow.md: -------------------------------------------------------------------------------- 1 | Compile-time constant expressions that overflow are a potential source of bugs. 2 | 3 | Literals without an explicit `L` suffix have type `int`, so the following 4 | multiplication expression is evaluated as an integer before being widened to 5 | `long`. The value is greater than `Integer.MAX_VALUE`, so it wraps around to 6 | `-1857093632`. 7 | 8 | ```java 9 | static final long NANOS_PER_DAY = 24 * 60 * 60 * 1000 * 1000 * 1000; 10 | ``` 11 | 12 | The intent was probably for the multiplication expression to be evaluated as a 13 | `long` instead of an `int`. 14 | 15 | ```java 16 | static final long NANOS_PER_DAY = 24L * 60 * 60 * 1000 * 1000 * 1000; 17 | ``` 18 | 19 | If you find yourself doing this kind of time-based math, consider using an API 20 | that provides a safer, more readable and strongly-typed solution like the 21 | [`java.time.Duration`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/Duration.html) 22 | API. 23 | -------------------------------------------------------------------------------- /docs/bugpattern/ConstantPatternCompile.md: -------------------------------------------------------------------------------- 1 | Method bodies should generally not call 2 | `java.util.regex.Pattern#compile(String)` with constant arguments. Instead, 3 | define a constant to store that Pattern. This can avoid recompilation of the 4 | regex every time the method is invoked. 5 | 6 | That is, prefer this: 7 | 8 | ```java 9 | private static final Pattern REGEX_PATTERN = Pattern.compile("a+"); 10 | 11 | public static boolean doSomething(String input) { 12 | Matcher matcher = REGEX_PATTERN.matcher(input); 13 | if (matcher.matches()) { 14 | ... 15 | } 16 | } 17 | ``` 18 | 19 | to this: 20 | 21 | ```java 22 | public static boolean doSomething(String input) { 23 | Matcher matcher = Pattern.compile("a+").matcher(input); 24 | if (matcher.matches()) { 25 | ... 26 | } 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/bugpattern/DaggerProvidesNull.md: -------------------------------------------------------------------------------- 1 | Dagger `@Provides` methods may not return null unless annotated with 2 | `@Nullable`. Such a method will cause a `NullPointerException` at runtime if the 3 | `return null` path is ever taken. 4 | 5 | If you believe the `return null` path can never be taken, please throw a 6 | `RuntimeException` instead. Otherwise, please annotate the method with 7 | `@Nullable`. 8 | -------------------------------------------------------------------------------- /docs/bugpattern/DeadException.md: -------------------------------------------------------------------------------- 1 | The exception is created with `new`, but is not thrown, and the reference is 2 | lost. 3 | 4 | Creating an exception without using it is unlikely to be correct, so we assume 5 | that you wanted to throw the exception. 6 | -------------------------------------------------------------------------------- /docs/bugpattern/DeadThread.md: -------------------------------------------------------------------------------- 1 | The Thread is created with `new`, but is never started and is not otherwise 2 | captured. 3 | 4 | Threads must be started with `start()` to actually execute. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/DefaultPackage.md: -------------------------------------------------------------------------------- 1 | Declaring classes in the default package is discouraged. 2 | -------------------------------------------------------------------------------- /docs/bugpattern/DepAnn.md: -------------------------------------------------------------------------------- 1 | A declaration has the `@deprecated` Javadoc tag but no `@Deprecated` annotation. 2 | Please add an `@Deprecated` annotation to this declaration in addition to the 3 | `@deprecated` tag in the Javadoc. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/DeprecatedVariable.md: -------------------------------------------------------------------------------- 1 | `@Deprecated` annotations should not be applied to local variables and 2 | parameters, since they have no effect there. 3 | 4 | The 5 | [javadoc for `@Deprecated`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Deprecated.html) 6 | says 7 | 8 | > Use of the `@Deprecated` annotation on a local variable declaration or on a 9 | > parameter declaration or a package declaration has no effect on the warnings 10 | > issued by a compiler. 11 | -------------------------------------------------------------------------------- /docs/bugpattern/DistinctVarargsChecker.md: -------------------------------------------------------------------------------- 1 | Various methods which take variable-length arguments throw runtime exceptions 2 | like `IllegalArgumentException` when the arguments are not distinct. 3 | 4 | This checker warns on using non-distinct parameters in various varargs methods 5 | when the usage is either redundant or will result in a runtime exception. 6 | 7 | Bad: 8 | 9 | ```java 10 | ImmutableSet.of(first, second, second, third); 11 | ``` 12 | 13 | Good: 14 | 15 | ```java 16 | ImmutableSet.of(first, second, third); 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/bugpattern/DoNotClaimAnnotations.md: -------------------------------------------------------------------------------- 1 | Do not 'claim' annotations in annotation processors; [`Processor#process`] 2 | should unconditionally `return false`. Claiming annotations prevents other 3 | processors from seeing the annotations, which there's usually no reason to do. 4 | It's also fragile, since it relies on the order the processors run in, and 5 | there's no robust way in most build systems to ensure a particular processor 6 | sees the annotations first. 7 | 8 | [`Processor#process`]: https://docs.oracle.com/en/java/javase/11/docs/api/java.compiler/javax/annotation/processing/Processor.html#process(java.util.Set,javax.annotation.processing.RoundEnvironment) 9 | -------------------------------------------------------------------------------- /docs/bugpattern/DuplicateBranches.md: -------------------------------------------------------------------------------- 1 | Branching constructs (`if` statements, `conditional` expressions) should contain 2 | difference code in the two branches. Repeating identical code in both branches 3 | is usually a bug. 4 | 5 | For example: 6 | 7 | ```java 8 | condition ? same : same 9 | ``` 10 | 11 | ```java 12 | if (condition) { 13 | same(); 14 | } else { 15 | same(); 16 | } 17 | ``` 18 | 19 | this usually indicates a typo where one of the branches was supposed to contain 20 | different logic: 21 | 22 | ```java 23 | condition ? something : somethingElse 24 | ``` 25 | 26 | ```java 27 | if (condition) { 28 | doSomething(); 29 | } else { 30 | doSomethingElse(); 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/bugpattern/DuplicateMapKeys.md: -------------------------------------------------------------------------------- 1 | JDK 9 has 2 | [`Map#ofEntries`](https://docs.oracle.com/javase/9/docs/api/java/util/Map.html#ofEntries-java.util.Map.Entry...-) 3 | factory which throws runtime error when provided multiple entries with the same 4 | key. 5 | 6 | For eg, the following code is erroneously adding two entries with `Foo` as key. 7 | 8 | ``` 9 | Map map = Map.ofEntries( 10 | Map.entry("Foo", "Bar"), 11 | Map.entry("Ping", "Pong"), 12 | Map.entry("Kit", "Kat"), 13 | Map.entry("Foo", "Bar")); 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/bugpattern/EmptyIf.md: -------------------------------------------------------------------------------- 1 | An if statement contains an empty statement as the then clause. A semicolon may 2 | have been inserted by accident. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/EmptySetMultibindingContributions.md: -------------------------------------------------------------------------------- 1 | When using [Dagger Multibinding][dmb], you can use methods like the below to 2 | make sure that there's a (potentially empty) Set binding for your type: 3 | 4 | ```java 5 | @Provides @ElementsIntoSet Set provideEmptySetOfMyType() { 6 | return new HashSet<>(); 7 | } 8 | ``` 9 | 10 | However, there's a slightly easier way to express this: 11 | 12 | ```java 13 | @Multibinds abstract Set provideEmptySetOfMyType(); 14 | ``` 15 | 16 | [dmb]: https://dagger.dev/multibindings.html 17 | -------------------------------------------------------------------------------- /docs/bugpattern/EmptyTopLevelDeclaration.md: -------------------------------------------------------------------------------- 1 | A semi-colon at the top level of a Java file is treated as an empty type 2 | declaration in the grammar, but it's confusing and unnecessary. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/EqualsHashCode.md: -------------------------------------------------------------------------------- 1 | The contract for `Object.hashCode` states that if two objects are equal, then 2 | calling the `hashCode()` method on each of the two objects must produce the same 3 | result. Implementing `equals()` but not `hashCode()` causes broken behaviour 4 | when trying to store the object in a collection. 5 | 6 | See [Effective Java 3rd Edition §11][ej3e-11] for more information and a 7 | discussion of how to correctly implement `hashCode()`. 8 | 9 | [ej3e-11]: https://books.google.com/books?id=BIpDDwAAQBAJ 10 | -------------------------------------------------------------------------------- /docs/bugpattern/EqualsNaN.md: -------------------------------------------------------------------------------- 1 | As per JLS 15.21.1, == NaN comparisons always return false, even NaN == NaN. 2 | Instead, use the isNaN methods to check for NaN. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/EqualsNull.md: -------------------------------------------------------------------------------- 1 | The contract of `Object.equals()` states that for any non-null reference value 2 | `x`, `x.equals(null)` should return `false`. Thus code such as 3 | 4 | ``` 5 | if (x.equals(null)) { 6 | ... 7 | } 8 | ``` 9 | 10 | either returns `false`, or throws a `NullPointerException` if `x` is `null`. The 11 | nested block may never execute. 12 | 13 | This check replaces `x.equals(null)` with `x == null`, and `!x.equals(null)` 14 | with `x != null`. If the author intended for `x.equals(null)` to return `true`, 15 | consider this as fragile code as it breaks the contract of `Object.equals()`. 16 | 17 | See [Effective Java 3rd Edition §10: Objey the general contract when overriding 18 | equals][ej3e-10] for more details. 19 | 20 | [ej3e-10]: https://books.google.com/books?id=BIpDDwAAQBAJ 21 | -------------------------------------------------------------------------------- /docs/bugpattern/EqualsReference.md: -------------------------------------------------------------------------------- 1 | .equals() to the same object will result in infinite recursion 2 | -------------------------------------------------------------------------------- /docs/bugpattern/EqualsUnsafeCast.md: -------------------------------------------------------------------------------- 1 | Implementations of `#equals` should return `false` for different types, not 2 | throw. 3 | 4 | ```java 5 | class Data { 6 | private int a; 7 | 8 | @Override 9 | public boolean equals(Object other) { 10 | Data that = (Data) other; // BAD: This may throw ClassCastException. 11 | return a == that.a; 12 | } 13 | } 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/bugpattern/EqualsUsingHashCode.md: -------------------------------------------------------------------------------- 1 | Don't implement `#equals` using just a `hashCode` comparison: 2 | 3 | ```java 4 | class MyClass { 5 | private final int a; 6 | private final int b; 7 | private final String c; 8 | 9 | ... 10 | 11 | @Override 12 | public boolean equals(@Nullable Object o) { 13 | return o.hashCode() == hashCode(); 14 | } 15 | 16 | @Override 17 | public int hashCode() { 18 | return Objects.hashCode(a, b, c); 19 | } 20 | ``` 21 | 22 | The number of `Object`s with randomly distributed `hashCode` required to give a 23 | 50% chance of collision (and therefore, with this pattern, erroneously correct 24 | equality) is only ~77k. 25 | -------------------------------------------------------------------------------- /docs/bugpattern/EqualsWrongThing.md: -------------------------------------------------------------------------------- 1 | An equals method compares non-corresponding fields from itself and the other 2 | instance: 3 | 4 | ```java 5 | class Frobnicator { 6 | private int a; 7 | private int b; 8 | 9 | @Override 10 | public boolean equals(@Nullable Object other) { 11 | if (!(other instanceof Frobnicator)) { 12 | return false; 13 | } 14 | Frobnicator that = (Frobnicator) other; 15 | return a == that.a && b == that.a; // BUG: should be b == that.b 16 | } 17 | } 18 | ``` 19 | -------------------------------------------------------------------------------- /docs/bugpattern/ExtendsObject.md: -------------------------------------------------------------------------------- 1 | `T extends Object` is redundant; both `` and `` compile to 2 | identical class files.— unless you are using the Checker Framework. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/FallThrough.md: -------------------------------------------------------------------------------- 1 | The [Google Java Style Guide §4.8.4.2][style] requires that within a switch 2 | block, each statement group either terminates abruptly (with a `break`, 3 | `continue`, `return` or `throw` statement), or is marked with a comment to 4 | indicate that execution will or might continue into the next statement group. 5 | This special comment is not required in the last statement group of the switch 6 | block. 7 | 8 | Example: 9 | 10 | ```java 11 | switch (input) { 12 | case 1: 13 | case 2: 14 | prepareOneOrTwo(); 15 | // fall through 16 | case 3: 17 | handleOneTwoOrThree(); 18 | break; 19 | default: 20 | handleLargeNumber(input); 21 | } 22 | ``` 23 | 24 | [style]: https://google.github.io/styleguide/javaguide.html#s4.8.4.2-switch-fall-through 25 | -------------------------------------------------------------------------------- /docs/bugpattern/FieldCanBeLocal.md: -------------------------------------------------------------------------------- 1 | A field which is always assigned before being used from every method that reads 2 | it may be better expressed as a local variable. Using a field in such cases 3 | gives the impression of mutable state in the class where it isn't necessary. 4 | 5 | ```java 6 | class Frobnicator { 7 | private int sum = 0; 8 | 9 | int sum(int a, int b) { 10 | sum = a + b; 11 | return sum; 12 | } 13 | 14 | int sum(int a, int b, int c) { 15 | sum = a + b + c; 16 | return sum; 17 | } 18 | ``` 19 | 20 | ```java 21 | class Frobnicator { 22 | int sum(int a, int b) { 23 | int sum = a + b; 24 | return sum; 25 | } 26 | 27 | int sum(int a, int b, int c) { 28 | int sum = a + b + c; 29 | return sum; 30 | } 31 | ``` 32 | 33 | ## Suppression 34 | 35 | This check is suppressed by `@SuppressWarnings("FieldCanBeLocal")`. 36 | 37 | It will also be suppressed if the field is annotated with `@Keep` or an 38 | annotation annotated with `@Keep`. 39 | -------------------------------------------------------------------------------- /docs/bugpattern/FieldCanBeStatic.md: -------------------------------------------------------------------------------- 1 | `final` fields initialized with a literal can elide a per-instance reference by 2 | adding the `static` keyword. Since the field is `final` it is unmodifiable and 3 | since its initializer is a literal the value is immutable and thus sharing a 4 | per-class field is safe. This also allows a simpler constant load bytecode 5 | instead of a field lookup. 6 | 7 | That is, prefer this: 8 | 9 | ```java 10 | static final String string = "string"; 11 | static final int number = 42; 12 | ``` 13 | 14 | Not this: 15 | 16 | ```java 17 | final String string = "string"; 18 | final int number = 42; 19 | ``` 20 | -------------------------------------------------------------------------------- /docs/bugpattern/FieldMissingNullable.md: -------------------------------------------------------------------------------- 1 | 2 | Fields that may be `null` should be annotated with `@Nullable`. For example, do 3 | this: 4 | 5 | ```java 6 | public class Foo { 7 | @Nullable private String message = "hello"; 8 | public void reset() { 9 | message = null; 10 | } 11 | } 12 | ``` 13 | 14 | Not this: 15 | 16 | ```java 17 | public class Foo { 18 | private String message = "hello"; 19 | public void reset() { 20 | message = null; 21 | } 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/bugpattern/Finalize.md: -------------------------------------------------------------------------------- 1 | Do not override `Object.finalize`. 2 | 3 | Starting in JDK 18, the method is deprecated for removal, see 4 | [JEP 421: Deprecate Finalization for Removal](https://openjdk.org/jeps/421). 5 | 6 | The [Google Java Style Guide §6.4][style] states: 7 | 8 | > It is extremely rare to override `Object.finalize`. 9 | > 10 | > Tip: Don't do it. If you absolutely must, first read and understand 11 | > [Effective Java Item 8][ej3e-8], "Avoid finalizers and cleaners" very 12 | > carefully, and then don't do it. 13 | 14 | [ej3e-8]: https://books.google.com/books?id=BIpDDwAAQBAJ 15 | [style]: https://google.github.io/styleguide/javaguide.html#s6.4-finalizers 16 | 17 | ## Suppression 18 | 19 | Suppress false positives by adding the suppression annotation to the enclosing 20 | element: 21 | 22 | ```java 23 | @SuppressWarnings("Finalize") // TODO(user): remove overrides of finalize 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/bugpattern/FloatCast.md: -------------------------------------------------------------------------------- 1 | Casts have higher precedence than binary expressions, so `(int) 0.5f * 100` is 2 | equivalent to `((int) 0.5f) * 100` = `0 * 100` = `0`, not `(int) (0.5f * 100)` = 3 | `50`. 4 | 5 | To avoid this common source of error, add explicit parentheses to make the 6 | precedence explicit. For example, instead of this: 7 | 8 | ```java 9 | long SIZE_IN_GB = (long) 1.5 * 1024 * 1024 * 1024; // this is 1GB, not 1.5GB! 10 | 11 | // this is 0, not a long in the range [0, 1000000000] 12 | long rand = (long) new Random().nextDouble() * 1000000000 13 | ``` 14 | 15 | Prefer: 16 | 17 | ```java 18 | long SIZE_IN_GB = (long) (1.5 * 1024 * 1024 * 1024); 19 | 20 | long rand = (long) (new Random().nextDouble() * 1000000000); 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/bugpattern/FloatingPointLiteralPrecision.md: -------------------------------------------------------------------------------- 1 | `double` and `float` literals that can't be precisely represented should be 2 | avoided. 3 | 4 | Example: 5 | 6 | ```java 7 | double d = 1.9999999999999999999999999999999; 8 | System.err.println(d); // prints 2.0 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/bugpattern/FloggerArgumentToString.md: -------------------------------------------------------------------------------- 1 | Prefer to let Flogger transform your arguments to strings, instead of calling 2 | `toString()` explicitly. 3 | 4 | For example, prefer the following: 5 | 6 | ```java 7 | logger.atInfo().log("hello '%s'", world); 8 | ``` 9 | 10 | instead of this, which eagerly calls `world.toString()` even if `INFO` level 11 | logging is disabled. 12 | 13 | ```java 14 | logger.atInfo().log("hello '%s'", world.toString()); 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/bugpattern/FloggerStringConcatenation.md: -------------------------------------------------------------------------------- 1 | Prefer string formatting to concatenating format arguments together, to avoid 2 | work at the log site. 3 | 4 | That is, prefer this: 5 | 6 | ```java 7 | logger.atInfo().log("processing: %s", request); 8 | ``` 9 | 10 | to this, which calls `request.toString()` even if `INFO` logging is disabled: 11 | 12 | ```java 13 | logger.atInfo().log("processing: " + request); 14 | ``` 15 | 16 | More information: https://google.github.io/flogger/formatting 17 | -------------------------------------------------------------------------------- /docs/bugpattern/ForEachIterable.md: -------------------------------------------------------------------------------- 1 | Prefer enhanced for loops instead of explicitly using an iterator where 2 | possible. 3 | 4 | That is, prefer this: 5 | 6 | ```java 7 | for (T element : list) { 8 | doSomething(element); 9 | } 10 | ``` 11 | 12 | to this: 13 | 14 | ```java 15 | for (Iterator iterator = list.iterator(); iterator.hasNext(); ) { 16 | doSomething(iterator.next()); 17 | } 18 | ``` 19 | -------------------------------------------------------------------------------- /docs/bugpattern/ForOverride.md: -------------------------------------------------------------------------------- 1 | A method that overrides a @ForOverride method should not be invoked directly. 2 | Instead, it should be invoked only from the class in which it was declared. For 3 | example, if overriding Converter.doForward, you should invoke it through 4 | Converter.convert. For testing, factor out the code you want to run to a 5 | separate method. 6 | -------------------------------------------------------------------------------- /docs/bugpattern/FutureTransformAsync.md: -------------------------------------------------------------------------------- 1 | The usage of `transformAsync`, `callAsync` and `submitAsync` is not necessary 2 | when all the return values of the transformation function are immediate futures. 3 | In this case, the usage of `transform`, `call` and `submit` is preferred. 4 | 5 | Note that `transform` cannot be used if the body of the transformation function 6 | throws checked exceptions. 7 | -------------------------------------------------------------------------------- /docs/bugpattern/FuturesGetCheckedIllegalExceptionType.md: -------------------------------------------------------------------------------- 1 | The passed exception type must not be a RuntimeException, and it must expose a 2 | public constructor whose only parameters are of type String or Throwable. 3 | getChecked will reject any other type with an IllegalArgumentException. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/FuzzyEqualsShouldNotBeUsedInEqualsMethod.md: -------------------------------------------------------------------------------- 1 | From documentation: DoubleMath.fuzzyEquals is not transitive, so it is not 2 | suitable for use in Object#equals implementations. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/GetClassOnAnnotation.md: -------------------------------------------------------------------------------- 1 | Instances of an annotation interface generally return a random proxy class when 2 | `getClass()` is called on them; to get the actual annotation type use 3 | `annotationType()`. 4 | 5 | In the following example, calling `getClass()` on the annotation instance 6 | returns a proxy class like `com.sun.proxy.$Proxy1`, while `annotationType()` 7 | returns `Deprecated`. 8 | 9 | ```java 10 | @Deprecated 11 | public class Test { 12 | static void printAnnotationClass(Annotation annotation) { 13 | System.err.println(annotation.getClass()); 14 | System.err.println(annotation.annotationType()); 15 | } 16 | 17 | public static void main(String[] args) { 18 | printAnnotationClass(Test.class.getAnnotation(Deprecated.class)); 19 | } 20 | } 21 | ``` 22 | 23 | Prints: 24 | 25 | ``` 26 | class com.sun.proxy.$Proxy1 27 | interface java.lang.Deprecated 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/bugpattern/GetClassOnClass.md: -------------------------------------------------------------------------------- 1 | Calling `getClass()` on an object of type Class returns the Class object for 2 | java.lang.Class. Usually this is a mistake, and people intend to operate on the 3 | object itself (for example, to print an error message). If you really did intend 4 | to operate on the Class object for java.lang.Class, please use `Class.class` 5 | instead for clarity. 6 | -------------------------------------------------------------------------------- /docs/bugpattern/GuiceAssistedInjectScoping.md: -------------------------------------------------------------------------------- 1 | Classes that AssistedInject factories create may not be annotated with scope 2 | annotations, such as @Singleton. This will cause a Guice error at runtime. 3 | 4 | See 5 | [this bug report](https://code.google.com/p/google-guice/issues/detail?id=742) 6 | for details. 7 | -------------------------------------------------------------------------------- /docs/bugpattern/GuiceInjectOnFinalField.md: -------------------------------------------------------------------------------- 1 | From the [Guice wiki][wiki]: 2 | 3 | > Injecting `final` fields is not recommended because the injected value may not 4 | > be visible to other threads. 5 | 6 | [wiki]: https://github.com/google/guice/wiki/InjectionPoints#how-guice-injects 7 | -------------------------------------------------------------------------------- /docs/bugpattern/HashtableContains.md: -------------------------------------------------------------------------------- 1 | `Hashtable.contains(Object)` and `ConcurrentHashMap.contains(Object)` are legacy 2 | methods for testing if the given object is a value in the hash table. They are 3 | often mistaken for `containsKey`, which checks whether the given object is a 4 | *key* in the hash table. 5 | 6 | If you intended to check whether the given object is a key in the hash table, 7 | use `containsKey` instead. If you really intended to check whether the given 8 | object is a value in the hash table, use `containsValue` for clarity. 9 | -------------------------------------------------------------------------------- /docs/bugpattern/ICCProfileGetInstance.md: -------------------------------------------------------------------------------- 1 | `ICC_Profile.getInstance(String)` searches the entire classpath, which is often 2 | unnecessary and can result in slow performance for applications with long 3 | classpaths. Prefer `getInstance(byte[])` or `getInstance(InputStream)` instead. 4 | 5 | See also https://bugs.openjdk.org/browse/JDK-8191622. 6 | -------------------------------------------------------------------------------- /docs/bugpattern/IdentityBinaryExpression.md: -------------------------------------------------------------------------------- 1 | Using the same expressions as both arguments to the following binary expressions 2 | is usually a mistake: 3 | 4 | * `a && a`, `a || a`, `a & a`, or `a | a` is equivalent to `a` 5 | * `a <= a`, `a >= a`, or `a == a` is always `true` 6 | * `a < a`, `a > a`, `a != a`, or `a ^ a` is always `false` 7 | * `a / a` is always `1` 8 | * `a % a` or `a - a` is always `0` 9 | 10 | If the expression has side-effects, consider refactoring one of the expressions 11 | with side effects into a local. For example, prefer this: 12 | 13 | ```java 14 | // check twice, just to be sure 15 | boolean isTrue = foo.isTrue(); 16 | if (isTrue && foo.isTrue()) { 17 | // ... 18 | } 19 | ``` 20 | 21 | to this: 22 | 23 | ```java 24 | if (foo.isTrue() && foo.isTrue()) { 25 | // ... 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/bugpattern/IncompatibleModifiers.md: -------------------------------------------------------------------------------- 1 | The @IncompatibleModifiers annotation declares that the target annotation is 2 | incompatible with a set of provided modifiers. This check ensures that all 3 | annotations respect their @IncompatibleModifiers specifications. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/InconsistentCapitalization.md: -------------------------------------------------------------------------------- 1 | It is confusing to have two or more variables under the same scope that differ 2 | only in capitalization. Make sure that both of these follow the casing guide 3 | ([Google Java Style Guide §5.3][styleCamelCase]) and to be consistent if more 4 | than one option is possible. 5 | 6 | This checker will only find parameters that differ in capitalization with fields 7 | that can be accessed from the parameter's scope. 8 | 9 | 10 | [styleCamelCase]: https://google.github.io/styleguide/javaguide.html#s5.3-camel-case 11 | -------------------------------------------------------------------------------- /docs/bugpattern/InconsistentHashCode.md: -------------------------------------------------------------------------------- 1 | Implementations of `Object#hashCode` should not incorporate fields which the 2 | implementation of `Object#equals` does not. This violates the contract of 3 | `hashCode`: specifically, equal objects must have equal hashCodes. 4 | 5 | ```java 6 | class Foo { 7 | private final int a; 8 | private final int b; 9 | 10 | Foo(int a, int b) { 11 | this.a = a; 12 | this.b = b; 13 | } 14 | 15 | @Override 16 | public boolean equals(@Nullable Object o) { 17 | return o instanceof Foo && ((Foo) o).a == a; 18 | } 19 | 20 | @Override 21 | public int hashCode() { 22 | return a + 31 * b; 23 | } 24 | } 25 | 26 | Foo first = new Foo(10, 20); 27 | Foo second = new Foo(10, 40); 28 | 29 | first.equals(second) // true 30 | first.hashCode() == second.hashCode() // false 31 | ``` 32 | 33 | The fix for this class is either to include a comparison of `b` in the `#equals` 34 | method, or remove `b` from `#hashCode`. The former is more likely to be correct. 35 | -------------------------------------------------------------------------------- /docs/bugpattern/IncorrectMainMethod.md: -------------------------------------------------------------------------------- 1 | A `main` method must be `public`, `static`, and return `void` (see 2 | [JLS §12.1.4]). 3 | 4 | For example, the following method is confusing, because it is an overload of a 5 | valid `main` method (it has the same name and signature), but is not a valid 6 | `main` method: 7 | 8 | ```java 9 | class Test { 10 | static void main(String[] args) { 11 | System.err.println("hello world"); 12 | } 13 | } 14 | ``` 15 | 16 | ``` 17 | $ java T.java 18 | error: 'main' method is not declared 'public static' 19 | ``` 20 | 21 | [JLS §12.1.4]: https://docs.oracle.com/javase/specs/jls/se11/html/jls-12.html#jls-12.1.4 22 | 23 | TIP: If you're declaring a method that isn't intended to be used as the main 24 | method of your program, prefer to use a name other than `main`. It's confusing 25 | to humans and static analysis to see methods like `private int main(String[] 26 | args)`. 27 | -------------------------------------------------------------------------------- /docs/bugpattern/InfiniteRecursion.md: -------------------------------------------------------------------------------- 1 | A method that always calls itself will cause a StackOverflowError. 2 | 3 | ```java 4 | int oops() { 5 | return oops(); 6 | } 7 | ``` 8 | 9 | ``` 10 | Exception in thread "main" java.lang.StackOverflowError 11 | at Test.oops(X.java:3) 12 | at Test.oops(X.java:3) 13 | ... 14 | ``` 15 | 16 | The fix may be to call another method with the same name: 17 | 18 | ```java 19 | void process(String name, int id) { 20 | process(name, id); // error 21 | process(name, id, /*verbose=*/ true); // ok 22 | } 23 | 24 | void process(String name, int id, boolean verbose) { 25 | // ... 26 | } 27 | ``` 28 | 29 | or to call the method on a different instance: 30 | 31 | ```java 32 | class Delegate implements Processor { 33 | Processor delegate; 34 | 35 | void process(String name, int id) { 36 | process(name, id); // error 37 | delegate.process(name, id); // ok 38 | } 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/bugpattern/InjectInvalidTargetingOnScopingAnnotation.md: -------------------------------------------------------------------------------- 1 | `@Scope` annotations should be applicable to TYPE (annotating classes that 2 | should be scoped) and to METHOD (annotating `@Provides` methods to apply scoping 3 | to the returned object. 4 | 5 | If an annotation's use is restricted by `@Target` and it doesn't include those 6 | two element types, the annotation can't be used where it should be able to be 7 | used. 8 | -------------------------------------------------------------------------------- /docs/bugpattern/InjectMoreThanOneQualifier.md: -------------------------------------------------------------------------------- 1 | An element can be qualified by at most one qualifier. 2 | -------------------------------------------------------------------------------- /docs/bugpattern/InjectMoreThanOneScopeAnnotationOnClass.md: -------------------------------------------------------------------------------- 1 | Annotating a class with more than one scope annotation is invalid according to 2 | the JSR-330 specification. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/InjectOnConstructorOfAbstractClass.md: -------------------------------------------------------------------------------- 1 | When dependency injection frameworks call constructors, they can only do so on 2 | constructors of concrete classes, which can delegate to superclass constructors. 3 | In the case of abstract classes, their constructors are only called by their 4 | concrete subclasses, not directly by injection frameworks, so the `@Inject` 5 | annotation has no effect. 6 | -------------------------------------------------------------------------------- /docs/bugpattern/InjectScopeAnnotationOnInterfaceOrAbstractClass.md: -------------------------------------------------------------------------------- 1 | Scoping annotations are not inherited. They will have no effect if added to an 2 | abstract type. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/InjectedConstructorAnnotations.md: -------------------------------------------------------------------------------- 1 | The constructor is annotated with @Inject(optional=true), or it is annotated 2 | with @Inject and a binding annotation. This will cause a Guice runtime error. 3 | 4 | See [https://code.google.com/p/google-guice/wiki/InjectionPoints] for details. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/InlineTrivialConstant.md: -------------------------------------------------------------------------------- 1 | Constants should be given names that emphasize the semantic meaning of the 2 | value. If the name of the constant doesn't convey any information that isn't 3 | clear from the value, consider inlining it. 4 | 5 | For example, prefer this: 6 | 7 | ```java 8 | System.err.println(1); 9 | System.err.println(""); 10 | ``` 11 | 12 | to this: 13 | 14 | ```java 15 | private static final int ONE = 1; 16 | private static final String EMPTY_STRING = ""; 17 | ... 18 | System.err.println(ONE); 19 | System.err.println(EMPTY_STRING); 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/bugpattern/InputStreamSlowMultibyteRead.md: -------------------------------------------------------------------------------- 1 | `java.io.InputStream` defines a single abstract method: `int read()`, which 2 | subclasses implement to return bytes from the logical input stream. 3 | 4 | However, in most circumstances, readers from `InputStreams` use higher-level 5 | methods like `read(byte[], int offset, int length)` to read multiple bytes at a 6 | time into a buffer. The default implementation of this method is to repeatedly 7 | call `read()`. However, most InputStream implementations could do much better if 8 | they can read multiple bytes at once (at the very least, avoiding unneeded 9 | `byte` -> `int` -> `byte` casts that are needed when implementing the read() 10 | method over an underlying `byte` source). 11 | 12 | The class in question implements `int read()` without also overriding `int 13 | read(byte[], int, int)` and will thus be subject to the costs associated with 14 | the default behavior of the multibyte read method. 15 | -------------------------------------------------------------------------------- /docs/bugpattern/IntFloatConversion.md: -------------------------------------------------------------------------------- 1 | Implicit conversions from `int` to `float` may lose precision when when calling 2 | methods with overloads that accept both`float` and `double`. 3 | 4 | For example, `Math.scalb` has overloads 5 | [`Math.scalb(float, int)`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Math.html#scalb\(float,int\)) 6 | and 7 | [`Math.scalb(double, int)`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Math.html#scalb\(double,int\)). 8 | 9 | When passing an `int` as the first argument, `Math.scalb(float, int)` will be 10 | selected. If the result of `Math.scalb(float, int)` is then used as a `double`, 11 | this may result in a loss of precision. 12 | 13 | To avoid this, an explicit cast to `double` can be used to call the 14 | `Match.scalb(double, int)` overload: 15 | 16 | ```java 17 | int x = ... 18 | int y = ... 19 | double f = Math.scalb((double) x, 2); 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/bugpattern/IntLongMath.md: -------------------------------------------------------------------------------- 1 | Performing an arithmetic expression on arguments of type int and then assigning 2 | the result to a long is error-prone. The result is widened to a long as the 3 | final step, and the intermediate results may overflow. 4 | 5 | For example, the following expression exceeds `Integer.MAX_VALUE` and overflows 6 | to `-1857093632`: 7 | 8 | ```java 9 | long nanosPerDay = 24 * 60 * 60 * 1000 * 1000 * 1000; 10 | ``` 11 | 12 | The corrected code (which has a value of `86400000000000`) is: 13 | 14 | ```java 15 | long nanosPerDay = 24L * 60 * 60 * 1000 * 1000 * 1000; 16 | ``` 17 | -------------------------------------------------------------------------------- /docs/bugpattern/InterfaceWithOnlyStatics.md: -------------------------------------------------------------------------------- 1 | Interfaces should be used to define types. Using an interface as a collection of 2 | static methods and fields violates that, and can lead to confusing type 3 | hierarchies if the interface is then implemented to allow easy access to the 4 | constants. 5 | 6 | Prefer using a `public final` class instead to prohibit subclassing. 7 | 8 | ```java 9 | public interface Constants { 10 | final float PI = 3.14159f; 11 | } 12 | ``` 13 | 14 | ```java 15 | public final class Constants { 16 | public static final float PI = 3.14159f; 17 | 18 | private Constants() {} 19 | } 20 | ``` 21 | 22 | See 23 | [Effective Java 3rd Edition §22: Use interfaces only to define types][ej3e-22] 24 | for more details. 25 | 26 | [ej3e-22]: https://books.google.com/books?id=BIpDDwAAQBAJ 27 | -------------------------------------------------------------------------------- /docs/bugpattern/Interruption.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/error-prone/962f83aac3193dca53129e8e3b34740176bc0bde/docs/bugpattern/Interruption.md -------------------------------------------------------------------------------- /docs/bugpattern/InvalidLink.md: -------------------------------------------------------------------------------- 1 | This error is triggered by a Javadoc `@link` tag that either is syntactically 2 | invalid or can't be resolved. See [javadoc documentation][javadoc] for an 3 | explanation of how to correctly format the contents of this tag. 4 | 5 | [javadoc]: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javadoc.html#JSSOR654 6 | 7 | ### Linking to generic types 8 | 9 | Use the erased type of method parameters in `@link` tags. For example, write 10 | `{@link #foo(List)}` instead of `{@link #foo(List)}`. Javadoc does yet not 11 | support generics in `@link` tags, due to a bug: 12 | [JDK-5096551](https://bugs.openjdk.java.net/browse/JDK-5096551). 13 | -------------------------------------------------------------------------------- /docs/bugpattern/InvalidPatternSyntax.md: -------------------------------------------------------------------------------- 1 | This error is triggered by calls to regex-accepting methods with invalid string 2 | literals. These calls would cause a PatternSyntaxException at runtime. 3 | 4 | We deliberately do not check `java.util.regex.Pattern#compile` as many of its 5 | users are deliberately testing the regex compiler or using a vacuously true 6 | regex. 7 | 8 | `"."` is also discouraged, as it is a valid regex but is easy to mistake for 9 | `"\\."`. Instead of e.g. `str.replaceAll(".", "x")`, prefer `Strings.repeat("x", 10 | str.length())` or `CharMatcher.ANY.replaceFrom(str, "x")`. 11 | -------------------------------------------------------------------------------- /docs/bugpattern/InvalidTimeZoneID.md: -------------------------------------------------------------------------------- 1 | TimeZone.getTimeZone(String) silently returns GMT when an invalid time zone 2 | identifier is passed in. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/IsLoggableTagLength.md: -------------------------------------------------------------------------------- 1 | `Log.isLoggable(tag, level)` throws an `IllegalArgumentException` if its tag 2 | argument is more than 23 characters long. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/IterableAndIterator.md: -------------------------------------------------------------------------------- 1 | An `Iterator` is a *state-ful* instance that enables you to check whether it has 2 | more elements (via `hasNext()`) and moves to the next one if any (via `next()`), 3 | while an `Iterable` is a representation of literally iterable elements. An 4 | `Iterable` can generate multiple valid `Iterator`s, though. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/IterablePathParameter.md: -------------------------------------------------------------------------------- 1 | [`java.nio.file.Path`] implements `Iterable`, and provides an iterator 2 | over the name elements of the path. Declaring a parameter of type 3 | `Iterable` is not recommended, since it allows clients to pass either an 4 | `Iterable` of `Path`s, or a single `Path`. Using `Collection` prevents 5 | clients from accidentally passing a single `Path`. 6 | 7 | [`java.nio.file.Path`]: https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html 8 | 9 | Example: 10 | 11 | ```java 12 | void printPaths(Iterable paths) { 13 | for (Path path : paths) System.err.println(path); 14 | } 15 | ``` 16 | 17 | ``` 18 | printPaths(Paths.get("/tmp/hello")); 19 | tmp 20 | hello 21 | ``` 22 | 23 | ``` 24 | printPaths(ImmutableList.of(Paths.get("/tmp/hello"))); 25 | /tmp/hello 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/bugpattern/JUnit3FloatingPointComparisonWithoutDelta.md: -------------------------------------------------------------------------------- 1 | Use `assertEquals(expected, actual, delta)` to compare floating-point numbers. 2 | This call to `assertEquals()` will either fail or not compile in JUnit 4. Use 3 | `assertEquals(expected, actual, 0.0)` if the delta must be `0.0`. 4 | 5 | Alternatively, one can use Google Truth library's `DoubleSubject` class which 6 | has both `isEqualTo()` for delta `0.0` and `isWithin()` for non-zero deltas. 7 | -------------------------------------------------------------------------------- /docs/bugpattern/JUnit3TestNotRun.md: -------------------------------------------------------------------------------- 1 | JUnit 3 requires that test method names start with "`test`". The method that 2 | triggered this error looks like it is supposed to be a test, but misspells the 3 | required prefix; has `@Test` annotation, but no prefix; or has the wrong method 4 | signature. As a consequence, JUnit 3 will ignore it. 5 | 6 | If you meant to disable this test on purpose, or this is a helper method, change 7 | the name to something more descriptive, like "`disabledTestSomething()`". You 8 | don't need an `@Test` annotation, but if you want to keep it, add `@Ignore` too. 9 | -------------------------------------------------------------------------------- /docs/bugpattern/JUnit4ClassAnnotationNonStatic.md: -------------------------------------------------------------------------------- 1 | JUnit4 provides two annotations ([`@BeforeClass`][beforeclass] and 2 | [`@AfterClass`][afterclass]) that are applied to methods that are run once per 3 | **test class**. These complement the more-often used `@Before` and `@After` 4 | which are applied to methods that are run once per **test method**. 5 | 6 | JUnit4 runs `@BeforeClass` and `@AfterClass` methods without making an instance 7 | of the test class, meaning that the methods must be `static`. JUnit4 will fail 8 | to run any `@BeforeClass` or `@AfterClass` method that isn't also `static`. 9 | 10 | [beforeclass]: https://junit.sourceforge.net/javadoc/org/junit/BeforeClass.html 11 | [afterclass]: https://junit.sourceforge.net/javadoc/org/junit/AfterClass.html 12 | -------------------------------------------------------------------------------- /docs/bugpattern/JUnit4SetUpNotRun.md: -------------------------------------------------------------------------------- 1 | JUnit 3 provides the method setUp(), to be overridden by subclasses when the 2 | test needs to perform some pre-test initialization. In JUnit 4, this is 3 | accomplished by annotating such a method with @Before. 4 | 5 | The method that triggered this error matches the definition of setUp() from 6 | JUnit3, but was not annotated with @Before and thus won't be run by the JUnit4 7 | runner. 8 | 9 | If you intend for this setUp() method not to run by the JUnit4 runner, but 10 | perhaps manually be invoked in certain test methods, please rename the method or 11 | mark it private. 12 | 13 | If the method is part of an abstract test class hierarchy where this class's 14 | setUp() is invoked by a superclass method that is annotated with @Before, then 15 | please rename the abstract method or add @Before to the superclass's definition 16 | of setUp() 17 | -------------------------------------------------------------------------------- /docs/bugpattern/JUnit4TearDownNotRun.md: -------------------------------------------------------------------------------- 1 | JUnit 3 provides the overridable method tearDown(), to be overridden by 2 | subclasses when the test needs to perform some post-test de-initialization. In 3 | JUnit 4, this is accomplished by annotating such a method with @After. The 4 | method that triggered this error matches the definition of tearDown() from 5 | JUnit3, but was not annotated with @After and thus won't be run by the JUnit4 6 | runner. 7 | 8 | If you intend for this tearDown() method not to be run by the JUnit4 runner, but 9 | perhaps be manually invoked after certain test methods, please rename the method 10 | or mark it private. 11 | 12 | If the method is part of an abstract test class hierarchy where this class's 13 | tearDown() is invoked by a superclass method that is annotated with @After, then 14 | please rename the abstract method or add @After to the superclass's definition 15 | of tearDown(). 16 | -------------------------------------------------------------------------------- /docs/bugpattern/JUnit4TestNotRun.md: -------------------------------------------------------------------------------- 1 | Unlike in JUnit 3, JUnit 4 tests will not be run unless annotated with @Test. 2 | The test method that triggered this error looks like it was meant to be a test, 3 | but was not so annotated, so it will not be run. If you intend for this test 4 | method not to run, please add both an @Test and an @Ignore annotation to make it 5 | clear that you are purposely disabling it. If this is a helper method and not a 6 | test, consider reducing its visibility to non-public, if possible. 7 | -------------------------------------------------------------------------------- /docs/bugpattern/JavaLangClash.md: -------------------------------------------------------------------------------- 1 | Class names from `java.lang` should never be reused. From 2 | [Java Puzzlers](https://www.javapuzzlers.com/java-puzzlers-sampler.pdf): 3 | 4 | > Avoid reusing the names of platform classes, and never reuse class names from 5 | > `java.lang`, because these names are automatically imported everywhere. 6 | > Programmers are used to seeing these names in their unqualified form and 7 | > naturally assume that these names refer to the familiar classes from 8 | > `java.lang`. If you reuse one of these names, the unqualified name will refer 9 | > to the new definition any time it is used inside its own package. 10 | -------------------------------------------------------------------------------- /docs/bugpattern/JavaUtilDate.md: -------------------------------------------------------------------------------- 1 | The `Date` API is full of 2 | [major design flaws and pitfalls](https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/) 3 | and should be avoided at all costs. Prefer the `java.time` APIs, specifically, 4 | `java.time.Instant` (for physical time) and `java.time.LocalDate[Time]` (for 5 | civil time). 6 | -------------------------------------------------------------------------------- /docs/bugpattern/JavaxInjectOnAbstractMethod.md: -------------------------------------------------------------------------------- 1 | The [`Inject`] annotation cannot be applied to abstract methods, per the JSR-330 2 | spec, since injectors will only inject those methods if the concrete implementer 3 | of the abstract method has the [`Inject`] annotation as well. See 4 | [OverridesJavaxInjectableMethod] for more examples of this interaction. 5 | 6 | Currently, default methods in interfaces are not injected if they have 7 | [`Inject`] for similar reasons, although future updates to dependency injection 8 | frameworks may allow this, since the default methods are not abstract. 9 | 10 | See the [Guice wiki] page on JSR-330 for more. 11 | 12 | [`Inject`]: https://javax-inject.github.io/javax-inject/api/javax/inject/Inject.html 13 | [OverridesJavaxInjectableMethod]: OverridesJavaxInjectableMethod 14 | [Guice wiki]: https://github.com/google/guice/wiki/JSR330 15 | -------------------------------------------------------------------------------- /docs/bugpattern/JavaxInjectOnFinalField.md: -------------------------------------------------------------------------------- 1 | According to the JSR-330 spec, the @javax.inject.Inject annotation cannot go on 2 | final fields. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/LabelledBreakTarget.md: -------------------------------------------------------------------------------- 1 | Labels should only be used on loops. For other statements, consider refactoring 2 | to express the control flow without labelled breaks. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/LambdaFunctionalInterface.md: -------------------------------------------------------------------------------- 1 | Prefer specialized functional interface types for primitives, for example 2 | `IntToLongFunction` instead of `Function`, to avoid boxing 3 | overhead. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/LiteEnumValueOf.md: -------------------------------------------------------------------------------- 1 | Byte code optimizers can change the implementation of `toString()` in lite 2 | runtime and thus using `valueOf(String)` is discouraged. Instead of converting 3 | enums to string and back, its numeric value should be used instead as it is the 4 | stable part of the protocol defined by the enum. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/LockOnBoxedPrimitive.md: -------------------------------------------------------------------------------- 1 | Instances of boxed primitive types may be cached by the standard library 2 | `valueOf` method. This method is used for autoboxing. This means that using a 3 | boxed primitive as a lock can result in unintentionally sharing a lock with 4 | another piece of code. 5 | 6 | Consider using an explicit lock `Object` instead of locking on a boxed 7 | primitive. That is, prefer this: 8 | 9 | ```java 10 | private final Object lock = new Object(); 11 | 12 | void doSomething() { 13 | synchronized (lock) { 14 | // ... 15 | } 16 | } 17 | ``` 18 | 19 | instead of this: 20 | 21 | ```java 22 | private final Integer lock = 42; 23 | 24 | void doSomething() { 25 | synchronized (lock) { 26 | // ... 27 | } 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/bugpattern/LogicalAssignment.md: -------------------------------------------------------------------------------- 1 | When an assignment expression is used as the condition of a loop, it isn't clear 2 | to the reader whether the assignment was deliberate or it was intended to be an 3 | equality test. Parenthesis should be used around assignments in loop conditions 4 | to make it clear to the reader that the assignment is deliberate. 5 | 6 | That is, instead of this: 7 | 8 | ```java 9 | void f(boolean x) { 10 | while (x = checkSomething()) { 11 | // ... 12 | } 13 | } 14 | ``` 15 | 16 | Prefer `while ((x = checkSomething())) {` or `while (x == checkSomething()) {`. 17 | -------------------------------------------------------------------------------- /docs/bugpattern/LongLiteralLowerCaseSuffix.md: -------------------------------------------------------------------------------- 1 | A long literal can have a suffix of 'L' or 'l', but the former is less likely to 2 | be confused with a '1' in most fonts. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/MislabeledAndroidString.md: -------------------------------------------------------------------------------- 1 | Certain resources in `android.R.string` have names that do not match their 2 | content: `android.R.string.yes` is actually "OK" and `android.R.string.no` is 3 | "Cancel". Avoid these string resources and prefer ones whose names *do* match 4 | their content. If you need "Yes" or "No" you must create your own string 5 | resources. 6 | -------------------------------------------------------------------------------- /docs/bugpattern/MisleadingEscapedSpace.md: -------------------------------------------------------------------------------- 1 | When Java introduced text blocks as a feature, it also introduced a new string 2 | escape sequence `\s`. This escape sequence is another way to write a normal 3 | space, but it has the advantage that it can be used at the end of a line in a 4 | text block, where a normal space would be stripped. 5 | 6 | This new escape sequence can easily be confused with the regex `\s`, which is a 7 | metacharacter that matches any kind of whitespace character. To write that 8 | metacharacter in a Java string, you must still write `\\s`: an escaped backslash 9 | followed by an `s`. 10 | 11 | There is little reason to ever write the Java escape `\s` except at the end of a 12 | line. Either use a normal space, or switch to `\\s` if you are trying to write 13 | the regex metacharacter. 14 | 15 | ```java 16 | // Each line here is five characters long. 17 | String colors = """ 18 | one \s 19 | two \s 20 | three 21 | """; 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/bugpattern/MissingOverride.md: -------------------------------------------------------------------------------- 1 | The [Google Java Style Guide §6.1][style] requires that a method is marked with 2 | the `@Override` annotation whenever it is legal. This includes a class method 3 | overriding a superclass method, a class method implementing an interface method, 4 | and an interface method respecifying a superinterface method. 5 | 6 | Exception: `@Override` may be omitted when the parent method is `@Deprecated`. 7 | If the flag `-XepOpt:MissingOverride:IgnoreInterfaceOverrides=true` is used, 8 | `@Override` can be omitted for an interface method respecifying a superinterface 9 | method. 10 | 11 | [style]: https://google.github.io/styleguide/javaguide.html#s6.1-override-annotation 12 | -------------------------------------------------------------------------------- /docs/bugpattern/MissingRefasterAnnotation.md: -------------------------------------------------------------------------------- 1 | A Refaster template consists of multiple methods. Typically, each method in the 2 | class has an annotation. If a method has no annotation, this is likely an 3 | oversight. 4 | 5 | ```java 6 | static final class MethodLacksBeforeTemplateAnnotation { 7 | @BeforeTemplate 8 | boolean before1(String string) { 9 | return string.equals(""); 10 | } 11 | 12 | // @BeforeTemplate is missing 13 | boolean before2(String string) { 14 | return string.length() == 0; 15 | } 16 | 17 | @AfterTemplate 18 | @AlsoNegation 19 | boolean after(String string) { 20 | return string.isEmpty(); 21 | } 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/bugpattern/MissingSuperCall.md: -------------------------------------------------------------------------------- 1 | API providers may annotate a method with an annotation like 2 | `androidx.annotation.CallSuper` or 3 | `javax.annotation.OverridingMethodsMustInvokeSuper` to require that overriding 4 | methods invoke the super method. This check enforces those annotations. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/MissingTestCall.md: -------------------------------------------------------------------------------- 1 | Some test helpers such as `EqualsTester` require a terminating method call to be 2 | of any use. 3 | 4 | ```java 5 | @Test 6 | public void string() { 7 | new EqualsTester() 8 | .addEqualityGroup("hello", new String("hello")) 9 | .addEqualityGroup("world", new String("world")) 10 | .addEqualityGroup(2, Integer.valueOf(2)); 11 | // Oops: forgot to call `testEquals()` 12 | } 13 | ``` 14 | -------------------------------------------------------------------------------- /docs/bugpattern/MisusedWeekYear.md: -------------------------------------------------------------------------------- 1 | "YYYY" in a date pattern means "week year". The week year is defined to begin at 2 | the beginning of the week that contains the year's first Thursday. For example, 3 | the week year 2015 began on Monday, December 29, 2014, since January 1, 2015, 4 | was on a Thursday. 5 | 6 | "Week year" is intended to be used for week dates, e.g. "2015-W01-1", but is 7 | often mistakenly used for calendar dates, e.g. 2014-12-29, in which case the 8 | year may be incorrect during the last week of the year. If you are formatting 9 | anything other than a week date, you should use the year specifier "yyyy" 10 | instead. 11 | -------------------------------------------------------------------------------- /docs/bugpattern/MixedDescriptors.md: -------------------------------------------------------------------------------- 1 | A field `Descriptor` was created by mixing the message `Descriptor` from one 2 | proto message with the field number from another. For example: 3 | 4 | ```java 5 | Foo.getDescriptor().findFieldByNumber(Bar.ID_FIELD_NUMBER) 6 | ``` 7 | 8 | This accesses the `Descriptor` of a field in `Foo` with a field number from 9 | `Bar`. One of these was probably intended: 10 | 11 | ```java 12 | Foo.getDescriptor().findFieldByNumber(Foo.ID_FIELD_NUMBER) 13 | Bar.getDescriptor().findFieldByNumber(Bar.ID_FIELD_NUMBER) 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/bugpattern/MixedMutabilityReturnType.md: -------------------------------------------------------------------------------- 1 | It is dangerous for a method to return a mutable instance in some circumstances, 2 | but immutable in others. Doing so may lead users of your API to make incorrect 3 | assumptions about the mutability of the return type. For example, consider this 4 | method: 5 | 6 | ```java 7 | List primeFactors(int n) { 8 | if (isPrime(n)) { 9 | return Collections.singletonList(n); 10 | } 11 | List factors = new ArrayList<>(); 12 | for (...) { 13 | factors.add(i); 14 | } 15 | return factors; 16 | } 17 | ``` 18 | 19 | If someone were to add another method to include the trivial factor `1`, a bug 20 | will be introduced. 21 | 22 | ```java 23 | List primeFactorsAndOne(int n) { 24 | List primeFactors = primeFactors(n); 25 | primeFactors.add(1); 26 | return primeFactors; 27 | } 28 | ``` 29 | 30 | `primeFactorsAndOne` will behave as intended for composite numbers, but throw an 31 | exception for primes. 32 | -------------------------------------------------------------------------------- /docs/bugpattern/MockitoDoSetup.md: -------------------------------------------------------------------------------- 1 | Prefer using the format 2 | 3 | ```java 4 | when(mock.mockedMethod(...)).thenReturn(returnValue); 5 | ``` 6 | 7 | to initialise mocks, rather than, 8 | 9 | ```java 10 | doReturn(returnValue).when(mock).mockedMethod(...); 11 | ``` 12 | 13 | Mockito recommends the `when`/`thenReturn` syntax as it is both more readable 14 | and provides type-safety: the return type of the stubbed method is checked 15 | against the stubbed value at compile time. 16 | 17 | There are certain situations where `doReturn` is required: 18 | 19 | * Overriding previous stubbing where the method will *throw*, as `when` makes 20 | an actual method call. 21 | * Overriding a `spy` where the method call where calling the spied method 22 | brings undesired side-effects. 23 | -------------------------------------------------------------------------------- /docs/bugpattern/MockitoUsage.md: -------------------------------------------------------------------------------- 1 | Calls to `Mockito.when` should always be accompanied by a call to a method like 2 | `thenReturn`. 3 | 4 | ```java 5 | when(mock.get()).thenReturn(answer); // correct 6 | when(mock.get()) // oops! 7 | ``` 8 | 9 | Similarly, calls to `Mockito.verify` should call the verified method *outside* 10 | the call to `verify`. 11 | 12 | ```java 13 | verify(mock).execute(); // correct 14 | verify(mock.execute()); // oops! 15 | ``` 16 | 17 | For more information, see the [Mockito documentation][docs]. 18 | 19 | [docs]: https://github.com/mockito/mockito/wiki/FAQ#what-are-unfinished-verificationstubbing-errors 20 | -------------------------------------------------------------------------------- /docs/bugpattern/ModifyingCollectionWithItself.md: -------------------------------------------------------------------------------- 1 | Invoking a collection method with the same collection as the argument is likely 2 | incorrect. 3 | 4 | * `collection.addAll(collection)` may cause an infinite loop, duplicate the 5 | elements, or do nothing, depending on the type of Collection and 6 | implementation class. 7 | * `collection.retainAll(collection)` is a no-op. 8 | * `collection.removeAll(collection)` is the same as `collection.clear()`. 9 | * `collection.containsAll(collection)` is always true. 10 | -------------------------------------------------------------------------------- /docs/bugpattern/MoreThanOneInjectableConstructor.md: -------------------------------------------------------------------------------- 1 | Injection frameworks may use `@Inject` to determine how to construct an object 2 | in the absence of other instructions. Annotating `@Inject` on a constructor 3 | tells the injection framework to use that constructor. However, if multiple 4 | `@Inject` constructors exist, injection frameworks can't reliably choose between 5 | them. 6 | -------------------------------------------------------------------------------- /docs/bugpattern/MoveToSafeHtmlResponse.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/error-prone/962f83aac3193dca53129e8e3b34740176bc0bde/docs/bugpattern/MoveToSafeHtmlResponse.md -------------------------------------------------------------------------------- /docs/bugpattern/MultipleTopLevelClasses.md: -------------------------------------------------------------------------------- 1 | The Google Java Style Guide §3.4.1 requires each source file to contain exactly 2 | one top-level class. 3 | 4 | ## Suppression 5 | 6 | Since `@SuppressWarnings` cannot be applied to package declarations, this 7 | warning can be suppressed by annotating any top-level class in the compilation 8 | unit with `@SuppressWarnings("MultipleTopLevelClasses")`. 9 | -------------------------------------------------------------------------------- /docs/bugpattern/MultipleUnaryOperatorsInMethodCall.md: -------------------------------------------------------------------------------- 1 | Increment operators in method calls are dubious and while argument lists are 2 | evaluated left-to-right, documentation suggests that code not rely on this 3 | specification. In addition, code is clearer when each expression contains at 4 | most one side effect. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/MustBeClosedChecker.md: -------------------------------------------------------------------------------- 1 | Methods or constructors annotated with `@MustBeClosed` require that the returned 2 | resource is closed. This is enforced by checking that invocations occur within 3 | the resource variable initializer of a try-with-resources statement: 4 | 5 | ```java 6 | try (AutoCloseable resource = createTheResource()) { 7 | doSomething(resource); 8 | } 9 | ``` 10 | 11 | or the `return` statement of another method annotated with `@MustBeClosed`: 12 | 13 | ```java 14 | @MustBeClosed 15 | AutoCloseable createMyResource() { 16 | return createTheResource(); 17 | } 18 | ``` 19 | 20 | To support legacy code, the following pattern is also supported: 21 | 22 | ```java 23 | AutoCloseable resource = createTheResource(); 24 | try { 25 | doSomething(resource); 26 | } finally { 27 | resource.close(); 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/bugpattern/MutableGuiceModule.md: -------------------------------------------------------------------------------- 1 | Guice modules should not be mutable. 2 | -------------------------------------------------------------------------------- /docs/bugpattern/MutablePublicArray.md: -------------------------------------------------------------------------------- 1 | Nonzero-length arrays are mutable. Declaring one `public static final` indicates 2 | that the developer expects it to be a constant, which is not the case. Making it 3 | `public` is especially dangerous since clients of this code can modify the 4 | contents of the array. 5 | 6 | There are two ways to fix this problem: 7 | 8 | 1. Refactor the array to an `ImmutableList`. 9 | 2. Make the array `private` and add a `public` method that returns a copy of 10 | the `private` array. 11 | 12 | See [Effective Java 3rd Edition §15][ej3e-15] for more details. 13 | 14 | [ej3e-15]: https://books.google.com/books?id=BIpDDwAAQBAJ 15 | -------------------------------------------------------------------------------- /docs/bugpattern/NCopiesOfChar.md: -------------------------------------------------------------------------------- 1 | Calling `nCopies('a', 10)` returns a list with 97 copies of 10, not a list with 2 | 10 copies of 'a'. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/NewFileSystem.md: -------------------------------------------------------------------------------- 1 | Starting in JDK 13, calls to `FileSystem.newFileSystem(path, null)` are 2 | ambiguous. 3 | 4 | The calls match both: 5 | 6 | * [`FileSystem.newFileSystem(Path, ClassLoader)`](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/nio/file/FileSystems.html#newFileSystem\(java.nio.file.Path,java.lang.ClassLoader\)) 7 | * [`FileSystem.newFileSystem(Path, Map)`](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/nio/file/FileSystems.html#newFileSystem\(java.nio.file.Path,java.util.Map\)) 8 | 9 | To disambiguate, add a cast to the desired type, to preserve the pre-JDK 13 10 | behaviour. 11 | 12 | That is, prefer this: 13 | 14 | ```java 15 | FileSystem.newFileSystem(path, (ClassLoader) null); 16 | ``` 17 | 18 | Instead of this: 19 | 20 | ```java 21 | FileSystem.newFileSystem(path, null); 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/bugpattern/NonAtomicVolatileUpdate.md: -------------------------------------------------------------------------------- 1 | The volatile modifier ensures that updates to a variable are propagated 2 | predictably to other threads. A read of a volatile variable always returns the 3 | most recent write by any thread. 4 | 5 | However, this does not mean that all updates to a volatile variable are atomic. 6 | For example, if you increment or decrement a volatile variable, you are actually 7 | doing (1) a read of the variable, (2) an increment or decrement of a local copy, 8 | and (3) a write back to the variable. Each step is atomic individually, but the 9 | whole sequence is not, and it will cause a race condition if two threads try to 10 | increment or decrement a volatile variable at the same time. The same is true 11 | for compound assignment, e.g. foo += bar. 12 | 13 | If you intended for this update to be atomic, you should wrap all update 14 | operations on this variable in a synchronized block. If the variable is an 15 | integer, you could use an AtomicInteger instead of a volatile int. 16 | -------------------------------------------------------------------------------- /docs/bugpattern/NonCanonicalType.md: -------------------------------------------------------------------------------- 1 | Types being referred to by non-canonical names can be confusing. For example, 2 | 3 | ```java 4 | public final class Entries { 5 | private final ImmutableList> entries; 6 | 7 | public Entries(Map map) { 8 | this.entries = ImmutableList.copyOf(map.entrySet()); 9 | } 10 | } 11 | ``` 12 | 13 | There is nothing special about `ImmutableMap.Entry`; it is precisely the same 14 | type as `Map.Entry`. This example makes it look deceptively as though 15 | `ImmutableList>` is an immutable type and therefore 16 | safe to store indefinitely, when really it offers no more safety than 17 | `ImmutableList>`. You should use `ImmutableList>` instead, so it's obvious what type you're referring to. 19 | -------------------------------------------------------------------------------- /docs/bugpattern/NonFinalCompileTimeConstant.md: -------------------------------------------------------------------------------- 1 | If a method's formal parameter is annotated with `@CompileTimeConstant`, the 2 | method will always be invoked with an argument that is a static constant. If the 3 | parameter itself is non-final, then it is a mutable reference to immutable data. 4 | This is rarely useful, and can be confusing when trying to use the parameter in 5 | a context that requires an compile-time constant. For example: 6 | 7 | ```java 8 | void f(@CompileTimeConstant y) {} 9 | void g(@CompileTimeConstant x) { 10 | x = f(x); // x is not a constant 11 | } 12 | ``` 13 | -------------------------------------------------------------------------------- /docs/bugpattern/NonFinalStaticField.md: -------------------------------------------------------------------------------- 1 | `static` fields should almost always be both `final` and deeply immutable. 2 | 3 | Instead of: 4 | 5 | ```java 6 | private static String FOO = "foo"; 7 | ``` 8 | 9 | Prefer: 10 | 11 | ```java 12 | private static final String FOO = "foo"; 13 | ``` 14 | -------------------------------------------------------------------------------- /docs/bugpattern/NonRuntimeAnnotation.md: -------------------------------------------------------------------------------- 1 | Calling getAnnotation on an annotation that does not have its Retention set to 2 | RetentionPolicy.RUNTIME will always return null. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/NullOptional.md: -------------------------------------------------------------------------------- 1 | Passing a literal `null` to an `Optional` accepting parameter is likely a bug. 2 | `Optional` is already designed to encode missing values through a non-`null` 3 | instance. 4 | 5 | ```java 6 | Optional double(Optional i) { 7 | return i.map(i -> i * 2); 8 | } 9 | 10 | Optional doubled = double(null); 11 | ``` 12 | 13 | ```java 14 | Optional doubled = double(Optional.empty()); 15 | ``` 16 | 17 | This is a scenario that can easily happen when refactoring code from accepting 18 | `@Nullable` parameters to accept `Optional`s. Note that the check will not match 19 | if the parameter is explicitly annotated `@Nullable`. 20 | -------------------------------------------------------------------------------- /docs/bugpattern/NullTernary.md: -------------------------------------------------------------------------------- 1 | If a conditional expression evaluates to `null`, unboxing it will result in a 2 | `NullPointerException`. 3 | 4 | For example: 5 | 6 | ```java 7 | int x = flag ? foo : null; 8 | ``` 9 | 10 | If `flag` is false, `null` will be auto-unboxed from an `Integer` to `int`, 11 | resulting in a NullPointerException. 12 | -------------------------------------------------------------------------------- /docs/bugpattern/NullableConstructor.md: -------------------------------------------------------------------------------- 1 | Constructors never return null. 2 | -------------------------------------------------------------------------------- /docs/bugpattern/NullableOptional.md: -------------------------------------------------------------------------------- 1 | `Optional` is a container object which may or may not contain a value. The 2 | presence or absence of the contained value should be demonstrated by the 3 | `Optional` object itself. 4 | 5 | Using an Optional variable which is expected to possibly be null is discouraged. 6 | An nullable Optional which uses `null` to indicate the absence of the value will 7 | lead to extra work for `null` checking when using the object and even cause 8 | exceptions such as `NullPointerException`. It is best to indicate the absence of 9 | the value by assigning it an empty optional. 10 | -------------------------------------------------------------------------------- /docs/bugpattern/NullablePrimitive.md: -------------------------------------------------------------------------------- 1 | Primitives can never be null. 2 | -------------------------------------------------------------------------------- /docs/bugpattern/NullablePrimitiveArray.md: -------------------------------------------------------------------------------- 1 | For `@Nullable` type annotations (such as 2 | `org.checkerframework.checker.nullness.qual.Nullable`), `@Nullable byte[]` means 3 | a 'non-null array of nullable bytes', and `byte @Nullable []` means a 'nullable 4 | array of non-null bytes'. Since primitive types cannot be null, the former is 5 | incorrect. 6 | 7 | Some other nullness annotations (such as `javax.annotation.Nullable`) are 8 | _declaration_ annotations rather than _type_ annotations. Their meaning is 9 | different: For such annotations, `@Nullable byte[]` refers to 'a nullable array 10 | of non-null bytes,' and `byte @Nullable []` is rejected by javac. Thus, this 11 | check never reports errors for usages of declaration annotations. 12 | 13 | See also: https://checkerframework.org/manual/#faq-array-syntax-meaning 14 | -------------------------------------------------------------------------------- /docs/bugpattern/NullableVoid.md: -------------------------------------------------------------------------------- 1 | void-returning methods cannot return null. 2 | -------------------------------------------------------------------------------- /docs/bugpattern/ObjectToString.md: -------------------------------------------------------------------------------- 1 | Calling `toString` on objects that don't override `toString()` doesn't provide 2 | useful information (just the class name and the `hashCode()`). 3 | 4 | Consider overriding toString() function to return a meaningful String describing 5 | the object. 6 | -------------------------------------------------------------------------------- /docs/bugpattern/OperatorPrecedence.md: -------------------------------------------------------------------------------- 1 | The [Google Java Style Guide §4.7][style] states: 2 | 3 | > Optional grouping parentheses are omitted only when author and reviewer agree 4 | > that there is no reasonable chance the code will be misinterpreted without 5 | > them, nor would they have made the code easier to read. It is not reasonable 6 | > to assume that every reader has the entire Java operator precedence table 7 | > memorized. 8 | 9 | [style]: https://google.github.io/styleguide/javaguide.html#s4.7-grouping-parentheses 10 | 11 | Use grouping parentheses to disambiguate expressions that could be 12 | misinterpreted. 13 | 14 | For example, consider this: 15 | 16 | ```java 17 | boolean d = (a && b) || c;", 18 | boolean e = (a || b) ? c : d;", 19 | int z = (x + y) << 2;", 20 | ``` 21 | 22 | Instead of this: 23 | 24 | ```java 25 | boolean r = a && b || c;", 26 | boolean e = a || b ? c : d;", 27 | int z = x + y << 2;", 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/bugpattern/OptionalEquality.md: -------------------------------------------------------------------------------- 1 | Optionals should be compared for value equality using `.equals()`, and not for 2 | reference equality using `==` and `!=`. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/OptionalNotPresent.md: -------------------------------------------------------------------------------- 1 | Calling `get()` on an `Optional` that is not present will result in a 2 | `NoSuchElementException`. 3 | 4 | This check detects cases where `get()` is called when the optional is definitely 5 | not present, e.g.: 6 | 7 | ```java 8 | if (!o.isPresent()) { 9 | return o.get(); // this will throw a NoSuchElementException 10 | } 11 | ``` 12 | 13 | ```java 14 | if (o.isEmpty()) { 15 | return o.get(); // this will throw a NoSuchElementException 16 | } 17 | ``` 18 | 19 | These cases are almost definitely bugs; the intent may have been to invert the 20 | test: 21 | 22 | ```java 23 | if (o.isPresent()) { 24 | return o.get(); 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/bugpattern/OutlineNone.md: -------------------------------------------------------------------------------- 1 | The `outline` CSS property provides visual indicators as to which element is 2 | currently selected within a web page. These are the dotted lines you see 3 | surrounding links, etc. when you tab to them using the keyboard. 4 | 5 | ![A link shown with and without a focus outline.](https://github.com/google/error-prone/blob/gh-pages/images/Outline%20Demonstration.png) 6 | 7 | These indicators are important for users navigating without a mouse (such as 8 | those with visual or mobility impairments). Setting `outline` style to `"none"` 9 | or `0` removes these indicators, leaving these users without any way to tell 10 | where they are within the page, therefore making the page inaccessible. 11 | 12 | Caveat: `outline` is not the *only* way to emphasize selected elements. You may 13 | instead choose to change the background color, add an underline, or otherwise 14 | make them visually distinct. Learn more & get alternative suggestions at 15 | [OutlineNone.com](https://outlinenone.com). 16 | -------------------------------------------------------------------------------- /docs/bugpattern/OverrideThrowableToString.md: -------------------------------------------------------------------------------- 1 | Many logging tools build a string representation out of getMessage() and ignores 2 | toString() completely. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/OverridesGuiceInjectableMethod.md: -------------------------------------------------------------------------------- 1 | Unlike with `@javax.inject.Inject`, if a method overrides a method annotated 2 | with `@com.google.inject.Inject`, Guice will inject it even if it itself is not 3 | annotated. This differs from the behavior of methods that override 4 | `@javax.inject.Inject` methods since according to the JSR-330 spec, a method 5 | that overrides a method annotated with `@javax.inject.Inject` will not be 6 | injected unless it itself is annotated with `@Inject`. Because of this 7 | difference, it is recommended that you annotate this method explicitly. 8 | -------------------------------------------------------------------------------- /docs/bugpattern/OverridingMethodInconsistentArgumentNamesChecker.md: -------------------------------------------------------------------------------- 1 | Inconsistently ordered parameters in method overrides mostly indicate an 2 | accidental bug in the overriding method. An example for an overriding method 3 | with inconsistent parameter names: 4 | 5 | ```java 6 | class A { 7 | public void foo(int foo, int baz) { ... } 8 | } 9 | 10 | class B extends A { 11 | @Override 12 | public void foo(int baz, int foo) { ... } 13 | } 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/bugpattern/PackageInfo.md: -------------------------------------------------------------------------------- 1 | Classes should not be declared inside `package-info.java` files. 2 | 3 | > Typically package-info.java contains only a package declaration, preceded 4 | > immediately by the annotations on the package. While the file could 5 | > technically contain the source code for one or more classes with package 6 | > access, it would be very bad form. 7 | 8 | -- [JLS 7.4] 9 | 10 | [JLS 7.4]: https://docs.oracle.com/javase/specs/jls/se8/html/jls-7.html#jls-7.4 11 | -------------------------------------------------------------------------------- /docs/bugpattern/PackageLocation.md: -------------------------------------------------------------------------------- 1 | Java files should be located in a directory that 2 | ends with the fully qualified name of the package. 3 | 4 | For example, classes in the package `edu.oswego.cs.dl.util.concurrent` should be 5 | located in: `.../edu/oswego/cs/dl/util/concurrent`. 6 | 7 | ## Suppression 8 | 9 | If necessary, the check may be suppressed by annotating the enclosing package 10 | declaration with `@com.google.errorprone.annotations.SuppressPackageLocation`, 11 | for example: 12 | 13 | ```java 14 | // package-info.java 15 | @com.google.errorprone.annotations.SuppressPackageLocation 16 | package com.google.my.pkg; 17 | ``` 18 | 19 | Note that package annotations must be located in a `package-info.java` file that 20 | must be built together with the package. 21 | -------------------------------------------------------------------------------- /docs/bugpattern/ParameterComment.md: -------------------------------------------------------------------------------- 1 | When documenting the name of the corresponding formal parameter for a method 2 | argument, prefer the `f(/* foo= */ value)` style of comment. 3 | 4 | The problem with e.g. `f(false /* exclusive */)` is it can be interpreted 5 | multiple ways: 6 | 7 | * Exclusiveness is false, so this is inclusive. 8 | * I am making this exclusive by setting the inclusiveness to false. 9 | 10 | TIP: When you feel the need to add a parameter comment, consider whether the API 11 | could be changed to be more self-documenting. 12 | 13 | NOTE: The `f(/* foo= */ value)` format leads to compile-time enforcement that 14 | the parameter comment matches the formal parameter name. 15 | -------------------------------------------------------------------------------- /docs/bugpattern/PatternMatchingInstanceof.md: -------------------------------------------------------------------------------- 1 | Pattern matching with `instanceof` allows writing this: 2 | 3 | ```java 4 | void handle(Object o) { 5 | if (o instanceof Point(int x, int y)) { 6 | handlePoint(x, y); 7 | } else if (o instanceof String s) { 8 | handleString(s); 9 | } 10 | } 11 | ``` 12 | 13 | which is more concise than an instanceof and a separate cast: 14 | 15 | ```java 16 | void handle(Object o) { 17 | if (o instanceof Point) { 18 | Point point = (Point) o; 19 | handlePoint(point.x(), point.y()); 20 | } else if (o instanceof String) { 21 | String s = (String) o; 22 | handleString(s); 23 | } 24 | } 25 | ``` 26 | 27 | For more information on pattern matching and `instanceof`, see 28 | [Pattern Matching for the instanceof Operator](https://docs.oracle.com/en/java/javase/21/language/pattern-matching-instanceof.html) 29 | -------------------------------------------------------------------------------- /docs/bugpattern/PreconditionsExpensiveString.md: -------------------------------------------------------------------------------- 1 | Preconditions checks take an error message to display if the check fails. The 2 | error message is rarely needed, so it should either be cheap to construct or 3 | constructed only when needed. This check ensures that these error messages are 4 | not constructed using expensive methods that are evaluated eagerly. 5 | 6 | Prefer this: 7 | 8 | ```java 9 | checkNotNull(foo, "hello %s", name); 10 | ``` 11 | 12 | instead of this: 13 | 14 | ```java 15 | checkNotNull(foo, String.format("hello %s", name)); 16 | ``` 17 | -------------------------------------------------------------------------------- /docs/bugpattern/PreconditionsInvalidPlaceholder.md: -------------------------------------------------------------------------------- 1 | The Guava Preconditions checks take error message template strings that look 2 | similar to format strings, but only accept the %s format (not %d, %f, etc.). 3 | This check points out places where a Preconditions error message template string 4 | has a non-%s format, or where the number of arguments does not match the number 5 | of %s formats in the string. 6 | -------------------------------------------------------------------------------- /docs/bugpattern/PreferJavaTimeOverload.md: -------------------------------------------------------------------------------- 1 | APIs that accept a `java.time.Duration` or `java.time.Instant` should be 2 | preferred, when available. 3 | 4 | JodaTime is now considered a legacy library for Java 8+ users. 5 | 6 | Representing date/time concepts as numeric primitives is strongly discouraged 7 | (e.g., `long timeout`). 8 | 9 | APIs that require a `long, TimeUnit` pair suffer from a number of problems 10 | 11 | 1. they may require plumbing 2 parameters through various layers of your 12 | application 13 | 14 | 2. overflows are possible when doing duration math 15 | 16 | 3. they lack semantic meaning (when viewed separately) 17 | 18 | 4. decomposing a duration into a `long, TimeUnit` is dangerous because of unit 19 | mismatch and/or excessive truncation. 20 | -------------------------------------------------------------------------------- /docs/bugpattern/PrimitiveArrayPassedToVarargsMethod.md: -------------------------------------------------------------------------------- 1 | When you pass a primitive array as the only argument to a varargs method, the 2 | primitive array is autoboxed into a single-element Object array. This is usually 3 | not what was intended. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/PrivateConstructorForNoninstantiableModule.md: -------------------------------------------------------------------------------- 1 | Modules that contain abstract binding methods (@Binds, @Multibinds) or only 2 | static @Provides methods will not be instantiated by Dagger when they are 3 | included in a component. Adding a private constructor clearly conveys that the 4 | module will not be used as an instance. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/PrivateConstructorForUtilityClass.md: -------------------------------------------------------------------------------- 1 | Utility classes are classes that only include static members and are not 2 | designed to be instantiated, for example `java.lang.Math` or `java.util.Arrays`. 3 | 4 | In the absence of explicit constructors, however, the compiler provides a 5 | public, parameterless default constructor. To a user, this constructor is 6 | indistinguishable from any other. It is not uncommon for a published API to 7 | accidentally include a public constructor for a class intended to be 8 | uninstantiable. 9 | 10 | To prevent users from instantiating classes that are not designed to be 11 | instantiated, you can add a private constructor: 12 | 13 | ```java 14 | public class UtilityClass { 15 | private UtilityClass() {} 16 | } 17 | ``` 18 | 19 | See: 20 | 21 | * [Effective Java 3rd Edition §4][ej3e-4] 22 | 23 | [ej3e-4]: https://books.google.com/books?id=BIpDDwAAQBAJ 24 | -------------------------------------------------------------------------------- /docs/bugpattern/ProtoStringFieldReferenceEquality.md: -------------------------------------------------------------------------------- 1 | Comparing strings with == is almost always an error, but it is an error 100% of 2 | the time when one of the strings is a protobuf field. Additionally, protobuf 3 | fields cannot be null, so Object.equals(Object) is always more correct. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/ProtoTruthMixedDescriptors.md: -------------------------------------------------------------------------------- 1 | ProtoTruth's `#ignoringFields` method accepts integer field numbers, so 2 | supplying field numbers from the wrong protocol buffers is possible. For 3 | example: 4 | 5 | ```proto 6 | message Bar { 7 | optional string name = 1; 8 | } 9 | message Foo { 10 | optional string name = 1; 11 | optional Bar bar = 2; 12 | } 13 | ``` 14 | 15 | ```java 16 | void assertOnFoo(Foo foo) { 17 | assertThat(foo).ignoringFields(Bar.NAME_FIELD_NUMBER).isEqualTo(...); 18 | } 19 | ``` 20 | 21 | This will ignore the `Foo#name` field rather than `Bar#name`. The field number 22 | can be turned into a `Descriptor` object to resolve the correct nested field to 23 | ignore: 24 | 25 | ```java 26 | void assertOnFoo(Foo foo) { 27 | assertThat(foo) 28 | .ignoringFieldDescriptors( 29 | Bar.getDescriptor().findFieldByNumber(Bar.NAME_FIELD_NUMBER)) 30 | .isEqualTo(...); 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/bugpattern/ProtocolBufferOrdinal.md: -------------------------------------------------------------------------------- 1 | The generated Java source files for Protocol Buffer enums have `getNumber()` as 2 | accessors for the tag number in the protobuf file. 3 | 4 | In addition, since it's a java enum, it also has the `ordinal()` method, 5 | returning its positional index within the generated java enum. 6 | 7 | The `ordinal()` order of the generated Java enums isn't guaranteed, and can 8 | change when a new enum value is inserted into a proto enum. The `getNumber()` 9 | value won't change for an enum value (since making that change is a 10 | backwards-incompatible change for the protocol buffer). 11 | 12 | You should very likely use `getNumber()` in preference to `ordinal()` in all 13 | circumstances since it's a more stable value. 14 | 15 | Note: If you're changing code that was already using ordinal(), it's likely that 16 | getNumber() will return a different real value. Tread carefully to avoid 17 | mismatches if the ordinal was persisted elsewhere. 18 | -------------------------------------------------------------------------------- /docs/bugpattern/ProvidesMethodOutsideOfModule.md: -------------------------------------------------------------------------------- 1 | Guice `@Provides` methods annotate methods that are used as a means of declaring 2 | bindings. However, this is only helpful inside of a module. Methods outside of 3 | these modules are not used for binding declaration. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/QualifierWithTypeUse.md: -------------------------------------------------------------------------------- 1 | Allowing a qualifier annotation in [`TYPE_PARAMETER`] or [`TYPE_USE`] contexts 2 | allows end users to write code like: 3 | 4 | ```java 5 | @Inject Foo(List<@MyAnnotation String> strings) 6 | ``` 7 | 8 | Guice, Dagger, and other dependency injection frameworks don't currently see 9 | type annotations in this context, so the above code is equivalent to: 10 | 11 | ```java 12 | @Inject Foo(List strings) 13 | ``` 14 | 15 | [`TYPE_PARAMETER`]: https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/ElementType.html#TYPE_PARAMETER 16 | [`TYPE_USE`]: https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/ElementType.html#TYPE_USE 17 | -------------------------------------------------------------------------------- /docs/bugpattern/RandomCast.md: -------------------------------------------------------------------------------- 1 | `Math.random()`, `Random#nextFloat`, and `Random#nextDouble` return results in 2 | the range `[0.0, 1.0)`. Therefore, casting the result to `(int)` or `(long)` 3 | *always* results in the value of `0`. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/RandomModInteger.md: -------------------------------------------------------------------------------- 1 | `Random.nextInt() % n` has 2 | 3 | * a 1/n chance of being 0 4 | * a 1/2n chance of being each number from `1` to `n-1` inclusive 5 | * a 1/2n chance of being each number from `-1` to `-(n-1)` inclusive 6 | 7 | Many users expect a uniformly distributed random integer between `0` and `n-1` 8 | inclusive, but you must use random.nextInt(n) to get that behavior. If the 9 | original behavior is truly desired, use `(random.nextBoolean() ? 1 : -1) * 10 | random.nextInt(n)`. 11 | -------------------------------------------------------------------------------- /docs/bugpattern/RectIntersectReturnValueIgnored.md: -------------------------------------------------------------------------------- 1 | `android.graphics.Rect.intersect(Rect r)` and 2 | `android.graphics.Rect.intersect(int, int, int, int)` do not always modify the 3 | rectangle to the intersected result. If the rectangles do not intersect, no 4 | change is made and the original rectangle is not modified. These methods return 5 | false to indicate that this has happened. 6 | 7 | If you don’t check the return value of these methods, you may end up drawing the 8 | wrong rectangle. 9 | -------------------------------------------------------------------------------- /docs/bugpattern/RedundantOverride.md: -------------------------------------------------------------------------------- 1 | An override of a method that delegates its implementation to the super method is 2 | redundant, and can be removed. 3 | 4 | For example, the `equals` method in the following class implementation can be 5 | deleted. 6 | 7 | ```java 8 | class Test { 9 | @Override 10 | public boolean equals(Object o) { 11 | return super.equals(o); 12 | } 13 | } 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/bugpattern/RedundantSetterCall.md: -------------------------------------------------------------------------------- 1 | Proto and AutoValue builders provide a fluent interface for constructing 2 | instances. Unlike argument lists, however, they do not prevent the user from 3 | providing multiple values for the same field. 4 | 5 | Setting the same field multiple times in the same chained expression is 6 | pointless (as the intermediate value will be overwritten), and can easily mask a 7 | bug, especially if the setter is called with *different* arguments. 8 | 9 | ```java 10 | return MyProto.newBuilder() 11 | .setFoo(copy.getFoo()) 12 | .setFoo(copy.getBar()) 13 | .build(); 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/bugpattern/RemoveUnusedImports.md: -------------------------------------------------------------------------------- 1 | This import is unused. 2 | 3 | ## The check reported an import that was actually used! 4 | 5 | The check has no known bugs. If it reports an unused import that looks like it 6 | was actually used, try removing it and recompiling. If everything still 7 | compiles, it was unused. 8 | 9 | Note that the check can detect some unused imports that `google-java-format` 10 | cannot. The formatter looks at a single file at a time, so `RemoveUnusedImports` 11 | is more accurate in examples like the following: 12 | 13 | ```java 14 | package a; 15 | 16 | import b.Baz; // this is unused! 17 | 18 | class Foo extends Bar { 19 | Baz baz; // this is a.Bar.Baz (from the supertype), *not* b.Baz 20 | } 21 | ``` 22 | 23 | ```java 24 | package a; 25 | class Bar { 26 | class Baz {} 27 | } 28 | ``` 29 | 30 | ```java 31 | package b; 32 | class Baz {} 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/bugpattern/RequiredModifiers.md: -------------------------------------------------------------------------------- 1 | This annotation is itself annotated with @RequiredModifiers and can only be used 2 | when the specified modifiers are present. You are attempting to use it on an 3 | element that is missing one or more required modifiers. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/RestrictedApi.md: -------------------------------------------------------------------------------- 1 | Calls to APIs marked `@RestrictedApi` are prohibited without a corresponding 2 | allowlist annotation. 3 | 4 | The intended use-case for `@RestrictedApi` is to restrict calls to annotated 5 | methods so that each usage of those APIs must be reviewed separately. For 6 | example, an API might lead to security bugs unless the programmer uses it 7 | correctly. 8 | 9 | See the 10 | [javadoc for `@RestrictedApi`](https://errorprone.info/api/latest/com/google/errorprone/annotations/RestrictedApi.html) 11 | for more details. 12 | -------------------------------------------------------------------------------- /docs/bugpattern/RethrowReflectiveOperationExceptionAsLinkageError.md: -------------------------------------------------------------------------------- 1 | Consider using `LinkageError` instead of `AssertionError` when rethrowing 2 | reflective exceptions as unchecked exceptions, since it conveys more information 3 | when reflection fails due to an incompatible change in the classpath. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/ReturnAtTheEndOfVoidFunction.md: -------------------------------------------------------------------------------- 1 | Detects no-op `return` statements in `void` functions when they occur at the end 2 | of the method. 3 | 4 | Instead of: 5 | 6 | ```java 7 | public void stuff() { 8 | int x = 5; 9 | return; 10 | } 11 | ``` 12 | 13 | do: 14 | 15 | ```java 16 | public void stuff() { 17 | int x = 5; 18 | } 19 | ``` 20 | -------------------------------------------------------------------------------- /docs/bugpattern/ReturnMissingNullable.md: -------------------------------------------------------------------------------- 1 | Annotating a method `@Nullable` communicates to tools that the method can return 2 | null. That means they can check that callers handle a returned null correctly. 3 | 4 | Adding `@Nullable` may require updating callers so that they deal with the 5 | possibly-null value. This can happen for example with Kotlin callers, or with 6 | Java callers that are checked for null-safety by static-analysis tools. 7 | Alternatively, depending on the tool, it may be possible to annotate Java 8 | callers temporarily with `@SuppressWarnings("nullness")`. 9 | -------------------------------------------------------------------------------- /docs/bugpattern/ScopeOnModule.md: -------------------------------------------------------------------------------- 1 | Scopes on modules have no function and are often incorrectly assumed to apply 2 | the scope to every binding method in the module. This check removes all scope 3 | annotations from any class annotated with `@Module` or `@ProducerModule`. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/SelfAlwaysReturnsThis.md: -------------------------------------------------------------------------------- 1 | A common pattern for abstract `Builders` is to declare an instance method named 2 | `self()`, which subtypes override and implement as `return this` (see Effective 3 | Java 3rd Edition, Item 2). 4 | 5 | Returning anything other than `this` from an instance method named `self()` with 6 | a return type that matches the enclosing class will be confusing for readers and 7 | callers. 8 | 9 | ## Casting 10 | 11 | If an unchecked cast is required, prefer a single-statement cast, with the 12 | suppression on the method (rather than the statement). For example: 13 | 14 | ```java 15 | @SuppressWarnings("unchecked") 16 | default U self() { 17 | return (U) this; 18 | } 19 | ``` 20 | 21 | Instead of: 22 | 23 | ```java 24 | default U self() { 25 | @SuppressWarnings("unchecked") 26 | U self = (U) this; 27 | return self; 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/bugpattern/SelfAssertion.md: -------------------------------------------------------------------------------- 1 | If a test subject and the argument to `isEqualTo` are the same instance (e.g. 2 | `assertThat(x).isEqualTo(x)`), then the assertion will always pass. Truth 3 | implements `isEqualTo` using [`Objects#equal`] , which tests its arguments for 4 | reference equality and returns true without calling `equals()` if both arguments 5 | are the same instance. 6 | 7 | JUnit's `assertEquals` (and similar) methods are implemented in terms of 8 | `Object#equals`. However, this is not explicitly documented, so isn't a 9 | contractual guarantee of the assertion methods. 10 | 11 | [`Objects#equals`]: https://guava.dev/releases/21.0/api/docs/com/google/common/base/Objects.html#equal-java.lang.Object-java.lang.Object- 12 | 13 | To test the implementation of an `equals` method, use 14 | [Guava's EqualsTester][javadoc], or explicitly call `equals` as part of the 15 | test. 16 | 17 | [javadoc]: https://static.javadoc.io/com.google.guava/guava-testlib/21.0/com/google/common/testing/EqualsTester.html 18 | -------------------------------------------------------------------------------- /docs/bugpattern/SelfAssignment.md: -------------------------------------------------------------------------------- 1 | The left-hand side and right-hand side of this assignment are the same. It has 2 | no effect. 3 | 4 | This also handles assignments in which the right-hand side is a call to 5 | Preconditions.checkNotNull(), which returns the variable that was checked for 6 | non-nullity. If you just intended to check that the variable is non-null, please 7 | don't assign the result to the checked variable; just call 8 | Preconditions.checkNotNull() as a bare statement. 9 | -------------------------------------------------------------------------------- /docs/bugpattern/SelfComparison.md: -------------------------------------------------------------------------------- 1 | The arguments to compareTo method are the same object, so it always returns 0. 2 | Either change the arguments to point to different objects or substitute 0. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/SelfEquals.md: -------------------------------------------------------------------------------- 1 | The arguments to equals method are the same object, so it always returns true. 2 | Either change the arguments to point to different objects or substitute true. 3 | 4 | For test cases, instead of explicitly testing equals, use 5 | [EqualsTester from Guava](https://static.javadoc.io/com.google.guava/guava-testlib/19.0/com/google/common/testing/EqualsTester.html). 6 | -------------------------------------------------------------------------------- /docs/bugpattern/ShortCircuitBoolean.md: -------------------------------------------------------------------------------- 1 | The boolean operators `&&` and `||` should almost always be used instead of `&` 2 | and `|`. 3 | 4 | If the right hand side is an expression that has side effects or is expensive to 5 | compute, `&&` and `||` will short-circuit but `&` and `|` will not, which may be 6 | surprising or cause slowness. 7 | 8 | If evaluating both operands is necessary for side effects, consider refactoring 9 | to make that explicit. For example, prefer this: 10 | 11 | ```java 12 | boolean rhs = hasSideEffects(); 13 | if (lhs && rhs) { 14 | // ... 15 | } 16 | ``` 17 | 18 | to this: 19 | 20 | ```java 21 | if (lhs & hasSideEffects()) { 22 | // ... 23 | } 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/bugpattern/SizeGreaterThanOrEqualsZero.md: -------------------------------------------------------------------------------- 1 | A standard means of checking non-emptiness of an array or collection is to test 2 | if the size of that collection is greater than 0. However, one may accidentally 3 | check if the size is greater than or equal to 0, which is always true. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/StaticAssignmentInConstructor.md: -------------------------------------------------------------------------------- 1 | Assigning to a static variable from a constructor is highly indicative of a bug, 2 | or error-prone design. 3 | 4 | Common reasons are: 5 | 6 | 1. The field simply should be an instance field, and there's a bug. 7 | 8 | 2. An attempt is being made to lazily initialize a static field. In this case, 9 | first consider whether lazy initialization is necessary: it often isn't. If 10 | it is, doing it from a constructor is very hairy: the static field could be 11 | accessed from a static method before the class is even initialized. Consider 12 | using a memoized `Supplier`. 13 | -------------------------------------------------------------------------------- /docs/bugpattern/StaticAssignmentOfThrowable.md: -------------------------------------------------------------------------------- 1 | The problem we're trying to prevent is unhelpful stack traces that don't contain 2 | information about where the Exception was thrown from. This problem can 3 | sometimes arise when an attempt is being made to cache or reuse a Throwable 4 | (often, a particular Exception). In this case, consider whether this is really 5 | is necessary: it often isn't. Could a Throwable simply be instantiated when 6 | needed? 7 | 8 | ``` {.bad} 9 | // this always has the same stack trace 10 | static final MyException MY_EXCEPTION = new MyException("something terrible has happened!"); 11 | ``` 12 | 13 | ``` {.good} 14 | throw new MyException("something terrible has happened!"); 15 | ``` 16 | 17 | ``` {.good} 18 | static MyException myException() { 19 | return new MyException("something terrible has happened!"); 20 | } 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/bugpattern/StaticMockMember.md: -------------------------------------------------------------------------------- 1 | Making a `@Mock` instance `static` will share the state across tests and can 2 | make them order dependent and/or unclear to reader/maintainer. Removing 3 | `static`, will ensure fresh mock instances are used for each tests. 4 | 5 | Additionally, if the `@Mock` instance is marked as `static` to make it 6 | serializable, there is a cleaner way to do it : 7 | https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#serilization_across_classloader 8 | and 9 | https://javadoc.io/static/org.mockito/mockito-core/3.3.3/org/mockito/Mock.html#serializable-- 10 | -------------------------------------------------------------------------------- /docs/bugpattern/StaticOrDefaultInterfaceMethod.md: -------------------------------------------------------------------------------- 1 | Static and default interface methods are not natively supported on Android 2 | versions earlier than 7.0. Enable this check for compatibility with older 3 | devices. See 4 | [Android Java 8 Documentation](https://developer.android.com/guide/platform/j8-jack.html). 5 | 6 | ## Suppression 7 | 8 | To declare default or static methods in interfaces, add a 9 | `@SuppressWarnings("StaticOrDefaultInterfaceMethod")` annotation to the 10 | enclosing element. 11 | -------------------------------------------------------------------------------- /docs/bugpattern/StreamToString.md: -------------------------------------------------------------------------------- 1 | The `toString` method on a `Stream` will print its identity, such as 2 | `java.util.stream.ReferencePipeline$Head@6d06d69c`. This is rarely what was 3 | intended. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/StringBuilderInitWithChar.md: -------------------------------------------------------------------------------- 1 | StringBuilder does not have a char constructor, so instead this code creates a 2 | StringBuilder with initial size equal to the code point of the specified char. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/StringCaseLocaleUsage.md: -------------------------------------------------------------------------------- 1 | `String.toLowerCase()` (and `toUpperCase`) without specifying a `Locale` can 2 | have surprising results. 3 | 4 | For example, if this is used on a device and the user's `Locale` is Türkiye, 5 | then `"I".toLowerCase()` will yield a lowercase dotless I ("ı"). This could be 6 | extremely dangerous if you were expecting to operate on ASCII text to generate 7 | machine-readable identifiers. 8 | 9 | If this kind of regionalisation is desired, use 10 | `.toLowerCase(Locale.getDefault())` to make that explicit. If not, 11 | `.toLowerCase(Locale.ROOT)` or `.toLowerCase(Locale.ENGLISH)` will give you 12 | casing independent of the user's current `Locale`. If you know that you're 13 | operating on ASCII, prefer `Ascii.toLower/UpperCase` to make that explicit. 14 | -------------------------------------------------------------------------------- /docs/bugpattern/SunApi.md: -------------------------------------------------------------------------------- 1 | Warn on internal, proprietary APIs that may be removed in future JDK versions. 2 | 3 | For `sun.misc.Unsafe`, note that the API will be removed from a future version 4 | of the JDK: 5 | [JEP 471: Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal](https://openjdk.org/jeps/471). 6 | 7 | This check is a re-implementation of javac's 'sunapi' diagnostic. 8 | -------------------------------------------------------------------------------- /docs/bugpattern/SuppressWarningsDeprecated.md: -------------------------------------------------------------------------------- 1 | To suppress warnings to deprecated methods, you should add the annotation 2 | `@SuppressWarnings("deprecation")` and not `@SuppressWarnings("deprecated")` 3 | -------------------------------------------------------------------------------- /docs/bugpattern/SuppressWarningsWithoutExplanation.md: -------------------------------------------------------------------------------- 1 | Suppressions for `unchecked` or `rawtypes` warnings should have an accompanying 2 | comment to explain why the javac warning is safe to ignore. 3 | 4 | Rather than just suppressing the warning: 5 | 6 | ```java 7 | @SuppressWarnings("unchecked") 8 | public ImmutableList performScaryCast(ImmutableList strings) { 9 | return (ImmutableList) (ImmutableList) strings; 10 | } 11 | ``` 12 | 13 | Provide a concise explanation for why it is safe: 14 | 15 | ```java 16 | @SuppressWarnings("unchecked") // Safe covariant cast, given ImmutableList cannot be added to. 17 | public ImmutableList performScaryCast(ImmutableList strings) { 18 | return (ImmutableList) (ImmutableList) strings; 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/bugpattern/SwigMemoryLeak.md: -------------------------------------------------------------------------------- 1 | SWIG is a tool that will automatically generate Java bindings to C++ code. It is 2 | possible to %ignore in SWIG a C++ object's destructor, this is trivially 3 | achieved when using %ignoreall and then selectively %unignore-ing an API. SWIG 4 | cleans up C++ objects using a delete method, which is most commonly called by a 5 | finalizer. When a SWIG generated delete method can't call a destructor, as it is 6 | hidden, the delete method throws an exception. However, in the case of a hidden 7 | C++ destructor SWIG also doesn't generate a finalizer, and so the most common 8 | call to the delete method is removed. The consequence of this is that the SWIG 9 | objects leak their C++ counterpart and no warnings or exceptions are thrown. 10 | 11 | This check looks for the pattern of a memory leaking SWIG generated object and 12 | warns about the potential memory leak. The most straightforward fix is to the 13 | SWIG input code to tell it not to %ignore the C++ code's destructor. 14 | -------------------------------------------------------------------------------- /docs/bugpattern/SynchronizeOnNonFinalField.md: -------------------------------------------------------------------------------- 1 | Possible fixes: 2 | 3 | * If the field is never reassigned, add the missing `final` modifier. 4 | 5 | * If the field needs to be mutable, create a separate lock by adding a private 6 | final field and synchronizing on it to guard all accesses. 7 | 8 | * If the field is lazily initialized, annotation it with 9 | `com.google.errorprone.annotations.concurrent.LazyInit`. 10 | -------------------------------------------------------------------------------- /docs/bugpattern/ThreadJoinLoop.md: -------------------------------------------------------------------------------- 1 | Thread.join() can be interrupted, and so requires users to catch 2 | InterruptedException. Most users should be looping until the join() actually 3 | succeeds. 4 | 5 | Instead of writing your own try-catch and loop to handle it properly, you may 6 | use **Uninterruptibles.joinUninterruptibly** which does the same for you. 7 | 8 | Example: 9 | 10 | ``` 11 | Thread thread = new Thread(new Runnable() {...}); 12 | 13 | Uninterruptibles.joinUninterruptibly(thread); 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/bugpattern/ThreadLocalUsage.md: -------------------------------------------------------------------------------- 1 | `ThreadLocal`s should be stored in `static` variables to avoid memory leaks. If 2 | a `ThreadLocal` is stored in an instance (non-static) variable, there will be 3 | M \* N instances of the `ThreadLocal` value where `M` is the number 4 | of threads, and `N` is the number of instances of the containing class. Each 5 | instance may remain live as long the thread that stored it stays live. 6 | 7 | Example: 8 | 9 | ```java 10 | class C { 11 | private final ThreadLocal local = new ThreadLocal(); 12 | 13 | public f() { 14 | D d = local.get(); 15 | if (d == null) { 16 | d = new D(this); 17 | local.set(d); 18 | } 19 | d.doSomething(); 20 | } 21 | } 22 | ``` 23 | 24 | The fix is often to make the field `static`: 25 | 26 | ```java 27 | private static final ThreadLocal local = new ThreadLocal(); 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/bugpattern/ThreadPriorityCheck.md: -------------------------------------------------------------------------------- 1 | Don't rely on the thread scheduler for correctness or performance. Instead, 2 | ensure that the average number of runnable threads is not significantly greater 3 | than the number of processors, i.e. by using the executor framework and an 4 | appropriately sized thread pool. 5 | 6 | For more information, see [Effective Java 3rd Edition §84][ej3e-84]. 7 | 8 | [ej3e-84]: https://books.google.com/books?id=BIpDDwAAQBAJ 9 | -------------------------------------------------------------------------------- /docs/bugpattern/ThrowIfUncheckedKnownChecked.md: -------------------------------------------------------------------------------- 1 | `throwIfUnchecked(knownCheckedException)` is a no-op (aside from performing a 2 | null check). `propagateIfPossible(knownCheckedException)` is a complete no-op. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/ThrowsUncheckedException.md: -------------------------------------------------------------------------------- 1 | [Effective Java 3rd Edition §74][ej3e-74] says: 2 | 3 | > Use the Javadoc `@throws` tag to document each exception that a method can 4 | > throw, but do *not* use the `throws` keyword on unchecked exceptions. 5 | 6 | [ej3e-74]: https://books.google.com/books?id=BIpDDwAAQBAJ 7 | -------------------------------------------------------------------------------- /docs/bugpattern/TooManyParameters.md: -------------------------------------------------------------------------------- 1 | In 2 | [*Detecting Argument Selection Defects*](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/46317.pdf) 3 | by Rice et. al., the authors argue that methods should have 5 of fewer 4 | parameters (see section 7.1). APIs with larger than this number often lead to 5 | parameter mismatch bugs (e.g, calling `create(firstName, lastName)` instead of 6 | `create(lastName, firstName)`). 7 | 8 | In *Effective Java* (Item 2), Bloch recommends "consider[ing] a builder 9 | [pattern] when faced with many [constructor] parameters". You may consider 10 | encapsulating your parameters into a single 11 | [`@AutoValue`](https://github.com/google/auto/tree/master/value) object, which 12 | is created using an 13 | [AutoValue Builder](https://github.com/google/auto/blob/master/value/userguide/builders.md). 14 | -------------------------------------------------------------------------------- /docs/bugpattern/TraditionalSwitchExpression.md: -------------------------------------------------------------------------------- 1 | The newer arrow (`->`) syntax for switches is preferred to the older colon (`:`) 2 | syntax. The main reason for continuing to use the colon syntax in switch 3 | *statements* is that it allows fall-through from one statement group to the 4 | next. But in a switch *expression*, fall-through would only be useful if the 5 | code that falls through has side effects. Burying side effects inside a switch 6 | expression makes code hard to understand. 7 | -------------------------------------------------------------------------------- /docs/bugpattern/TreeToString.md: -------------------------------------------------------------------------------- 1 | `Tree#toString` shouldn't be used for Trees deriving from the code being 2 | compiled, as it discards whitespace and comments. 3 | 4 | This check only runs inside Error Prone code. Suggested replacements include: 5 | 6 | * Prefer `VisitorState#getConstantExpression` for escaping constants in 7 | generated code. 8 | * `VisitorState#getSourceForNode` : it will give you the original source text. 9 | Note that for synthetic trees (e.g.: implicit constructors), that source may 10 | be `null`. 11 | * If the string representation was being used for comparison with keywords 12 | like `this` and `super`, try `tree.getName().contentEquals("this")` 13 | * One can also get the symbol name and use it for comparison : 14 | `ASTHelpers.getSymbol(tree).getSimpleName().toString()` 15 | -------------------------------------------------------------------------------- /docs/bugpattern/TruthAssertExpected.md: -------------------------------------------------------------------------------- 1 | Arguments to a fluent [Truth][truth] assertion appear to be reversed based on 2 | the argument names. 3 | 4 | ```java 5 | int expected = 1; 6 | assertThat(expected).isEqualTo(codeUnderTest()); 7 | ``` 8 | 9 | This is problematic as the quality of Truth's error message depends on the 10 | argument order. If `codeUnderTest()` returns `2`, this code will output: 11 | 12 | ``` 13 | expected: 2 14 | but was : 1 15 | ``` 16 | 17 | Which will likely make debugging the problem harder. Truth assertions should 18 | follow the opposite order to JUnit assertions. Compare: 19 | 20 | ```java 21 | assertThat(actual).isEqualTo(expected); 22 | assertEquals(expected, actual); 23 | ``` 24 | 25 | See https://truth.dev/faq#order for more details. 26 | 27 | [truth]: https://truth.dev 28 | -------------------------------------------------------------------------------- /docs/bugpattern/TruthConstantAsserts.md: -------------------------------------------------------------------------------- 1 | The arguments to assertThat method is a constant. It should be a variable or a 2 | method invocation. For eg. switch assertThat(1).isEqualTo(methodCall()) to 3 | assertThat(methodCall()).isEqualTo(1). 4 | -------------------------------------------------------------------------------- /docs/bugpattern/TryFailThrowable.md: -------------------------------------------------------------------------------- 1 | When testing that a line of code throws an expected exception, it is typical to 2 | execute that line in a try block with a `fail()` or `assert*()` on the line 3 | following. The expectation is that the expected exception will be thrown, and 4 | execution will continue in the catch block, and the `fail()` or `assert*()` will 5 | not be executed. 6 | 7 | `fail()` and `assert*()` throw AssertionErrors, which are a subtype of 8 | Throwable. That means that if the catch block catches Throwable, then execution 9 | will always jump to the catch block, and the test will always pass. 10 | 11 | To fix this, you usually want to catch Exception rather than Throwable. If you 12 | need to catch throwable (e.g., the expected exception is an AssertionError), 13 | then add logic in your catch block to ensure that the AssertionError that was 14 | caught is not the same one thrown by the call to `fail()` or `assert*()`. 15 | -------------------------------------------------------------------------------- /docs/bugpattern/TryWithResourcesVariable.md: -------------------------------------------------------------------------------- 1 | Starting in Java 9, the resource in a try-with-resources statement can be a 2 | reference to a `final` or effectively-`final` variable. 3 | 4 | That is, you can write this: 5 | 6 | ```java 7 | AutoCloseable resource = ...; 8 | try (resource) { 9 | doSomething(resource); 10 | } 11 | ``` 12 | 13 | instead of this: 14 | 15 | ```java 16 | AutoCloseable resource = ...; 17 | try (AutoCloseable resource2 = resource) { 18 | doSomething(resource2); 19 | } 20 | ``` 21 | 22 | NOTE: the resource cannot be an arbitrary expression, for example `try 23 | (returnsTheResources()) { ... }` is still not allowed. 24 | -------------------------------------------------------------------------------- /docs/bugpattern/TypeEquals.md: -------------------------------------------------------------------------------- 1 | [`TypeMirror`](https://docs.oracle.com/en/java/javase/11/docs/api/java.compiler/javax/lang/model/type/TypeMirror.html) 2 | doesn't override `Object.equals` and instances are not interned by javac, so 3 | testing types for equality should be done with 4 | [`Types#isSameType`](https://docs.oracle.com/en/java/javase/11/docs/api/java.compiler/javax/lang/model/util/Types.html#isSameType\(javax.lang.model.type.TypeMirror,javax.lang.model.type.TypeMirror\)) 5 | instead. 6 | 7 | If you're implementing an Error Prone `BugChecker`, you can get a `Types` 8 | instance from `VisitorState`. 9 | 10 | If you're implementing `AnnotationProcessor`, you can get the `Types` instance 11 | from `javax.annotation.processing.ProcessingEnvironment`. 12 | -------------------------------------------------------------------------------- /docs/bugpattern/TypeNameShadowing.md: -------------------------------------------------------------------------------- 1 | When declaring type parameters, it's possible to declare a type parameter with 2 | the same name as another type in scope, "shadowing" that type and potentially 3 | causing confusing or unintended behavior. 4 | 5 | ```java 6 | class Bar { 7 | ... 8 | public void doSomething(T object) { 9 | // Here, object is the static class T in this file 10 | } 11 | 12 | public void doSomethingElse(T object) { 13 | // Here, object is a generic T 14 | } 15 | ... 16 | public static class T {...} 17 | } 18 | ``` 19 | 20 | This checker warns when a type parameter shadows another type and suggests a 21 | possible renaming for the type parameter. 22 | 23 | Note, however, that in some cases it may be preferable to rename or delete the 24 | shadowed type rather than the type parameter shadowing it, such as in cases 25 | where the type parameter is always instantiated with the same type. 26 | -------------------------------------------------------------------------------- /docs/bugpattern/TypeParameterQualifier.md: -------------------------------------------------------------------------------- 1 | Using a type parameter as a qualifier in the name of a type or expression is 2 | equivalent to referencing the type parameter's upper bound directly. 3 | 4 | For example, this signature: 5 | 6 | ```java 7 | static T populate(T.Builder builder) {} 8 | ``` 9 | 10 | Is identical to the following: 11 | 12 | ```java 13 | static T populate(Message.Builder builder) {} 14 | ``` 15 | 16 | The use of `T.Builder` is unnecessary and misleading. Always refer to the type 17 | by its canonical name `Message.Builder` instead. 18 | -------------------------------------------------------------------------------- /docs/bugpattern/TypeToString.md: -------------------------------------------------------------------------------- 1 | `Type#toString` shouldn't be used for Type comparison as it is expensive and 2 | fragile. 3 | 4 | If this code is within an Error Prone check for comparing `Type`(s), there are 5 | better alternatives available. 6 | 7 | Instead of 8 | 9 | ```java 10 | type.toString().equals("com.package.SomeObject") 11 | ``` 12 | 13 | use 14 | 15 | ```java 16 | visitorState.getTypes().isSameType(type, visitorState.getTypeFromString("com.package.SomeObject")) 17 | ``` 18 | 19 | For primitive types, 20 | 21 | ```java 22 | type.getKind().equals(TypeKind.INT) 23 | ``` 24 | 25 | For object type, `java {.good} 26 | type.getKind().equals(state.getSymtab().objectType)` 27 | -------------------------------------------------------------------------------- /docs/bugpattern/URLEqualsHashCode.md: -------------------------------------------------------------------------------- 1 | The `equals` and `hashCode` methods of `java.net.URL` make blocking network 2 | calls. When you place a `URL` into a hash-based container, the container invokes 3 | those methods. 4 | 5 | Prefer `java.net.URI`. Or, if you must use `URL` in a 6 | collection, prefer to use a non-hash-based container like a `List`, and 7 | avoid calling methods like `contains` (which calls `equals`) on it. 8 | -------------------------------------------------------------------------------- /docs/bugpattern/UnicodeInCode.md: -------------------------------------------------------------------------------- 1 | Using non-ASCII Unicode characters in code can be confusing, and potentially 2 | unsafe. 3 | 4 | For example, homoglyphs can result in a different method to the one that was 5 | expected being invoked. 6 | 7 | ```java 8 | import static com.google.common.base.Objects.equal; 9 | 10 | public void isAuthenticated(String password) { 11 | // The "l" here is not what it seems. 12 | return equaⅼ(password, this.password()); 13 | } 14 | 15 | // ... 16 | 17 | private boolean equaⅼ(String a, String b) { 18 | return true; 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/bugpattern/UnnecessarilyVisible.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/error-prone/962f83aac3193dca53129e8e3b34740176bc0bde/docs/bugpattern/UnnecessarilyVisible.md -------------------------------------------------------------------------------- /docs/bugpattern/UnnecessaryAssignment.md: -------------------------------------------------------------------------------- 1 | The `@Mock` annotation is used to automatically initialize mocks using 2 | `MockitoAnnotations.initMocks`, or `MockitoJUnitRunner`. 3 | 4 | Variables annotated this way should not be explicitly initialized, as this will 5 | be overwritten by automatic initialization. 6 | -------------------------------------------------------------------------------- /docs/bugpattern/UnnecessaryBoxedAssignment.md: -------------------------------------------------------------------------------- 1 | The Java language automatically converts primitive types to their boxed 2 | representations in some contexts (see 3 | [JLS 5.1.7](https://docs.oracle.com/javase/specs/jls/se11/html/jls-5.html#jls-5.1.7)). 4 | 5 | That is, prefer this: 6 | 7 | ```java 8 | int x; 9 | Integer y = x; 10 | ``` 11 | 12 | to the equivalent but more verbose explicit conversion: 13 | 14 | ```java 15 | int x; 16 | Integer y = Integer.valueOf(x); 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/bugpattern/UnnecessaryBreakInSwitch.md: -------------------------------------------------------------------------------- 1 | The newer arrow (`->`) syntax for switches does not permit fallthrough between 2 | cases. A `break` statement is allowed to break out of the switch, but including 3 | a `break` as the last statement in a case body is unnecessary. 4 | -------------------------------------------------------------------------------- /docs/bugpattern/UnnecessaryMethodReference.md: -------------------------------------------------------------------------------- 1 | Using a method reference to refer to the abstract method of the target type is 2 | unnecessary. For example, 3 | 4 | ```java 5 | Stream filter(Stream xs, Predicate predicate) { 6 | return xs.filter(predicate::test); 7 | } 8 | ``` 9 | 10 | ```java 11 | Stream filter(Stream xs, Predicate predicate) { 12 | return xs.filter(predicate); 13 | } 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/bugpattern/UnnecessarySetDefault.md: -------------------------------------------------------------------------------- 1 | NullPointerTester comes with built-in support for some well known types like 2 | `Optional` and `ImmutableList` via guava's 3 | [`ArbitraryInstances`](https://static.javadoc.io/com.google.guava/guava-testlib/23.0/com/google/common/testing/ArbitraryInstances.html) 4 | class. Explicitly calling `setDefault` for these types is unnecessary. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/UnnecessaryStaticImport.md: -------------------------------------------------------------------------------- 1 | Using static imports for types is unnecessary, since they can always be replaced 2 | by equivalent non-static imports. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/UnnecessaryTestMethodPrefix.md: -------------------------------------------------------------------------------- 1 | Prefixing JUnit4 test methods with `test` is unnecessary and redundant given the 2 | use of the `@Test` annotation makes it clear that they're tests. 3 | -------------------------------------------------------------------------------- /docs/bugpattern/UnsafeReflectiveConstructionCast.md: -------------------------------------------------------------------------------- 1 | Prefer `asSubclass` instead of casting the result of `newInstance` to detect 2 | classes of incorrect type before invoking their constructors. This way, if the 3 | class is of the incorrect type, it will throw an exception before invoking its 4 | constructor. 5 | 6 | ```java 7 | (Foo) Class.forName(someString).getDeclaredConstructor(...).newInstance(args); 8 | ``` 9 | 10 | Should be written as 11 | 12 | ```java 13 | Class.forName(someString).asSubclass(Foo.class).getDeclaredConstructor(...).newInstance(); 14 | ``` 15 | 16 | This has caused issues in the past: 17 | 18 | CVE-2014-7911 - https://seclists.org/fulldisclosure/2014/Nov/51 19 | -------------------------------------------------------------------------------- /docs/bugpattern/UnusedAnonymousClass.md: -------------------------------------------------------------------------------- 1 | Creating a side-effect-free anonymous class and never using it is usually a 2 | mistake. 3 | 4 | For example: 5 | 6 | ```java 7 | public static void main(String[] args) { 8 | new Thread(new Runnable() { 9 | @Override public void run() { 10 | preventMissionCriticalDisasters(); 11 | } 12 | }); // did you mean to call Thread#start()? 13 | } 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/bugpattern/UnusedCollectionModifiedInPlace.md: -------------------------------------------------------------------------------- 1 | Several of the methods in `java.util.Collections`, such as `sort` and `shuffle`, 2 | modify collections in place. If you call one of these methods on a 3 | newly-allocated collection and don't use it later, you are doing unnecessary 4 | work. You probably meant to keep a reference to the newly-allocated copy of your 5 | collection and use that in the rest of your code. 6 | 7 | For example, this code sorts a new `ArrayList` and then throws away the result, 8 | returning the unsorted original collection: 9 | 10 | ```java 11 | public Collection sort(Collection foos) { 12 | Collections.sort(new ArrayList<>(foos)); 13 | return foos; 14 | } 15 | ``` 16 | 17 | The author probably meant: 18 | 19 | ```java 20 | public Collection sort(Collection foos) { 21 | List sortedFoos = new ArrayList<>(foos); 22 | Collections.sort(sortedFoos); 23 | return sortedFoos; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/bugpattern/UnusedMethod.md: -------------------------------------------------------------------------------- 1 | The presence of an unused method may indicate a bug. This check highlights 2 | _private_ methods which are unused and can be safely removed without considering 3 | the impact on other source files. 4 | 5 | ## Suppression 6 | 7 | Methods and fields which are used by reflection can be annotated with `@Keep` to 8 | suppress the warning. 9 | 10 | This annotation can also be applied to annotations, to suppress the warning for 11 | any member annotated with that annotation: 12 | 13 | ```java 14 | import com.google.errorprone.annotations.Keep; 15 | 16 | @Keep 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @interface Field {} 19 | 20 | ... 21 | 22 | public class Data { 23 | @Field private int a; // no warning. 24 | ... 25 | } 26 | ``` 27 | 28 | All false positives can be suppressed by annotating the method with 29 | `@SuppressWarnings("unused")` or prefixing its name with `unused`. 30 | -------------------------------------------------------------------------------- /docs/bugpattern/UseBinds.md: -------------------------------------------------------------------------------- 1 | A @Provides or @Produces method that returns its single parameter has long been 2 | Dagger's only mechanism for delegating a binding. Since the delegation is 3 | implemented via a user-defined method there is a disproportionate amount of 4 | overhead for such a conceptually simple operation. @Binds was introduced to 5 | provide a declarative way of delegating from one binding to another in a way 6 | that allows for minimal overhead in the implementation. @Binds should always be 7 | preferred over @Provides or @Produces for delegation. 8 | 9 | For instance, the following `@Provides` method 10 | 11 | ```java 12 | @Provides static Heater provideHeater(ElectricHeater heater) { 13 | return heater; 14 | } 15 | ``` 16 | 17 | is equivalent to the following preferred `@Binds` method. 18 | 19 | ```java 20 | @Binds abstract Heater bindHeater(ElectricHeater impl); 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/bugpattern/VarTypeName.md: -------------------------------------------------------------------------------- 1 | As of JDK 10 `var` is a restricted local variable type and cannot be used for 2 | type declarations (see [JEP 286][]). 3 | 4 | [JEP 286]: https://openjdk.java.net/jeps/286 5 | -------------------------------------------------------------------------------- /docs/bugpattern/VariableNameSameAsType.md: -------------------------------------------------------------------------------- 1 | When a field/variable name is the same as the field/variable type, it is 2 | difficult to determine which to use at which time. 3 | 4 | For example, 5 | 6 | ```java 7 | private static String String; 8 | ``` 9 | 10 | This would cause future use of String.something within this class to refer to 11 | the static field String, instead of the class String. 12 | 13 | This is worth calling out to avoid confusion and is a violation of 14 | [Google Java style naming conventions](https://google.github.io/styleguide/javaguide.html#s5.2.7-local-variable-names) 15 | 16 | Instead of this naming style, the correct way would be: 17 | 18 | ```java 19 | private static String string; 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/bugpattern/WithSignatureDiscouraged.md: -------------------------------------------------------------------------------- 1 | `withSignature` relies on the string representation of internal classes in the 2 | javac implementation. Those string representations are not necessarily stable 3 | across versions of javac, and they can change when a method is annotated with 4 | type-use annotations. 5 | 6 | Additionally, `withSignature` currently has at least one undocumented behavioral 7 | quirk. 8 | 9 | The most reasonable use case for `withSignature` is for methods that declare or 10 | use type variables, which are difficult or impossible to express with the rest 11 | of the `MethodMatchers` API. Still, where practical, prefer to write your own 12 | matching code instead of using `withSignature`. 13 | -------------------------------------------------------------------------------- /docs/bugpattern/WrongOneof.md: -------------------------------------------------------------------------------- 1 | When switching over a proto `one_of`, getters that don't match the current case 2 | are guaranteed to be return a default instance: 3 | 4 | ```java 5 | switch (foo.getBlahCase()) { 6 | case FOO: 7 | return foo.getFoo(); 8 | case BAR: 9 | return foo.getFoo(); // should be foo.getBar() 10 | } 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/bugpattern/XorPower.md: -------------------------------------------------------------------------------- 1 | The `^` binary XOR operator is sometimes mistaken for a power operator, but e.g. 2 | `2 ^ 2` evaluates to `0`, not `4`. 3 | 4 | Consider expressing powers of `2` using a bit shift instead. 5 | -------------------------------------------------------------------------------- /docs/bugpattern/android/BinderIdentityRestoredDangerously.md: -------------------------------------------------------------------------------- 1 | Binder is Android's inter-process communication mechanism. Each call to 2 | `Binder.clearCallingIdentity()` should be followed by 3 | `Binder.restoreCallingIdentity()` in a finally block. Otherwise the wrong Binder 4 | identity may be used by subsequent code. 5 | 6 | For example: `java long token = Binder.clearCallingIdentity(); // Issue a Binder 7 | call (may throw an Exception). someBinderInterface.makeCall(); 8 | Binder.restoreCallingIdentity(token);` 9 | 10 | The above code should be rewritten as: `java long token = 11 | Binder.clearCallingIdentity(); try { // Issue a Binder call (may throw an 12 | Exception). someBinderInterface.makeCall(); } finally { 13 | Binder.restoreCallingIdentity(token); }` 14 | -------------------------------------------------------------------------------- /docs/bugpattern/android/FragmentNotInstantiable.md: -------------------------------------------------------------------------------- 1 | Every subclass of `Fragment` must be public and have a public, nullary 2 | constructor. The Android framework will reflectively instantiate them after a 3 | configuration change, such as screen rotation, and if the class is not 4 | instantiable by `Class#newInstance()`, an `InstantiationException` will be 5 | thrown. 6 | 7 | In addition, it is strongly recommended that subclasses not have other 8 | constructors with parameters, since these constructors will not be called when 9 | the fragment is re-instantiated; instead, arguments should be supplied with 10 | `setArguments(Bundle)` and retrieved with `getArguments()`. 11 | 12 | For more information, please see the documentation for 13 | [Fragment](https://developer.android.com/reference/android/app/Fragment.html#Fragment\(\)). 14 | 15 | This check is an adaptation of the `ValidFragment` rule of 16 | [Android Lint](https://tools.android.com/tips/lint-checks). 17 | -------------------------------------------------------------------------------- /docs/bugpattern/android/HardCodedSdCardPath.md: -------------------------------------------------------------------------------- 1 | Your code should not reference the `/sdcard` path directly, which is 2 | platform-dependent. You should use 3 | `Environment.getExternalStorageDirectory().getPath()` instead. 4 | 5 | Similarly, do not reference the `/data/data/` path directly, as it can vary in 6 | multi-user scenarios. You should use `Context.getFilesDir().getPath()` instead. 7 | 8 | For more information, please see the documentation for 9 | [android.os.Environment](https://developer.android.com/reference/android/os/Environment.html) 10 | and 11 | [android.content.Context](https://developer.android.com/reference/android/content/Context.html). 12 | 13 | This check is an adaptation of the `SdCardPath` rule of 14 | [Android Lint](https://tools.android.com/tips/lint-checks). 15 | -------------------------------------------------------------------------------- /docs/bugpattern/flogger/FloggerLogWithCause.md: -------------------------------------------------------------------------------- 1 | When using a logger as error handling, setting the exception as the cause of the 2 | log statement will provide more context in the log message. 3 | 4 | Instead of: 5 | 6 | ```java 7 | try { 8 | ... 9 | } catch (Exception e) { 10 | logger.atWarning().log("Failed!"); 11 | } 12 | ``` 13 | 14 | Consider: 15 | 16 | ```java 17 | try { 18 | ... 19 | } catch (Exception e) { 20 | logger.atWarning().withCause(e).log("Failed!"); 21 | } 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/bugpattern/flogger/FloggerRedundantIsEnabled.md: -------------------------------------------------------------------------------- 1 | Guarding flogger log statements with an explicit log level check is redundant, 2 | since the log statement already contains the desired log level and is 3 | inexpensive to evaluate if the specified log level is disabled. 4 | 5 | This is redundant: 6 | 7 | ```java 8 | if (logger.atInfo().isEnabled()) { 9 | logger.atInfo().log(\"blah\"); 10 | } 11 | ``` 12 | 13 | If the log statement's *arguments* are expensive to evaluate, consider using 14 | lazy argument evaluation 15 | (https://google.github.io/flogger/examples#logging-with-lazy-argument-evaluation-java8): 16 | 17 | ```java 18 | logger.atFine().log(\"Value: %s\", lazy(() -> process(x, y))); 19 | ``` 20 | -------------------------------------------------------------------------------- /docs/bugpattern/flogger/FloggerWithoutCause.md: -------------------------------------------------------------------------------- 1 | Flogger uses `withCause(exception)` to associate Exceptions with log statements. 2 | Passing exceptions directly to `log()` only records the name and message, 3 | and loses the stack trace. 4 | 5 | ```java 6 | logger.atWarning().log("Unexpected exception: %s", e); 7 | ``` 8 | 9 | ```java 10 | logger.atWarning().withCause(e).log("Unexpected exception"); 11 | ``` 12 | 13 | If you intended not to log the stack trace or other parts of the exception, you 14 | should explicitly log the parts you want to keep so the intent is clear in the 15 | code: 16 | 17 | ```java 18 | // Avoid withCause() since stack traces are unnecessary here 19 | logger.atWarning().log("Unexpected exception [%s]: %s", e.getClass(), e.getMessage()); 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/bugpattern/inject/InjectOnMemberAndConstructor.md: -------------------------------------------------------------------------------- 1 | When a class uses `@Inject` on a field, and that field is also assigned from an 2 | `@Inject` constructor, then the field is assigned twice from the DI Injector. 3 | This may result in 2 objects being created, where the first instance is assigned 4 | then thrown away after the second injection. 5 | 6 | A simple solution is to remove the `@Inject` annotation from the injected field. 7 | -------------------------------------------------------------------------------- /docs/bugpattern/javadoc/AlmostJavadoc.md: -------------------------------------------------------------------------------- 1 | This comment contains Javadoc or HTML tags, and is in the right position for a 2 | Javadoc, but doesn't start with a double asterisk. Should it be a Javadoc? 3 | 4 | ```java 5 | /* Frobnicates the {@link Foo}s. */ 6 | class Frobnicator { 7 | Foo frobnicate(Foo foo); 8 | } 9 | ``` 10 | 11 | ```java 12 | /** Frobnicates the {@link Foo}s. */ 13 | class Frobnicator { 14 | Foo frobnicate(Foo foo); 15 | } 16 | ``` 17 | 18 | ## Suppression 19 | 20 | Suppress by applying `@SuppressWarnings("AlmostJavadoc")` to the element being 21 | documented (or not documented). 22 | -------------------------------------------------------------------------------- /docs/bugpattern/javadoc/EscapedEntity.md: -------------------------------------------------------------------------------- 1 | HTML entities used within `@code` and `@literal` tags will be interpreted 2 | directly rather than converted to the expected characters. For example, this is 3 | wrong: 4 | 5 | ```java 6 | /** 7 | *
{@code
 8 |  *   @Override
 9 |  *   public boolean equals(Object o) {
10 |  *     return false;
11 |  *   }
12 |  * }
13 | */ 14 | ``` 15 | 16 | An option is to drop the {@code } tags, though this will then require escaping 17 | any generic type parameters which may otherwise be interpreted as HTML. That is, 18 | `List` is the text "List" followed by the (non-existent) tag "Integer". 19 | 20 | ```java 21 | /** 22 | *
23 |  *   @Override
24 |  *   public boolean equals(Object o) {
25 |  *     return false;
26 |  *   }
27 |  * 
28 | */ 29 | ``` 30 | 31 | ## Suppression 32 | 33 | Suppress by applying `@SuppressWarnings("EscapedEntity")` to the element being 34 | documented. 35 | -------------------------------------------------------------------------------- /docs/bugpattern/javadoc/InheritDoc.md: -------------------------------------------------------------------------------- 1 | The `@inheritDoc` tag should only be used on classes/interfaces which extend or 2 | implement another and methods which override a method from a superclass. 3 | 4 | ```java 5 | class Frobnicator { 6 | /** {@inheritDoc} */ 7 | public void frobnicate() { 8 | // ... 9 | } 10 | } 11 | ``` 12 | 13 | ## Suppression 14 | 15 | Suppress by applying `@SuppressWarnings("InheritDoc")` to the element being 16 | documented. 17 | -------------------------------------------------------------------------------- /docs/bugpattern/javadoc/InvalidParam.md: -------------------------------------------------------------------------------- 1 | Javadoc's `@param` tag should not be used to document parameters which do not 2 | appear in the formal parameter list. This may indicate a typo, or an omission 3 | when refactoring. 4 | 5 | ```java 6 | /** 7 | * Parses {@code input} as a proto. 8 | * 9 | * @param inputBytes input bytes to parse. 10 | */ 11 | MyProto parse(byte[] input) { 12 | ... 13 | } 14 | ``` 15 | 16 | ## Suppression 17 | 18 | Suppress by applying `@SuppressWarnings("InvalidParam")` to the element being 19 | documented. 20 | -------------------------------------------------------------------------------- /docs/bugpattern/javadoc/InvalidThrows.md: -------------------------------------------------------------------------------- 1 | The `@throws` tag should not document a checked exception which is not actually 2 | thrown by the documented method. 3 | 4 | ```java 5 | /** 6 | * Validates {@code n}. 7 | * 8 | * @throws Exception if n is negative. 9 | */ 10 | void validate(int n) { 11 | ... 12 | } 13 | ``` 14 | 15 | ## Suppression 16 | 17 | Suppress by applying `@SuppressWarnings("InvalidThrows")` to the element being 18 | documented. 19 | -------------------------------------------------------------------------------- /docs/bugpattern/javadoc/InvalidThrowsLink.md: -------------------------------------------------------------------------------- 1 | `@throws` does not require `@link`ing the target exception. 2 | 3 | ```java 4 | /** 5 | * Validates {@code n}. 6 | * 7 | * @throws {@link Exception} if n is negative. 8 | */ 9 | void validate(int n) throws Exception { 10 | ... 11 | } 12 | ``` 13 | 14 | ```java 15 | /** 16 | * Validates {@code n}. 17 | * 18 | * @throws Exception if n is negative. 19 | */ 20 | void validate(int n) throws Exception { 21 | ... 22 | } 23 | ``` 24 | 25 | ## Suppression 26 | 27 | Suppress by applying `@SuppressWarnings("InvalidThrowsLink")` to the element 28 | being documented. 29 | -------------------------------------------------------------------------------- /docs/bugpattern/javadoc/MalformedInlineTag.md: -------------------------------------------------------------------------------- 1 | This error is triggered by a malformed inline tag, anywhere @{tag appears 2 | instead of {@tag inside a Javadoc comment. See [javadoc documentation][javadoc] 3 | for more explanation on the use of inline tags. 4 | 5 | [javadoc]: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javadoc.html#CHDJGIJB 6 | 7 | ## Suppression 8 | 9 | Suppress by applying `@SuppressWarnings("MalformedInlineTag")` to the element 10 | being documented. 11 | -------------------------------------------------------------------------------- /docs/bugpattern/javadoc/MissingSummary.md: -------------------------------------------------------------------------------- 1 | Javadocs on private and protected elements are required to contain a short 2 | summary line. This is often the only part of the Javadoc that others will see 3 | surfaced in various tools. 4 | 5 | ```java 6 | /** @return deserialised proto */ 7 | public Proto parse(byte[] bytes) { 8 | ... 9 | } 10 | ``` 11 | 12 | ```java 13 | /** Returns deserialised proto. */ 14 | public Proto parse(byte[] bytes) { 15 | ... 16 | } 17 | ``` 18 | 19 | ## Suppression 20 | 21 | Suppress by applying `@SuppressWarnings("MissingSummary")` to the element being 22 | documented. 23 | -------------------------------------------------------------------------------- /docs/bugpattern/javadoc/ReturnFromVoid.md: -------------------------------------------------------------------------------- 1 | Methods which do not return anything should not have a `@return` tag. 2 | 3 | ```java 4 | /** 5 | * Frobnicates. 6 | * 7 | * @return a frobnicator 8 | */ 9 | void frobnicator(int a) { 10 | ... 11 | } 12 | ``` 13 | 14 | ## Suppression 15 | 16 | Suppress by applying `@SuppressWarnings("ReturnFromVoid")` to the element being 17 | documented. 18 | -------------------------------------------------------------------------------- /docs/bugpattern/time/StronglyTypeTime.md: -------------------------------------------------------------------------------- 1 | Where possible, `java.time.Duration` fields should be strongly typed rather than 2 | stored as integral primitives and converted at the usage site. 3 | 4 | For example, rather than: 5 | 6 | ```java 7 | public class X { 8 | private static final long TIMEOUT = 100; 9 | 10 | // later in the file 11 | use(Duration.ofMillis(TIMEOUT)); 12 | } 13 | ``` 14 | 15 | Prefer: 16 | 17 | ```java 18 | public class X { 19 | private static final Duration TIMEOUT = Duration.ofMillis(100); 20 | 21 | // later in the file 22 | use(TIMEOUT); 23 | } 24 | ``` 25 | -------------------------------------------------------------------------------- /examples/plugin/bazel/java/com/google/errorprone/sample/BUILD: -------------------------------------------------------------------------------- 1 | java_plugin( 2 | name = "MyCustomCheckPlugin", 3 | srcs = ["MyCustomCheck.java"], 4 | deps = [ 5 | "@error_prone//jar", 6 | "@guava//jar", 7 | "//third_party/java/auto_service", 8 | ], 9 | ) 10 | 11 | java_library( 12 | name = "Hello", 13 | srcs = ["Hello.java"], 14 | plugins = [":MyCustomCheckPlugin"], 15 | ) 16 | -------------------------------------------------------------------------------- /examples/plugin/bazel/third_party/java/auto_service/BUILD: -------------------------------------------------------------------------------- 1 | licenses(["notice"]) # Apache License 2.0 2 | 3 | java_library( 4 | name = "auto_service", 5 | exported_plugins = [":auto_service_plugin"], 6 | visibility = ["//visibility:public"], 7 | exports = ["@auto_service//jar"], 8 | runtime_deps = ["@guava//jar"], 9 | ) 10 | 11 | java_plugin( 12 | name = "auto_service_plugin", 13 | processor_class = "com.google.auto.service.processor.AutoServiceProcessor", 14 | deps = [ 15 | "@auto_common//jar", 16 | "@auto_service//jar", 17 | "@guava//jar", 18 | ], 19 | ) 20 | --------------------------------------------------------------------------------