use of org.jetbrains.uast.UAnonymousClass in project kotlin by JetBrains.
the class FragmentDetector method checkClass.
@Override
public void checkClass(@NonNull JavaContext context, @NonNull UClass node) {
if (node instanceof UAnonymousClass) {
String message = "Fragments should be static such that they can be re-instantiated by " + "the system, and anonymous classes are not static";
context.reportUast(ISSUE, node, context.getUastNameLocation(node), message);
return;
}
JavaEvaluator evaluator = context.getEvaluator();
if (evaluator.isAbstract(node)) {
return;
}
if (!evaluator.isPublic(node)) {
String message = String.format("This fragment class should be public (%1$s)", node.getQualifiedName());
context.reportUast(ISSUE, node, context.getUastNameLocation(node), message);
return;
}
if (node.getContainingClass() != null && !evaluator.isStatic(node)) {
String message = String.format("This fragment inner class should be static (%1$s)", node.getQualifiedName());
context.reportUast(ISSUE, node, context.getUastNameLocation(node), message);
return;
}
boolean hasDefaultConstructor = false;
boolean hasConstructor = false;
for (PsiMethod constructor : node.getConstructors()) {
hasConstructor = true;
if (constructor.getParameterList().getParametersCount() == 0) {
if (evaluator.isPublic(constructor)) {
hasDefaultConstructor = true;
} else {
Location location = context.getNameLocation(constructor);
context.report(ISSUE, constructor, location, "The default constructor must be public");
// Also mark that we have a constructor so we don't complain again
// below since we've already emitted a more specific error related
// to the default constructor
hasDefaultConstructor = true;
}
} else {
Location location = context.getNameLocation(constructor);
// TODO: Use separate issue for this which isn't an error
String message = "Avoid non-default constructors in fragments: " + "use a default constructor plus " + "`Fragment#setArguments(Bundle)` instead";
context.report(ISSUE, constructor, location, message);
}
}
if (!hasDefaultConstructor && hasConstructor) {
String message = String.format("This fragment should provide a default constructor (a public " + "constructor with no arguments) (`%1$s`)", node.getQualifiedName());
context.reportUast(ISSUE, node, context.getNameLocation(node), message);
}
}
use of org.jetbrains.uast.UAnonymousClass in project kotlin by JetBrains.
the class HandlerDetector method checkClass.
@Override
public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
// Only consider static inner classes
if (context.getEvaluator().isStatic(declaration)) {
return;
}
boolean isAnonymous = declaration instanceof UAnonymousClass;
if (declaration.getContainingClass() == null && !isAnonymous) {
return;
}
//// Only flag handlers using the default looper
//noinspection unchecked
UCallExpression invocation = UastUtils.getParentOfType(declaration, UObjectLiteralExpression.class, true, UMethod.class);
if (invocation != null) {
if (isAnonymous && invocation.getValueArgumentCount() > 0) {
for (UExpression expression : invocation.getValueArguments()) {
PsiType type = expression.getExpressionType();
if (type instanceof PsiClassType && LOOPER_CLS.equals(type.getCanonicalText())) {
return;
}
}
}
} else if (hasLooperConstructorParameter(declaration)) {
// possibly used correctly from elsewhere
return;
}
Location location = context.getUastNameLocation(declaration);
String name;
if (isAnonymous) {
name = "anonymous " + ((UAnonymousClass) declaration).getBaseClassReference().getQualifiedName();
} else {
name = declaration.getQualifiedName();
}
//noinspection VariableNotUsedInsideIf
context.reportUast(ISSUE, declaration, location, String.format("This Handler class should be static or leaks might occur (%1$s)", name));
}
use of org.jetbrains.uast.UAnonymousClass in project kotlin by JetBrains.
the class ParcelDetector method checkClass.
@Override
public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
if (declaration instanceof UAnonymousClass) {
// Anonymous classes aren't parcelable
return;
}
// Only applies to concrete classes
if (declaration.isInterface()) {
return;
}
if (declaration.hasModifierProperty(PsiModifier.ABSTRACT)) {
return;
}
// Parceling spans is handled in TextUtils#CHAR_SEQUENCE_CREATOR
if (InheritanceUtil.isInheritor(declaration, false, "android.text.ParcelableSpan")) {
return;
}
PsiField field = declaration.findFieldByName("CREATOR", false);
if (field == null) {
Location location = context.getUastNameLocation(declaration);
context.reportUast(ISSUE, declaration, location, "This class implements `Parcelable` but does not " + "provide a `CREATOR` field");
}
}
Aggregations