
com.android.tools.lint.checks.AppCompatCallDetector Maven / Gradle / Ivy
/*
* Copyright (C) 2014 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.android.tools.lint.checks;
import static com.android.SdkConstants.APPCOMPAT_LIB_ARTIFACT;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.tools.lint.client.api.JavaParser;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Context;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Implementation;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.JavaContext;
import com.android.tools.lint.detector.api.Scope;
import com.android.tools.lint.detector.api.Severity;
import com.android.tools.lint.detector.api.Speed;
import java.util.Arrays;
import java.util.List;
import lombok.ast.AstVisitor;
import lombok.ast.MethodInvocation;
public class AppCompatCallDetector extends Detector implements Detector.JavaScanner {
public static final Issue ISSUE = Issue.create(
"AppCompatMethod",
"Using Wrong AppCompat Method",
"Finds cases where a custom `appcompat` method should be used instead",
"When using the appcompat library, there are some methods you should be calling " +
"instead of the normal ones; for example, `getSupportActionBar()` instead of " +
"`getActionBar()`. This lint check looks for calls to the wrong method.",
Category.CORRECTNESS, 6, Severity.WARNING,
new Implementation(
AppCompatCallDetector.class,
Scope.JAVA_FILE_SCOPE)).
addMoreInfo("http://developer.android.com/tools/support-library/index.html");
private static final String GET_ACTION_BAR = "getActionBar";
private static final String START_ACTION_MODE = "startActionMode";
private static final String SET_PROGRESS_BAR_VIS = "setProgressBarVisibility";
private static final String SET_PROGRESS_BAR_IN_VIS = "setProgressBarIndeterminateVisibility";
private static final String SET_PROGRESS_BAR_INDETERMINATE = "setProgressBarIndeterminate";
private static final String REQUEST_WINDOW_FEATURE = "requestWindowFeature";
private boolean mDependsOnAppCompat;
public AppCompatCallDetector() {
}
@NonNull
@Override
public Speed getSpeed() {
return Speed.NORMAL;
}
@Override
public void beforeCheckProject(@NonNull Context context) {
Boolean dependsOnAppCompat = context.getProject().dependsOn(APPCOMPAT_LIB_ARTIFACT);
mDependsOnAppCompat = dependsOnAppCompat != null && dependsOnAppCompat;
}
@Nullable
@Override
public List getApplicableMethodNames() {
return Arrays.asList(
GET_ACTION_BAR,
START_ACTION_MODE,
SET_PROGRESS_BAR_VIS,
SET_PROGRESS_BAR_IN_VIS,
SET_PROGRESS_BAR_INDETERMINATE,
REQUEST_WINDOW_FEATURE);
}
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable AstVisitor visitor,
@NonNull MethodInvocation node) {
if (mDependsOnAppCompat && isAppBarActivityCall(context, node)) {
String name = node.astName().astValue();
String replace = null;
if (GET_ACTION_BAR.equals(name)) {
replace = "getSupportActionBar";
} else if (START_ACTION_MODE.equals(name)) {
replace = "startSupportActionMode";
} else if (SET_PROGRESS_BAR_VIS.equals(name)) {
replace = "setSupportProgressBarVisibility";
} else if (SET_PROGRESS_BAR_IN_VIS.equals(name)) {
replace = "setSupportProgressBarIndeterminateVisibility";
} else if (SET_PROGRESS_BAR_INDETERMINATE.equals(name)) {
replace = "setSupportProgressBarIndeterminate";
} else if (REQUEST_WINDOW_FEATURE.equals(name)) {
replace = "supportRequestWindowFeature";
}
if (replace != null) {
String message = String.format("Should use %1$s instead of %2$s name",
replace, name);
context.report(ISSUE, node, context.getLocation(node), message, null);
}
}
}
private static boolean isAppBarActivityCall(@NonNull JavaContext context,
@NonNull MethodInvocation node) {
JavaParser.ResolvedNode resolved = context.resolve(node);
if (resolved instanceof JavaParser.ResolvedMethod) {
JavaParser.ResolvedMethod method = (JavaParser.ResolvedMethod) resolved;
JavaParser.ResolvedClass containingClass = method.getContainingClass();
if (containingClass.isSubclassOf("android.app.Activity", false)) {
return true;
}
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy