tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

errorprone.py (10143B)


      1 #!/usr/bin/env python3
      2 #
      3 # Copyright 2025 The Chromium Authors
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 """Run Error Prone."""
      7 
      8 import argparse
      9 import sys
     10 
     11 import compile_java
     12 from util import server_utils
     13 
     14 # Add a check here to cause the suggested fix to be applied while compiling.
     15 # Use this when trying to enable more checks.
     16 ERRORPRONE_CHECKS_TO_APPLY = []
     17 
     18 # Checks to disable in tests.
     19 TESTONLY_ERRORPRONE_WARNINGS_TO_DISABLE = [
     20    # Too much effort to enable.
     21    'UnusedVariable',
     22    # These are allowed in tests.
     23    'NoStreams',
     24 ]
     25 
     26 # Full list of checks: https://errorprone.info/bugpatterns
     27 ERRORPRONE_WARNINGS_TO_DISABLE = [
     28    'InlineMeInliner',
     29    'InlineMeSuggester',
     30    # High priority to enable:
     31    'HidingField',
     32    'AlreadyChecked',
     33    'DirectInvocationOnMock',
     34    'MockNotUsedInProduction',
     35    'PatternMatchingInstanceof',
     36    'AssignmentExpression',
     37    'RuleNotRun',
     38    # High priority to enable in non-tests:
     39    'JdkObsolete',
     40    'ReturnValueIgnored',
     41    'StaticAssignmentInConstructor',
     42    # These are all for Javadoc, which we don't really care about.
     43    # vvv
     44    'InvalidBlockTag',
     45    'InvalidParam',
     46    'InvalidLink',
     47    'InvalidInlineTag',
     48    'MalformedInlineTag',
     49    'MissingSummary',
     50    'UnescapedEntity',
     51    'UnrecognisedJavadocTag',
     52    # ^^^
     53    'MutablePublicArray',
     54    'NonCanonicalType',
     55    'DoNotClaimAnnotations',
     56    'JavaUtilDate',
     57    'IdentityHashMapUsage',
     58    'StaticMockMember',
     59    # Triggers in tests where this is useful to do.
     60    'StaticAssignmentOfThrowable',
     61    # TODO(crbug.com/41384349): Follow steps in bug.
     62    'CatchAndPrintStackTrace',
     63    # TODO(crbug.com/41364806): Follow steps in bug.
     64    'TypeParameterUnusedInFormals',
     65    # Android platform default is always UTF-8.
     66    # https://developer.android.com/reference/java/nio/charset/Charset.html#defaultCharset()
     67    'DefaultCharset',
     68    # There are lots of times when we just want to post a task.
     69    'FutureReturnValueIgnored',
     70    # Just false positives in our code.
     71    'ThreadJoinLoop',
     72    # Low priority corner cases with String.split.
     73    # Linking Guava and using Splitter was rejected
     74    # in the https://chromium-review.googlesource.com/c/chromium/src/+/871630.
     75    'StringSplitter',
     76    # Preferred to use another method since it propagates exceptions better.
     77    'ClassNewInstance',
     78    # Results in false positives.
     79    'ThreadLocalUsage',
     80    # Low priority.
     81    'EqualsHashCode',
     82    # Not necessary for tests.
     83    'OverrideThrowableToString',
     84    # Not that useful.
     85    'UnsafeReflectiveConstructionCast',
     86    # Not that useful.
     87    'MixedMutabilityReturnType',
     88    # Nice to have.
     89    'EqualsGetClass',
     90    # A lot of false-positives from CharSequence.equals().
     91    'UndefinedEquals',
     92    # Dagger generated code triggers this.
     93    'SameNameButDifferent',
     94    # Does not apply to Android because it assumes no desugaring.
     95    'UnnecessaryLambda',
     96    # Nice to have.
     97    'EmptyCatch',
     98    # Nice to have.
     99    'BadImport',
    100    # Nice to have.
    101    'UseCorrectAssertInTests',
    102    # Must be off since we are now passing in annotation processor generated
    103    # code as a source jar (deduplicating work with turbine).
    104    'RefersToDaggerCodegen',
    105    # We already have presubmit checks for this. We don't want it to fail
    106    # local compiles.
    107    'RemoveUnusedImports',
    108    # Only has false positives (would not want to enable this).
    109    'UnicodeEscape',
    110    # A lot of existing violations. e.g. Should return List and not ArrayList
    111    'NonApiType',
    112    # Nice to have.
    113    'StringCharset',
    114    # Nice to have.
    115    'StringConcatToTextBlock',
    116    # Nice to have.
    117    'StringCaseLocaleUsage',
    118    # Low priority.
    119    'RedundantControlFlow',
    120    # Low priority.
    121    'StatementSwitchToExpressionSwitch',
    122 ]
    123 
    124 # Full list of checks: https://errorprone.info/bugpatterns
    125 # Only those marked as "experimental" need to be listed here in order to be
    126 # enabled.
    127 ERRORPRONE_WARNINGS_TO_ENABLE = [
    128    'BinderIdentityRestoredDangerously',
    129    'EmptyIf',
    130    'EqualsBrokenForNull',
    131    'InvalidThrows',
    132    'LongLiteralLowerCaseSuffix',
    133    'MultiVariableDeclaration',
    134    'RedundantOverride',
    135    'StaticQualifiedUsingExpression',
    136    'TimeUnitMismatch',
    137    'UnnecessaryStaticImport',
    138    'UseBinds',
    139    'WildcardImport',
    140    'NoStreams',
    141 ]
    142 
    143 
    144 def main():
    145  parser = argparse.ArgumentParser()
    146  parser.add_argument('--skip-build-server',
    147                      action='store_true',
    148                      help='Avoid using the build server.')
    149  parser.add_argument('--use-build-server',
    150                      action='store_true',
    151                      help='Always use the build server.')
    152  parser.add_argument('--testonly',
    153                      action='store_true',
    154                      help='Disable some Error Prone checks')
    155  parser.add_argument('--enable-nullaway',
    156                      action='store_true',
    157                      help='Enable NullAway (requires --enable-errorprone)')
    158  parser.add_argument('--stamp',
    159                      required=True,
    160                      help='Path of output .stamp file')
    161  options, compile_java_argv = parser.parse_known_args()
    162 
    163  compile_java_argv += ['--jar-path', options.stamp]
    164 
    165  # Use the build server for errorprone runs.
    166  if not options.skip_build_server and (server_utils.MaybeRunCommand(
    167      name=options.stamp,
    168      argv=sys.argv,
    169      stamp_file=options.stamp,
    170      use_build_server=options.use_build_server)):
    171    compile_java.main(compile_java_argv, write_depfile_only=True)
    172    return
    173 
    174  # All errorprone args are passed space-separated in a single arg.
    175  errorprone_flags = ['-Xplugin:ErrorProne']
    176 
    177  if options.enable_nullaway:
    178    # See: https://github.com/uber/NullAway/wiki/Configuration
    179    # Check nullability only for classes marked with @NullMarked (this is our
    180    # migration story).
    181    errorprone_flags += ['-XepOpt:NullAway:OnlyNullMarked']
    182    errorprone_flags += [
    183        '-XepOpt:NullAway:CustomContractAnnotations='
    184        'org.chromium.build.annotations.Contract,'
    185        'org.chromium.support_lib_boundary.util.Contract'
    186    ]
    187    # TODO(agrieve): Re-enable once this is fixed:
    188    #     https://github.com/uber/NullAway/issues/1104
    189    # errorprone_flags += ['-XepOpt:NullAway:CheckContracts=true']
    190 
    191    # Make it a warning to use assumeNonNull() with a @NonNull.
    192    errorprone_flags += [('-XepOpt:NullAway:CastToNonNullMethod='
    193                          'org.chromium.build.NullUtil.assumeNonNull')]
    194    # Detect "assert foo != null" as a null check.
    195    errorprone_flags += ['-XepOpt:NullAway:AssertsEnabled=true']
    196    # Do not ignore @Nullable & @NonNull in non-@NullMarked classes.
    197    errorprone_flags += [
    198        '-XepOpt:NullAway:AcknowledgeRestrictiveAnnotations=true'
    199    ]
    200    # Treat @RecentlyNullable the same as @Nullable.
    201    errorprone_flags += ['-XepOpt:Nullaway:AcknowledgeAndroidRecent=true']
    202    # Enable experimental checking of @Nullable generics.
    203    # https://github.com/uber/NullAway/wiki/JSpecify-Support
    204    errorprone_flags += ['-XepOpt:NullAway:JSpecifyMode=true']
    205    # Treat these the same as constructors.
    206    init_methods = [
    207        'android.app.Application.onCreate',
    208        'android.app.Activity.onCreate',
    209        'android.app.Service.onCreate',
    210        'android.app.backup.BackupAgent.onCreate',
    211        'android.content.ContentProvider.attachInfo',
    212        'android.content.ContentProvider.onCreate',
    213        'android.content.ContextWrapper.attachBaseContext',
    214        'androidx.preference.PreferenceFragmentCompat.onCreatePreferences',
    215    ]
    216    errorprone_flags += [
    217        '-XepOpt:NullAway:KnownInitializers=' + ','.join(init_methods)
    218    ]
    219 
    220  # Make everything a warning so that when treat_warnings_as_errors is false,
    221  # they do not fail the build.
    222  errorprone_flags += ['-XepAllErrorsAsWarnings']
    223  # Don't check generated files (those tagged with @Generated).
    224  errorprone_flags += ['-XepDisableWarningsInGeneratedCode']
    225  errorprone_flags.extend('-Xep:{}:OFF'.format(x)
    226                          for x in ERRORPRONE_WARNINGS_TO_DISABLE)
    227  errorprone_flags.extend('-Xep:{}:WARN'.format(x)
    228                          for x in ERRORPRONE_WARNINGS_TO_ENABLE)
    229  if options.testonly:
    230    errorprone_flags.extend('-Xep:{}:OFF'.format(x)
    231                            for x in TESTONLY_ERRORPRONE_WARNINGS_TO_DISABLE)
    232 
    233  if ERRORPRONE_CHECKS_TO_APPLY:
    234    to_apply = list(ERRORPRONE_CHECKS_TO_APPLY)
    235    if options.testonly:
    236      to_apply = [
    237          x for x in to_apply
    238          if x not in TESTONLY_ERRORPRONE_WARNINGS_TO_DISABLE
    239      ]
    240    errorprone_flags += [
    241        '-XepPatchLocation:IN_PLACE', '-XepPatchChecks:,' + ','.join(to_apply)
    242    ]
    243 
    244  # These are required to use JDK 16, and are taken directly from
    245  # https://errorprone.info/docs/installation
    246  javac_args = [
    247      '-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED',
    248      '-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED',
    249      '-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED',
    250      '-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED',
    251      '-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED',
    252      '-J--add-exports=jdk.compiler/com.sun.tools.javac.processing='
    253      'ALL-UNNAMED',
    254      '-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',
    255      '-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED',
    256      '-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',
    257      '-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED',
    258  ]
    259 
    260  javac_args += ['-XDcompilePolicy=simple', ' '.join(errorprone_flags)]
    261 
    262  javac_args += ['-XDshould-stop.ifError=FLOW']
    263  # This flag quits errorprone after checks and before code generation, since
    264  # we do not need errorprone outputs, this speeds up errorprone by 4 seconds
    265  # for chrome_java.
    266  if not ERRORPRONE_CHECKS_TO_APPLY:
    267    javac_args += ['-XDshould-stop.ifNoError=FLOW']
    268 
    269  compile_java.main(compile_java_argv,
    270                    extra_javac_args=javac_args,
    271                    use_errorprone=True)
    272 
    273 
    274 if __name__ == '__main__':
    275  main()