Commit c9b8d61b by Jamie Madill Committed by Commit Bot

Update Android-releated tools DEPS.

Include the tools/android/errorprone_plugin mirror. This eliminates several cloned source files from ANGLE. Also include the Python tools/swarming_client for running tests. It seems like the tests depend on the logdog Python library available from this component. Bug: angleproject:2344 Change-Id: I70e011764c4443ab3904bfa0c9059f295f3817df Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2845233Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 9fbe5c00
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
/third_party/vulkan-deps /third_party/vulkan-deps
/third_party/vulkan_memory_allocator /third_party/vulkan_memory_allocator
/third_party/zlib /third_party/zlib
/tools/android/errorprone_plugin
/tools/clang /tools/clang
/tools/flex-bison/linux/bison /tools/flex-bison/linux/bison
/tools/flex-bison/linux/flex /tools/flex-bison/linux/flex
...@@ -84,6 +85,7 @@ ...@@ -84,6 +85,7 @@
/tools/memory /tools/memory
/tools/protoc_wrapper /tools/protoc_wrapper
/tools/skia_goldctl /tools/skia_goldctl
/tools/swarming_client
angle_debug.txt angle_debug.txt
build build
buildtools/ buildtools/
......
...@@ -503,6 +503,11 @@ deps = { ...@@ -503,6 +503,11 @@ deps = {
'condition': 'not build_with_chromium', 'condition': 'not build_with_chromium',
}, },
'tools/android/errorprone_plugin': {
'url': '{chromium_git}/chromium/src/tools/android/errorprone_plugin@e81dcab66095e6eec2cde2f76720b9a82c96d793',
'condition': 'checkout_android and not build_with_chromium',
},
'tools/clang': { 'tools/clang': {
'url': '{chromium_git}/chromium/src/tools/clang.git@7a6a1f2ea2593e9308910f58bb82a54dac351b71', 'url': '{chromium_git}/chromium/src/tools/clang.git@7a6a1f2ea2593e9308910f58bb82a54dac351b71',
'condition': 'not build_with_chromium', 'condition': 'not build_with_chromium',
...@@ -591,6 +596,11 @@ deps = { ...@@ -591,6 +596,11 @@ deps = {
'condition': 'checkout_mac and not build_with_chromium', 'condition': 'checkout_mac and not build_with_chromium',
}, },
'tools/swarming_client': {
'url': '{chromium_git}/infra/luci/client-py.git@a32a1607f6093d338f756c7e7c7b4333b0c50c9c',
'condition': 'checkout_android and not build_with_chromium',
},
# === ANGLE Restricted Trace Generated Code Start === # === ANGLE Restricted Trace Generated Code Start ===
'src/tests/restricted_traces/aliexpress': { 'src/tests/restricted_traces/aliexpress': {
'packages': [ 'packages': [
......
...@@ -70,6 +70,7 @@ ANGLE_CHROMIUM_DEPS = [ ...@@ -70,6 +70,7 @@ ANGLE_CHROMIUM_DEPS = [
'third_party/r8', 'third_party/r8',
'third_party/turbine', 'third_party/turbine',
'third_party/zlib', 'third_party/zlib',
'tools/android/errorprone_plugin',
'tools/clang', 'tools/clang',
'tools/clang/dsymutil', 'tools/clang/dsymutil',
'tools/luci-go', 'tools/luci-go',
...@@ -80,6 +81,7 @@ ANGLE_CHROMIUM_DEPS = [ ...@@ -80,6 +81,7 @@ ANGLE_CHROMIUM_DEPS = [
'tools/skia_goldctl/linux', 'tools/skia_goldctl/linux',
'tools/skia_goldctl/mac', 'tools/skia_goldctl/mac',
'tools/skia_goldctl/win', 'tools/skia_goldctl/win',
'tools/swarming_client',
] ]
ANGLE_URL = 'https://chromium.googlesource.com/angle/angle' ANGLE_URL = 'https://chromium.googlesource.com/angle/angle'
......
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/rules.gni")
java_binary("errorprone_plugin") {
# main_class and wrapper script are not actually used.
# This target is referenced directly from java_library_impl().
main_class = "<ignore>"
wrapper_script_name = "bin/helper/errorprone_plugin"
sources = [
# Turned off because of existing code which fails the check
# "src/org/chromium/tools/errorprone/plugin/NoContextGetApplicationContext.java",
"src/org/chromium/tools/errorprone/plugin/AndroidNullableCheck.java",
"src/org/chromium/tools/errorprone/plugin/NoAndroidAsyncTaskCheck.java",
"src/org/chromium/tools/errorprone/plugin/NoDynamicStringsInTraceEventCheck.java",
"src/org/chromium/tools/errorprone/plugin/NoRedundantFieldInitCheck.java",
"src/org/chromium/tools/errorprone/plugin/NoSynchronizedMethodCheck.java",
"src/org/chromium/tools/errorprone/plugin/NoSynchronizedThisCheck.java",
"src/org/chromium/tools/errorprone/plugin/TestClassNameCheck.java",
]
# Necessary to avoid dependency cycle
enable_errorprone = false
enable_bytecode_checks = false
annotation_processor_deps =
[ "//third_party/android_deps:auto_service_processor" ]
deps = [
"//third_party/android_deps:com_google_auto_service_auto_service_annotations_java",
"//third_party/android_deps:com_google_errorprone_error_prone_annotation_java",
"//third_party/android_deps:com_google_errorprone_error_prone_check_api_java",
"//third_party/android_deps:com_google_errorprone_error_prone_core_java",
"//third_party/android_deps:com_google_errorprone_javac_java",
]
}
agrieve@chromium.org
nyquist@chromium.org
wnwen@chromium.org
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.tools.errorprone.plugin;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.matchers.Matchers;
import com.sun.source.tree.AnnotationTree;
/**
* Assert androidx.annotation.Nullable is used instead of javax.annotation.Nullable.
*/
@AutoService(BugChecker.class)
@BugPattern(name = "AndroidNullableCheck",
summary = "Use androidx.annotation.Nullable instead of javax.annotation.Nullable.",
severity = BugPattern.SeverityLevel.ERROR, linkType = BugPattern.LinkType.CUSTOM,
link = "http://crbug.com/771683")
public class AndroidNullableCheck extends BugChecker implements BugChecker.AnnotationTreeMatcher
{
static final Matcher<AnnotationTree> IS_JAVAX_NULLABLE =
Matchers.anyOf(Matchers.isType("javax.annotation.Nullable"));
/**
* Match if nullable annotation is of type javax.annotation.Nullable.
*/
@Override
public Description matchAnnotation(AnnotationTree annotationTree, VisitorState visitorState)
{
if (IS_JAVAX_NULLABLE.matches(annotationTree, visitorState))
{
return describeMatch(annotationTree);
}
return Description.NO_MATCH;
}
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.tools.errorprone.plugin;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.MemberSelectTree;
import com.sun.tools.javac.code.Symbol;
/**
* Triggers an error for any occurrence of android.os.AsyncTask.
*/
@AutoService(BugChecker.class)
@BugPattern(name = "NoAndroidAsyncTaskCheck",
summary = "Do not use android.os.AsyncTask - use org.chromium.base.task.AsyncTask instead",
severity = BugPattern.SeverityLevel.ERROR, linkType = BugPattern.LinkType.CUSTOM,
link = "https://bugs.chromium.org/p/chromium/issues/detail?id=843745")
public class NoAndroidAsyncTaskCheck
extends BugChecker implements BugChecker.MemberSelectTreeMatcher
{
@Override
public Description matchMemberSelect(MemberSelectTree tree, VisitorState state)
{
if (tree.getIdentifier().contentEquals("AsyncTask"))
{
Symbol symbol = ASTHelpers.getSymbol(tree.getExpression());
if (symbol.getQualifiedName().contentEquals("android.os"))
{
return buildDescription(tree)
.setMessage("Do not use android.os.AsyncTask - "
+ "use org.chromium.base.task.AsyncTask instead")
.build();
}
}
return Description.NO_MATCH;
}
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.tools.errorprone.plugin;
import static com.google.errorprone.matchers.Matchers.instanceMethod;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.suppliers.Supplier;
import com.google.errorprone.suppliers.Suppliers;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.tools.javac.code.Type;
/**
* Checks for calls to getApplicationContext from {@link android.content.Context}.
* These calls should be replaced with the static getApplicationContext method in
* {@link org.chromium.base.ContextUtils}.
*/
@AutoService(BugChecker.class)
@BugPattern(name = "NoContextGetApplicationContext",
summary = "Do not use Context#getApplicationContext",
severity = BugPattern.SeverityLevel.ERROR, linkType = BugPattern.LinkType.CUSTOM,
link = "https://bugs.chromium.org/p/chromium/issues/detail?id=560466")
public class NoContextGetApplicationContext
extends BugChecker implements BugChecker.MethodInvocationTreeMatcher
{
private static final String CONTEXT_CLASS_NAME = "android.content.Context";
private static final String CONTEXT_UTILS_CLASS_NAME = "org.chromium.base.ContextUtils";
private static final String METHOD_NAME = "getApplicationContext";
private static final Supplier<Type> CONTEXT_UTILS_SUPPLIER =
Suppliers.typeFromString(CONTEXT_UTILS_CLASS_NAME);
private static final Matcher<ExpressionTree> CONTEXT_MATCHER =
instanceMethod()
.onDescendantOf(Suppliers.typeFromString(CONTEXT_CLASS_NAME))
.named(METHOD_NAME);
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState visitorState)
{
if (!CONTEXT_MATCHER.matches(tree, visitorState))
{
return Description.NO_MATCH;
}
// If ContextUtils can't be loaded, we are probably inside a third_party lib and shouldn't
// check for errors.
boolean canLoadContextUtils = CONTEXT_UTILS_SUPPLIER.get(visitorState) != null;
if (!canLoadContextUtils)
{
return Description.NO_MATCH;
}
return buildDescription(tree)
.setMessage("Don't use Context#getApplicationContext - "
+ "call ContextUtils.getApplicationContext instead")
.build();
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.tools.errorprone.plugin;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.LiteralTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.SimpleTreeVisitor;
import com.sun.tools.javac.code.Symbol;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
/**
* Triggers an error for {@link org.chromium.base.TraceEvent} usages with non string literals.
*/
@AutoService(BugChecker.class)
@BugPattern(name = "NoDynamicStringsInTraceEventCheck",
summary = "Only use of string literals are allowed in trace events.",
severity = BugPattern.SeverityLevel.ERROR, linkType = BugPattern.LinkType.CUSTOM,
link = "https://crbug.com/984827")
public class NoDynamicStringsInTraceEventCheck
extends BugChecker implements BugChecker.MethodInvocationTreeMatcher
{
private static final Set<String> sTracingFunctions = new HashSet<>(Arrays.asList(
"begin", "end", "scoped", "startAsync", "finishAsync", "instant", "TraceEvent"));
private static final ParameterVisitor sVisitor = new ParameterVisitor();
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState visitorState)
{
Symbol.MethodSymbol method = ASTHelpers.getSymbol(tree);
if (!sTracingFunctions.contains(method.name.toString())) return Description.NO_MATCH;
String className = method.enclClass().fullname.toString();
if (!"org.chromium.base.EarlyTraceEvent".equals(className)
&& !"org.chromium.base.TraceEvent".equals(className))
{
return Description.NO_MATCH;
}
// Allow the events added by tracing. Adding SuppressWarning in these files causes all
// caller warnings to be ignored.
String filename = visitorState.getPath().getCompilationUnit().getSourceFile().getName();
if (filename.endsWith("TraceEvent.java"))
{
return Description.NO_MATCH;
}
List<? extends Tree> args = tree.getArguments();
Tree eventName_expr = args.get(0);
ParameterVisitor.Result r = eventName_expr.accept(sVisitor, null);
if (r.success) return Description.NO_MATCH;
return buildDescription(tree)
.setMessage("Calling TraceEvent.begin() without a constant String object. "
+ r.errorMessage)
.build();
}
static class ParameterVisitor extends SimpleTreeVisitor<ParameterVisitor.Result, Void>
{
static class Result
{
public boolean success;
public String errorMessage;
private Result(boolean successVal, String error)
{
success = successVal;
errorMessage = error;
}
public static Result createError(String error)
{
return new Result(false, error);
}
public static Result createOk()
{
return new Result(true, null);
}
public Result append(Result other)
{
success &= other.success;
if (errorMessage == null)
{
errorMessage = other.errorMessage;
}
else if (other.errorMessage != null)
{
errorMessage += " " + other.errorMessage;
}
return this;
}
};
@Override
protected Result defaultAction(Tree tree, Void p)
{
throw new RuntimeException("Unhandled expression tree type: " + tree.getKind());
}
@Override
public Result visitBinary(BinaryTree tree, Void p)
{
return tree.getLeftOperand()
.accept(this, null)
.append(tree.getRightOperand().accept(this, null));
}
@Override
public Result visitLiteral(LiteralTree tree, Void p)
{
return Result.createOk();
}
@Override
public Result visitIdentifier(IdentifierTree node, Void p)
{
Symbol eventName = ASTHelpers.getSymbol(node);
if (eventName == null)
{
return Result.createError("Identifier was not found: " + node + '.');
}
if (eventName.getKind() == ElementKind.FIELD)
{
if (!"java.lang.String".equals(eventName.type.toString()))
{
return Result.createError("Field: " + eventName + " should be of type string.");
}
Set<Modifier> modifiers = eventName.getModifiers();
if (!modifiers.contains(Modifier.FINAL) || !modifiers.contains(Modifier.STATIC))
{
return Result.createError(
"String literal: " + eventName + " is not static final.");
}
return Result.createOk();
}
else if (eventName.getKind() == ElementKind.PARAMETER)
{
return Result.createError(
"Passing in event name as parameter: " + eventName + " is not supported.");
}
return Result.createError("Unhandled identifier kind: " + node.getKind() + '.');
}
};
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.tools.errorprone.plugin;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.matchers.Matchers;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.LiteralTree;
import com.sun.source.tree.ModifiersTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.VariableTree;
import com.sun.tools.javac.code.Symbol;
import javax.lang.model.element.Modifier;
/**
* Detects when non-final fields are explicitly initialized to default values
*/
@AutoService(BugChecker.class)
@BugPattern(name = "NoRedundantFieldInit",
summary = "Do not explicitly initialize a non-final field with a default value",
severity = BugPattern.SeverityLevel.ERROR, linkType = BugPattern.LinkType.CUSTOM,
link = "https://issuetracker.google.com/issues/37124982")
public class NoRedundantFieldInitCheck extends BugChecker implements BugChecker.VariableTreeMatcher
{
private static final Matcher<ClassTree> SUBTYPE_OF_IINTERFACE =
Matchers.isSubtypeOf("android.os.IInterface");
@Override
public Description matchVariable(VariableTree variableTree, VisitorState visitorState)
{
// Only match on fields.
if (!Matchers.isField().matches(variableTree, visitorState))
{
return Description.NO_MATCH;
}
Symbol.VarSymbol variableSymbol = ASTHelpers.getSymbol(variableTree);
Symbol.ClassSymbol enclosingClass = ASTHelpers.enclosingClass(variableSymbol);
// Temporarily turn off checks if the enclosing class is a subclass of IInterface.
if (SUBTYPE_OF_IINTERFACE.matches(
ASTHelpers.findClass(enclosingClass, visitorState), visitorState))
{
return Description.NO_MATCH;
}
// Skip fields that are final.
ModifiersTree modifiers = variableTree.getModifiers();
if (modifiers.getFlags().contains(Modifier.FINAL))
{
return Description.NO_MATCH;
}
// Skip fields in an @interface / any annotation type since these
// are implicitly final.
if (enclosingClass.isAnnotationType())
{
return Description.NO_MATCH;
}
// Fields in interfaces are also final implicitly so skip those.
if (enclosingClass.isInterface())
{
return Description.NO_MATCH;
}
// Check if field declaration is initialized to a literal default value.
if (isInitializedWithDefaultValue(variableTree))
{
// Generate fix string from original source e.g.
// public static int x = 0; --> public static int x;.
String source = visitorState.getSourceForNode(variableTree);
String suggestedSource = source.substring(0, source.indexOf('=')).trim() + ";";
return describeMatch(variableTree, SuggestedFix.replace(variableTree, suggestedSource));
}
return Description.NO_MATCH;
}
private boolean isInitializedWithDefaultValue(VariableTree variableTree)
{
ExpressionTree initializer = variableTree.getInitializer();
// Only match on literals.
if (!(initializer instanceof LiteralTree))
{
return false;
}
// Match on declarations with literal initializers that have default values.
if (variableTree.getType().getKind() == Tree.Kind.PRIMITIVE_TYPE)
{
LiteralTree literal = (LiteralTree) initializer;
if (literal.getKind() == Tree.Kind.BOOLEAN_LITERAL)
{
if (!(boolean) literal.getValue())
{
return true;
}
}
else if (literal.getKind() == Tree.Kind.LONG_LITERAL)
{
if ((long) literal.getValue() == 0L)
{
return true;
}
}
else if (literal.getKind() == Tree.Kind.CHAR_LITERAL)
{
if ((char) literal.getValue() == '\u0000')
{
return true;
}
}
else if (literal.getKind() == Tree.Kind.DOUBLE_LITERAL)
{
if ((double) literal.getValue() == 0.0d)
{
return true;
}
}
else if (literal.getKind() == Tree.Kind.FLOAT_LITERAL)
{
if ((float) literal.getValue() == 0.0f)
{
return true;
}
}
else if ((int) literal.getValue() == 0)
{
// Int/short/byte.
return true;
}
}
else if (initializer.getKind() == Tree.Kind.NULL_LITERAL)
{
// Non-primitive type default value is null.
return true;
}
return false;
}
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.tools.errorprone.plugin;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.fixes.SuggestedFixes;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.MethodTree;
import com.sun.tools.javac.code.Symbol;
import javax.lang.model.element.Modifier;
/**
* Triggers an error for public methods that use "synchronized" in their signature.
*/
@AutoService(BugChecker.class)
@BugPattern(name = "NoSynchronizedMethodCheck",
summary = "Use of synchronized in public method signature disallowed.",
severity = BugPattern.SeverityLevel.ERROR, linkType = BugPattern.LinkType.CUSTOM,
link = "https://stackoverflow.com/questions/20906548/why-is-synchronized-block-better-than-synchronized-method")
public class NoSynchronizedMethodCheck extends BugChecker implements BugChecker.MethodTreeMatcher
{
@Override
public Description matchMethod(MethodTree methodTree, VisitorState visitorState)
{
Symbol.MethodSymbol method = ASTHelpers.getSymbol(methodTree);
// Skip methods that aren't synchronized and non-public methods
if (!method.getModifiers().contains(Modifier.SYNCHRONIZED)
|| !method.getModifiers().contains(Modifier.PUBLIC))
{
return Description.NO_MATCH;
}
// Skip methods that are only public due to VisibleForTesting
if (ASTHelpers.hasDirectAnnotationWithSimpleName(method, "VisibleForTesting"))
{
return Description.NO_MATCH;
}
// A Synchronized @Override methods is unavoidable if the method being overridden is
// an Android API method (Example: Exception#fillInStackTrace()).
if (ASTHelpers.hasDirectAnnotationWithSimpleName(method, "Override"))
{
return Description.NO_MATCH;
}
// Skip non-public classes
Symbol.ClassSymbol enclosingClass = ASTHelpers.enclosingClass(method);
if (!enclosingClass.getModifiers().contains(Modifier.PUBLIC))
{
return Description.NO_MATCH;
}
return buildDescription(methodTree)
.addFix(SuggestedFixes.removeModifiers(
methodTree, visitorState, Modifier.SYNCHRONIZED))
.setMessage(String.format(
"Used synchronized modifier in public method %s", method.getSimpleName()))
.build();
}
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.tools.errorprone.plugin;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.SynchronizedTree;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeInfo;
import javax.lang.model.element.Modifier;
/**
* This class detects the synchronized method.
*/
@AutoService(BugChecker.class)
@BugPattern(name = "NoSynchronizedThisCheck",
summary = "Do not synchronized on 'this' in public classes",
severity = BugPattern.SeverityLevel.ERROR, linkType = BugPattern.LinkType.CUSTOM,
link = "https://stackoverflow.com/questions/442564/avoid-synchronizedthis-in-java")
public class NoSynchronizedThisCheck
extends BugChecker implements BugChecker.SynchronizedTreeMatcher
{
@Override
public Description matchSynchronized(SynchronizedTree tree, VisitorState visitorState)
{
Symbol lock = ASTHelpers.getSymbol(TreeInfo.skipParens((JCTree) tree.getExpression()));
// Skip locks that are not 'this'
if (!lock.getSimpleName().contentEquals("this"))
{
return Description.NO_MATCH;
}
// Skip non-public classes
Symbol.ClassSymbol enclosingClass = ASTHelpers.enclosingClass(lock);
if (!enclosingClass.getModifiers().contains(Modifier.PUBLIC))
{
return Description.NO_MATCH;
}
return buildDescription(tree)
.setMessage("Used instance variable as synchronization lock")
.build();
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.tools.errorprone.plugin;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.matchers.Matchers;
import com.sun.source.tree.AnnotationTree;
/**
* Assert class names of classes with Java tests in them end with "Test".
*
* Test classes are identified as those that are annotated with {@link org.junit.runner.RunWith}.
* This works for both JUnit and Instrumentation tests.
*/
@AutoService(BugChecker.class)
@BugPattern(name = "TestClassNameCheck",
summary = "Class names of classes with tests in them should end with \"Test\".",
severity = BugPattern.SeverityLevel.ERROR, linkType = BugPattern.LinkType.CUSTOM,
link = "http://crbug.com/1029370")
public class TestClassNameCheck extends BugChecker implements BugChecker.AnnotationTreeMatcher
{
static final Matcher<AnnotationTree> TEST_ANNOTATION =
Matchers.anyOf(Matchers.isType("org.junit.runner.RunWith"));
/**
* Match if nullable annotation is of type org.junit.runner.RunWith.
*/
@Override
public Description matchAnnotation(AnnotationTree annotationTree, VisitorState visitorState)
{
String filePath = visitorState.getPath().getCompilationUnit().getSourceFile().getName();
if (TEST_ANNOTATION.matches(annotationTree, visitorState)
&& !filePath.endsWith("Test.java"))
{
return describeMatch(annotationTree);
}
return Description.NO_MATCH;
}
}
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/android_nocompile.gni")
import("nocompile_gn/nocompile_sources.gni")
android_nocompile_test_suite("errorprone_plugin_tests") {
# Depend on errorprone_plugin so that the action is re-run whenever any custom
# errorprone check is modified.
deps = [ "//tools/android/errorprone_plugin" ]
tests = [
{
target = "nocompile_gn:no_redundant_field_init_check_int_test_java"
nocompile_sources =
rebase_path(no_redundant_field_init_check_int_test_nocompile_sources,
"",
"nocompile_gn")
expected_compile_output_regex = "warning: .NoRedundantFieldInit"
},
{
target = "nocompile_gn:test_class_name_check_test_java"
nocompile_sources =
rebase_path(test_class_name_check_test_nocompile_sources,
"",
"nocompile_gn")
expected_compile_output_regex = "warning: .TestClassNameCheck"
},
]
}
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/android_nocompile.gni")
import("//build/config/android/rules.gni")
import("nocompile_sources.gni")
empty_java = "../src/org/chromium/tools/errorprone/plugin/Empty.java"
android_library("no_redundant_field_init_check_int_test_java") {
testonly = true
enable_errorprone = true
sources = [ empty_java ]
if (enable_android_nocompile_tests) {
sources += no_redundant_field_init_check_int_test_nocompile_sources
skip_build_server = true
}
}
android_library("test_class_name_check_test_java") {
testonly = true
enable_errorprone = true
sources = [ empty_java ]
if (enable_android_nocompile_tests) {
sources += test_class_name_check_test_nocompile_sources
skip_build_server = true
}
deps = [
"//base:base_java_test_support",
"//third_party/android_support_test_runner:runner_java",
"//third_party/junit:junit",
]
}
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
no_redundant_field_init_check_int_test_nocompile_sources = [ "../src/org/chromium/tools/errorprone/plugin/NoRedundantFieldInitCheckIntTest.java" ]
test_class_name_check_test_nocompile_sources = [
"../src/org/chromium/tools/errorprone/plugin/TestClassNameCheckTesting.java",
]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.tools.errorprone.plugin;
/**
* Empty class.
*/
public class Empty
{}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.tools.errorprone.plugin;
/**
* |mBar| initialization should cause 'NoRedundantFieldInitCheck' errorprone warning.
*/
public class NoRedundantFieldInitCheckIntTest
{
private int mBar = 0;
public void foo()
{
System.out.println("" + mBar);
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.tools.errorprone.plugin;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.BaseJUnit4ClassRunner;
/**
* Should cause 'TestClassNameCheck' errorprone warning.
*/
@RunWith(BaseJUnit4ClassRunner.class)
public class TestClassNameCheckTesting
{
@Test
public void testRandom()
{}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment