Merge "Add custom Error Prone check for SDK comparisons." into rvc-dev am: 559130df3f
Change-Id: Iee4382de5aa1c27010427b9af68550b0ff8120ca
This commit is contained in:
25
errorprone/Android.bp
Normal file
25
errorprone/Android.bp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
java_plugin {
|
||||||
|
name: "error_prone_android_framework",
|
||||||
|
|
||||||
|
static_libs: [
|
||||||
|
"error_prone_android_framework_lib",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_library_host {
|
||||||
|
name: "error_prone_android_framework_lib",
|
||||||
|
|
||||||
|
srcs: ["java/**/*.java"],
|
||||||
|
|
||||||
|
static_libs: [
|
||||||
|
"//external/error_prone:error_prone_core",
|
||||||
|
"//external/dagger2:dagger2-auto-service",
|
||||||
|
],
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
"//external/dagger2:dagger2-auto-service",
|
||||||
|
],
|
||||||
|
|
||||||
|
javacflags: ["-verbose"],
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.errorprone.bugpatterns.android;
|
||||||
|
|
||||||
|
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
|
||||||
|
import static com.google.errorprone.matchers.Matchers.allOf;
|
||||||
|
import static com.google.errorprone.matchers.Matchers.anyOf;
|
||||||
|
import static com.google.errorprone.matchers.Matchers.anything;
|
||||||
|
import static com.google.errorprone.matchers.Matchers.kindIs;
|
||||||
|
|
||||||
|
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.bugpatterns.BugChecker.BinaryTreeMatcher;
|
||||||
|
import com.google.errorprone.matchers.Description;
|
||||||
|
import com.google.errorprone.matchers.FieldMatchers;
|
||||||
|
import com.google.errorprone.matchers.Matcher;
|
||||||
|
import com.sun.source.tree.BinaryTree;
|
||||||
|
import com.sun.source.tree.ExpressionTree;
|
||||||
|
import com.sun.source.tree.Tree.Kind;
|
||||||
|
|
||||||
|
@AutoService(BugChecker.class)
|
||||||
|
@BugPattern(
|
||||||
|
name = "AndroidFrameworkTargetSdk",
|
||||||
|
summary = "Verifies that all target SDK comparisons are sane",
|
||||||
|
severity = WARNING)
|
||||||
|
public final class TargetSdkChecker extends BugChecker implements BinaryTreeMatcher {
|
||||||
|
private static final Matcher<ExpressionTree> VERSION_CODE = FieldMatchers
|
||||||
|
.anyFieldInClass("android.os.Build.VERSION_CODES");
|
||||||
|
|
||||||
|
private static final Matcher<BinaryTree> INVALID_OLD_BEHAVIOR = anyOf(
|
||||||
|
allOf(kindIs(Kind.LESS_THAN_EQUAL), binaryTreeExact(anything(), VERSION_CODE)),
|
||||||
|
allOf(kindIs(Kind.GREATER_THAN_EQUAL), binaryTreeExact(VERSION_CODE, anything())));
|
||||||
|
|
||||||
|
private static final Matcher<BinaryTree> INVALID_NEW_BEHAVIOR = anyOf(
|
||||||
|
allOf(kindIs(Kind.GREATER_THAN), binaryTreeExact(anything(), VERSION_CODE)),
|
||||||
|
allOf(kindIs(Kind.LESS_THAN), binaryTreeExact(VERSION_CODE, anything())));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Description matchBinary(BinaryTree tree, VisitorState state) {
|
||||||
|
if (INVALID_OLD_BEHAVIOR.matches(tree, state)) {
|
||||||
|
return buildDescription(tree)
|
||||||
|
.setMessage("Legacy behaviors must be written in style "
|
||||||
|
+ "'targetSdk < Build.VERSION_CODES.Z'")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
if (INVALID_NEW_BEHAVIOR.matches(tree, state)) {
|
||||||
|
return buildDescription(tree)
|
||||||
|
.setMessage("Modern behaviors must be written in style "
|
||||||
|
+ "'targetSdk >= Build.VERSION_CODES.Z'")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
return Description.NO_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Matcher<BinaryTree> binaryTreeExact(Matcher<ExpressionTree> left,
|
||||||
|
Matcher<ExpressionTree> right) {
|
||||||
|
return new Matcher<BinaryTree>() {
|
||||||
|
@Override
|
||||||
|
public boolean matches(BinaryTree tree, VisitorState state) {
|
||||||
|
return left.matches(tree.getLeftOperand(), state)
|
||||||
|
&& right.matches(tree.getRightOperand(), state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 The Error Prone Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.errorprone.matchers;
|
||||||
|
|
||||||
|
import com.google.errorprone.VisitorState;
|
||||||
|
import com.google.errorprone.util.ASTHelpers;
|
||||||
|
import com.sun.source.tree.ExpressionTree;
|
||||||
|
import com.sun.source.tree.ImportTree;
|
||||||
|
import com.sun.tools.javac.code.Symbol;
|
||||||
|
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
// TODO(glorioso): this likely wants to be a fluent interface like MethodMatchers.
|
||||||
|
// Ex: [staticField()|instanceField()]
|
||||||
|
// .[onClass(String)|onAnyClass|onClassMatching]
|
||||||
|
// .[named(String)|withAnyName|withNameMatching]
|
||||||
|
/** Static utility methods for creating {@link Matcher}s for detecting references to fields. */
|
||||||
|
public final class FieldMatchers {
|
||||||
|
private FieldMatchers() {}
|
||||||
|
|
||||||
|
public static Matcher<ExpressionTree> anyFieldInClass(String className) {
|
||||||
|
return new FieldReferenceMatcher() {
|
||||||
|
@Override
|
||||||
|
boolean classIsAppropriate(ClassSymbol classSymbol) {
|
||||||
|
return classSymbol.getQualifiedName().contentEquals(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean fieldSymbolIsAppropriate(Symbol symbol) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Matcher<ExpressionTree> staticField(String className, String fieldName) {
|
||||||
|
return new FieldReferenceMatcher() {
|
||||||
|
@Override
|
||||||
|
boolean classIsAppropriate(ClassSymbol classSymbol) {
|
||||||
|
return classSymbol.getQualifiedName().contentEquals(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean fieldSymbolIsAppropriate(Symbol symbol) {
|
||||||
|
return symbol.isStatic() && symbol.getSimpleName().contentEquals(fieldName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Matcher<ExpressionTree> instanceField(String className, String fieldName) {
|
||||||
|
return new FieldReferenceMatcher() {
|
||||||
|
@Override
|
||||||
|
boolean classIsAppropriate(ClassSymbol classSymbol) {
|
||||||
|
return classSymbol.getQualifiedName().contentEquals(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean fieldSymbolIsAppropriate(Symbol symbol) {
|
||||||
|
return !symbol.isStatic() && symbol.getSimpleName().contentEquals(fieldName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract static class FieldReferenceMatcher implements Matcher<ExpressionTree> {
|
||||||
|
@Override
|
||||||
|
public boolean matches(ExpressionTree expressionTree, VisitorState state) {
|
||||||
|
return isSymbolFieldInAppropriateClass(ASTHelpers.getSymbol(expressionTree))
|
||||||
|
// Don't match if this is part of a static import tree, since they will get the finding
|
||||||
|
// on any usage of the field in their source.
|
||||||
|
&& ASTHelpers.findEnclosingNode(state.getPath(), ImportTree.class) == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSymbolFieldInAppropriateClass(@Nullable Symbol symbol) {
|
||||||
|
if (symbol == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return symbol.getKind().isField()
|
||||||
|
&& fieldSymbolIsAppropriate(symbol)
|
||||||
|
&& classIsAppropriate(symbol.owner.enclClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract boolean fieldSymbolIsAppropriate(Symbol symbol);
|
||||||
|
|
||||||
|
abstract boolean classIsAppropriate(ClassSymbol classSymbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,10 @@
|
|||||||
|
java_defaults {
|
||||||
|
name: "services_defaults",
|
||||||
|
plugins: [
|
||||||
|
"error_prone_android_framework",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
filegroup {
|
filegroup {
|
||||||
name: "services-main-sources",
|
name: "services-main-sources",
|
||||||
srcs: ["java/**/*.java"],
|
srcs: ["java/**/*.java"],
|
||||||
@@ -83,7 +90,6 @@ java_library {
|
|||||||
|
|
||||||
// Uncomment to enable output of certain warnings (deprecated, unchecked)
|
// Uncomment to enable output of certain warnings (deprecated, unchecked)
|
||||||
//javacflags: ["-Xlint"],
|
//javacflags: ["-Xlint"],
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// native library
|
// native library
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.accessibility",
|
name: "services.accessibility",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.accessibility-sources"],
|
srcs: [":services.accessibility-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.appprediction",
|
name: "services.appprediction",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.appprediction-sources"],
|
srcs: [":services.appprediction-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.appwidget",
|
name: "services.appwidget",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.appwidget-sources"],
|
srcs: [":services.appwidget-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.autofill",
|
name: "services.autofill",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.autofill-sources"],
|
srcs: [":services.autofill-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.backup",
|
name: "services.backup",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.backup-sources"],
|
srcs: [":services.backup-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
static_libs: ["backuplib"],
|
static_libs: ["backuplib"],
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.companion",
|
name: "services.companion",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.companion-sources"],
|
srcs: [":services.companion-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.contentcapture",
|
name: "services.contentcapture",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.contentcapture-sources"],
|
srcs: [":services.contentcapture-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.contentsuggestions",
|
name: "services.contentsuggestions",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.contentsuggestions-sources"],
|
srcs: [":services.contentsuggestions-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ java_genrule {
|
|||||||
|
|
||||||
java_library {
|
java_library {
|
||||||
name: "services.core",
|
name: "services.core",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
static_libs: ["services.core.priorityboosted"],
|
static_libs: ["services.core.priorityboosted"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.coverage",
|
name: "services.coverage",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.coverage-sources"],
|
srcs: [":services.coverage-sources"],
|
||||||
libs: ["jacocoagent"],
|
libs: ["jacocoagent"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.devicepolicy",
|
name: "services.devicepolicy",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.devicepolicy-sources"],
|
srcs: [":services.devicepolicy-sources"],
|
||||||
|
|
||||||
libs: [
|
libs: [
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.midi",
|
name: "services.midi",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.midi-sources"],
|
srcs: [":services.midi-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.net",
|
name: "services.net",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [
|
srcs: [
|
||||||
":net-module-utils-srcs",
|
":net-module-utils-srcs",
|
||||||
":services.net-sources",
|
":services.net-sources",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.people",
|
name: "services.people",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: ["java/**/*.java"],
|
srcs: ["java/**/*.java"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.print",
|
name: "services.print",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.print-sources"],
|
srcs: [":services.print-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.restrictions",
|
name: "services.restrictions",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.restrictions-sources"],
|
srcs: [":services.restrictions-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.startop",
|
name: "services.startop",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
|
|
||||||
static_libs: [
|
static_libs: [
|
||||||
// frameworks/base/startop/iorap
|
// frameworks/base/startop/iorap
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.systemcaptions",
|
name: "services.systemcaptions",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.systemcaptions-sources"],
|
srcs: [":services.systemcaptions-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.usage",
|
name: "services.usage",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.usage-sources"],
|
srcs: [":services.usage-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.usb",
|
name: "services.usb",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.usb-sources"],
|
srcs: [":services.usb-sources"],
|
||||||
|
|
||||||
libs: [
|
libs: [
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.voiceinteraction",
|
name: "services.voiceinteraction",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [":services.voiceinteraction-sources"],
|
srcs: [":services.voiceinteraction-sources"],
|
||||||
libs: ["services.core"],
|
libs: ["services.core"],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ filegroup {
|
|||||||
|
|
||||||
java_library_static {
|
java_library_static {
|
||||||
name: "services.wifi",
|
name: "services.wifi",
|
||||||
|
defaults: ["services_defaults"],
|
||||||
srcs: [
|
srcs: [
|
||||||
":services.wifi-sources",
|
":services.wifi-sources",
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user