Uast: Add Uast visitor extensions instead of additional checkers
This commit is contained in:
+3
-3
@@ -17,7 +17,7 @@
|
||||
package com.android.tools.klint.client.api;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.UastAdditionalChecker;
|
||||
import org.jetbrains.uast.UastVisitorExtension;
|
||||
import org.jetbrains.uast.UastConverter;
|
||||
import org.jetbrains.uast.java.JavaUastLanguagePlugin;
|
||||
|
||||
@@ -32,7 +32,7 @@ public class JavaLintLanguageExtension extends LintLanguageExtension {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<UastAdditionalChecker> getAdditionalCheckers() {
|
||||
return JavaUastLanguagePlugin.INSTANCE.getAdditionalCheckers();
|
||||
public List<UastVisitorExtension> getVisitorExtensions() {
|
||||
return JavaUastLanguagePlugin.INSTANCE.getVisitorExtensions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,14 +44,12 @@ import com.sun.istack.internal.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastChecker;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.java.JavaUastCallKinds;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.*;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.uast.UClass;
|
||||
import org.jetbrains.uast.UElement;
|
||||
import org.jetbrains.uast.UFunction;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
+2
-2
@@ -39,9 +39,9 @@ import org.jetbrains.uast.UElement;
|
||||
import org.jetbrains.uast.UQualifiedExpression;
|
||||
import org.jetbrains.uast.USimpleReferenceExpression;
|
||||
import org.jetbrains.uast.UastUtils;
|
||||
import org.jetbrains.uast.check.UastAndroidUtils;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.w3c.dom.Attr;
|
||||
|
||||
@@ -203,7 +203,7 @@ public class AlwaysShowActionDetector extends ResourceXmlDetector implements Uas
|
||||
return new FieldAccessChecker(context);
|
||||
}
|
||||
|
||||
private class FieldAccessChecker extends UastVisitor {
|
||||
private class FieldAccessChecker extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
|
||||
public FieldAccessChecker(UastAndroidContext context) {
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.java.JavaUastCallKinds;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,7 @@ public class AnnotationDetector extends Detector implements UastScanner {
|
||||
return new AnnotationChecker(context);
|
||||
}
|
||||
|
||||
private static class AnnotationChecker extends UastVisitor {
|
||||
private static class AnnotationChecker extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
|
||||
public AnnotationChecker(UastAndroidContext context) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.android.tools.klint.detector.api.*
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.check.UastAndroidContext
|
||||
import org.jetbrains.uast.check.UastScanner
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
import java.util.*
|
||||
|
||||
@@ -55,7 +56,7 @@ open class ApiDetector : Detector(), UastScanner {
|
||||
return ApiVersionVisitor(context)
|
||||
}
|
||||
|
||||
private inner class ApiVersionVisitor(val context: UastAndroidContext) : UastVisitor() {
|
||||
private inner class ApiVersionVisitor(val context: UastAndroidContext) : AbstractUastVisitor() {
|
||||
private var mMinApi = -1
|
||||
|
||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.java.JavaUAssertExpression;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
|
||||
import static org.jetbrains.uast.UastLiteralUtils.isNullLiteral;
|
||||
@@ -81,7 +82,7 @@ public class AssertDetector extends Detector implements UastScanner {
|
||||
|
||||
@Override
|
||||
public UastVisitor createUastVisitor(final UastAndroidContext context) {
|
||||
return new UastVisitor() {
|
||||
return new AbstractUastVisitor() {
|
||||
@Override
|
||||
public boolean visitCallExpression(@NotNull UCallExpression node) {
|
||||
if (!(node instanceof JavaUAssertExpression)) {
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
|
||||
/**
|
||||
@@ -84,7 +85,7 @@ public class CallSuperDetector extends Detector implements UastScanner {
|
||||
|
||||
@Override
|
||||
public UastVisitor createUastVisitor(final UastAndroidContext context) {
|
||||
return new UastVisitor() {
|
||||
return new AbstractUastVisitor() {
|
||||
@Override
|
||||
public boolean visitFunction(@NotNull UFunction node) {
|
||||
checkCallSuper(context, node);
|
||||
@@ -166,7 +167,7 @@ public class CallSuperDetector extends Detector implements UastScanner {
|
||||
}
|
||||
|
||||
/** Visits a method and determines whether the method calls its super method */
|
||||
private static class SuperCallVisitor extends UastVisitor {
|
||||
private static class SuperCallVisitor extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
private final String mMethodContainingClassFqName;
|
||||
private final String mMethodName;
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
|
||||
/**
|
||||
* Checks for missing {@code recycle} calls on resources that encourage it, and
|
||||
@@ -455,7 +455,7 @@ public class CleanupDetector extends Detector implements UastScanner {
|
||||
* case of a TypedArray we're looking for a "recycle", call, in the
|
||||
* case of a database cursor we're looking for a "close" call, etc.
|
||||
*/
|
||||
private abstract static class FinishVisitor extends UastVisitor {
|
||||
private abstract static class FinishVisitor extends AbstractUastVisitor {
|
||||
protected final UastAndroidContext mContext;
|
||||
protected final List<UVariable> mVariables;
|
||||
private boolean mContainsCleanup;
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
|
||||
/**
|
||||
* Detector looking for cut & paste issues
|
||||
@@ -182,7 +182,7 @@ public class CutPasteDetector extends Detector implements UastScanner {
|
||||
return visitor.isReachable();
|
||||
}
|
||||
|
||||
private static class ReachableVisitor extends UastVisitor {
|
||||
private static class ReachableVisitor extends AbstractUastVisitor {
|
||||
@NonNull private final UCallExpression mFrom;
|
||||
@NonNull private final UCallExpression mTo;
|
||||
private boolean mReachable;
|
||||
|
||||
@@ -73,6 +73,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
@@ -1975,7 +1976,7 @@ public class IconDetector extends ResourceXmlDetector implements UastScanner {
|
||||
return new NotificationFinder(context);
|
||||
}
|
||||
|
||||
private final class NotificationFinder extends UastVisitor {
|
||||
private final class NotificationFinder extends AbstractUastVisitor {
|
||||
private UastAndroidContext mContext;
|
||||
|
||||
public NotificationFinder(UastAndroidContext mContext) {
|
||||
@@ -2066,7 +2067,7 @@ public class IconDetector extends ResourceXmlDetector implements UastScanner {
|
||||
return false;
|
||||
}
|
||||
|
||||
private final class SetIconFinder extends UastVisitor {
|
||||
private final class SetIconFinder extends AbstractUastVisitor {
|
||||
@Override
|
||||
public boolean visitCallExpression(@NotNull UCallExpression node) {
|
||||
if (SET_SMALL_ICON.equals(node.getFunctionName())) {
|
||||
@@ -2080,7 +2081,7 @@ public class IconDetector extends ResourceXmlDetector implements UastScanner {
|
||||
}
|
||||
}
|
||||
|
||||
private final class MenuFinder extends UastVisitor {
|
||||
private final class MenuFinder extends AbstractUastVisitor {
|
||||
@Override
|
||||
public boolean visitQualifiedExpression(@NotNull UQualifiedExpression node) {
|
||||
// R.type.name
|
||||
|
||||
+3
-2
@@ -45,6 +45,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
|
||||
/**
|
||||
@@ -152,7 +153,7 @@ public class JavaPerformanceDetector extends Detector implements UastScanner {
|
||||
return new PerformanceVisitor(context);
|
||||
}
|
||||
|
||||
private static class PerformanceVisitor extends UastVisitor {
|
||||
private static class PerformanceVisitor extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
private final boolean mCheckMaps;
|
||||
private final boolean mCheckAllocations;
|
||||
@@ -552,7 +553,7 @@ public class JavaPerformanceDetector extends Detector implements UastScanner {
|
||||
}
|
||||
|
||||
/** Visitor which records variable names assigned into */
|
||||
private static class AssignmentTracker extends UastVisitor {
|
||||
private static class AssignmentTracker extends AbstractUastVisitor {
|
||||
private final Collection<String> mVariables;
|
||||
|
||||
public AssignmentTracker(Collection<String> variables) {
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
|
||||
/**
|
||||
* Looks for addJavascriptInterface calls on interfaces have been properly annotated
|
||||
@@ -182,7 +182,7 @@ public class JavaScriptInterfaceDetector extends Detector implements UastScanner
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class ConcreteTypeVisitor extends UastVisitor {
|
||||
private static class ConcreteTypeVisitor extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
private final UCallExpression mTargetCall;
|
||||
private boolean mFoundCall;
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -477,7 +478,7 @@ public class OverdrawDetector extends LayoutDetector implements UastScanner {
|
||||
return new OverdrawVisitor();
|
||||
}
|
||||
|
||||
private class OverdrawVisitor extends UastVisitor {
|
||||
private class OverdrawVisitor extends AbstractUastVisitor {
|
||||
private static final String ACTIVITY = "Activity"; //$NON-NLS-1$
|
||||
private String mClassFqn;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
|
||||
/**
|
||||
@@ -71,7 +72,7 @@ public class ParcelDetector extends Detector implements UastScanner {
|
||||
return new ParcelVisitor(context);
|
||||
}
|
||||
|
||||
private static class ParcelVisitor extends UastVisitor {
|
||||
private static class ParcelVisitor extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
|
||||
public ParcelVisitor(UastAndroidContext context) {
|
||||
|
||||
+2
-2
@@ -40,7 +40,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.java.JavaUastLanguagePlugin;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
|
||||
/**
|
||||
* A permission requirement is a boolean expression of permission names that a
|
||||
@@ -590,7 +590,7 @@ public abstract class PermissionRequirement {
|
||||
|
||||
if (node != null) {
|
||||
final AtomicReference<UExpression> reference = new AtomicReference<UExpression>();
|
||||
node.accept(new UastVisitor() {
|
||||
node.accept(new AbstractUastVisitor() {
|
||||
@Override
|
||||
public boolean visitVariable(@NotNull UVariable node) {
|
||||
reference.set(node.getInitializer());
|
||||
|
||||
@@ -76,6 +76,7 @@ import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.EmptyUastVisitor;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -571,7 +572,7 @@ public class RtlDetector extends LayoutDetector implements UastScanner {
|
||||
return EmptyUastVisitor.INSTANCE;
|
||||
}
|
||||
|
||||
private static class IdentifierChecker extends UastVisitor {
|
||||
private static class IdentifierChecker extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
|
||||
public IdentifierChecker(UastAndroidContext context) {
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.ULiteralExpression;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
|
||||
/**
|
||||
@@ -82,7 +83,7 @@ public class SdCardDetector extends Detector implements UastScanner {
|
||||
return new StringChecker(context);
|
||||
}
|
||||
|
||||
private static class StringChecker extends UastVisitor {
|
||||
private static class StringChecker extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
|
||||
public StringChecker(UastAndroidContext context) {
|
||||
|
||||
@@ -54,6 +54,7 @@ import org.jetbrains.uast.UCallExpression;
|
||||
import org.jetbrains.uast.USimpleReferenceExpression;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -358,10 +359,10 @@ public class SecurityDetector extends Detector implements Detector.XmlScanner, U
|
||||
return new IdentifierVisitor(context);
|
||||
}
|
||||
|
||||
private static class IdentifierVisitor extends UastVisitor {
|
||||
private static class IdentifierVisitor extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
|
||||
private final UastVisitor identifierHandler = new UastVisitor() {
|
||||
private final AbstractUastVisitor identifierHandler = new AbstractUastVisitor() {
|
||||
@Override
|
||||
public boolean visitSimpleReferenceExpression(@NotNull USimpleReferenceExpression node) {
|
||||
if ("MODE_WORLD_WRITEABLE".equals(node.getIdentifier())) { //$NON-NLS-1$
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.java.JavaUAssertExpression;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
|
||||
/**
|
||||
* Detector looking for SharedPreferences.edit() calls without a corresponding
|
||||
@@ -169,7 +169,7 @@ public class SharedPrefsDetector extends Detector implements UastScanner {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class CommitFinder extends UastVisitor {
|
||||
private static class CommitFinder extends AbstractUastVisitor {
|
||||
/** The target edit call */
|
||||
private final UCallExpression mTarget;
|
||||
/** whether it allows the commit call to be seen before the target node */
|
||||
|
||||
+2
-2
@@ -66,7 +66,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
@@ -1353,7 +1353,7 @@ public class StringFormatDetector extends ResourceXmlDetector implements UastSca
|
||||
* certain argument types are valid. Note however that it does not do full-blown
|
||||
* type analysis by checking method call signatures and so on.
|
||||
*/
|
||||
private static class UastStringTracker extends UastVisitor {
|
||||
private static class UastStringTracker extends AbstractUastVisitor {
|
||||
/** Method we're searching within */
|
||||
private final UElement mTop;
|
||||
/** The argument index in the method we're targeting */
|
||||
|
||||
+3
-3
@@ -52,7 +52,7 @@ import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.java.JavaUFunction;
|
||||
import org.jetbrains.uast.java.JavaUastCallKinds;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -455,7 +455,7 @@ public class SupportAnnotationDetector extends Detector implements UastScanner {
|
||||
* or whether the check return value (== PERMISSION_GRANTED vs != PERMISSION_GRANTED)
|
||||
* is handled correctly, etc.
|
||||
*/
|
||||
private static class CheckPermissionVisitor extends UastVisitor {
|
||||
private static class CheckPermissionVisitor extends AbstractUastVisitor {
|
||||
private boolean mChecksPermission;
|
||||
private boolean mDone;
|
||||
private final UElement mTarget;
|
||||
@@ -1251,7 +1251,7 @@ public class SupportAnnotationDetector extends Detector implements UastScanner {
|
||||
return new CallVisitor(context);
|
||||
}
|
||||
|
||||
private class CallVisitor extends UastVisitor {
|
||||
private class CallVisitor extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
|
||||
public CallVisitor(UastAndroidContext context) {
|
||||
|
||||
@@ -33,7 +33,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
|
||||
/** Detector looking for Toast.makeText() without a corresponding show() call */
|
||||
public class ToastDetector extends Detector implements UastScanner {
|
||||
@@ -110,7 +110,7 @@ public class ToastDetector extends Detector implements UastScanner {
|
||||
}
|
||||
}
|
||||
|
||||
private static class ShowFinder extends UastVisitor {
|
||||
private static class ShowFinder extends AbstractUastVisitor {
|
||||
/** The target makeText call */
|
||||
private final UExpression mTarget;
|
||||
/** Whether we've found the show method */
|
||||
|
||||
+3
-3
@@ -60,7 +60,7 @@ import org.jetbrains.uast.UElement;
|
||||
import org.jetbrains.uast.UVariable;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
@@ -530,7 +530,7 @@ public class UnusedResourceDetector extends ResourceXmlDetector implements UastS
|
||||
}
|
||||
|
||||
@Override
|
||||
public UastVisitor createUastVisitor(@NonNull UastAndroidContext context) {
|
||||
public AbstractUastVisitor createUastVisitor(@NonNull UastAndroidContext context) {
|
||||
if (mReferences != null) {
|
||||
return new UnusedResourceVisitor();
|
||||
} else {
|
||||
@@ -540,7 +540,7 @@ public class UnusedResourceDetector extends ResourceXmlDetector implements UastS
|
||||
}
|
||||
|
||||
// Look for references and declarations
|
||||
private class UnusedResourceVisitor extends UastVisitor {
|
||||
private class UnusedResourceVisitor extends AbstractUastVisitor {
|
||||
@Override
|
||||
public boolean visitClass(@NotNull UClass node) {
|
||||
// Look for declarations of R class fields and store them in
|
||||
|
||||
@@ -28,13 +28,13 @@ import com.android.tools.klint.detector.api.Severity;
|
||||
import com.android.tools.klint.detector.api.Speed;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
|
||||
/**
|
||||
@@ -83,7 +83,7 @@ public class ViewHolderDetector extends Detector implements UastScanner {
|
||||
return new ViewAdapterVisitor(context);
|
||||
}
|
||||
|
||||
private static class ViewAdapterVisitor extends UastVisitor {
|
||||
private static class ViewAdapterVisitor extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
|
||||
public ViewAdapterVisitor(UastAndroidContext context) {
|
||||
@@ -121,7 +121,7 @@ public class ViewHolderDetector extends Detector implements UastScanner {
|
||||
}
|
||||
}
|
||||
|
||||
private static class InflationVisitor extends UastVisitor {
|
||||
private static class InflationVisitor extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
private List<UElement> mNodes;
|
||||
private boolean mHaveConditional;
|
||||
|
||||
+2
-1
@@ -30,6 +30,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.UImportStatement;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.check.UastScanner;
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
|
||||
/**
|
||||
@@ -80,7 +81,7 @@ public class WrongImportDetector extends Detector implements UastScanner {
|
||||
return new ImportVisitor(context);
|
||||
}
|
||||
|
||||
private static class ImportVisitor extends UastVisitor {
|
||||
private static class ImportVisitor extends AbstractUastVisitor {
|
||||
private final UastAndroidContext mContext;
|
||||
|
||||
public ImportVisitor(UastAndroidContext context) {
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ class AndroidModelFacade(val facet: AndroidFacet) {
|
||||
fun getDependsOn(artifact: String): Boolean {
|
||||
val model = model ?: return false
|
||||
return GradleUtil::class.staticFunctions.firstOrNull {
|
||||
val type = it.parameters[0].type.toString()
|
||||
val type = it.parameters.firstOrNull()?.type?.toString() ?: ""
|
||||
it.parameters.size == 2 && "IdeaAndroidProject" in type || "AndroidGradleModel" in type
|
||||
}?.call(model, artifact) as? Boolean ?: false
|
||||
}
|
||||
|
||||
+1
-1
@@ -21,5 +21,5 @@ import org.jetbrains.kotlin.uast.KotlinUastLanguagePlugin
|
||||
|
||||
class KotlinLintLanguageExtension : LintLanguageExtension() {
|
||||
override val converter = KotlinUastLanguagePlugin.converter
|
||||
override val additionalCheckers = KotlinUastLanguagePlugin.additionalCheckers
|
||||
override val visitorExtensions = KotlinUastLanguagePlugin.visitorExtensions
|
||||
}
|
||||
@@ -27,6 +27,8 @@ import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.UastCallKind.Companion.CONSTRUCTOR_CALL
|
||||
import org.jetbrains.uast.UastCallKind.Companion.FUNCTION_CALL
|
||||
import org.jetbrains.uast.java.JavaUastLanguagePlugin
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor
|
||||
import org.jetbrains.uast.visitor.UastExtendableVisitor
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
import java.io.File
|
||||
|
||||
@@ -42,6 +44,7 @@ object UastChecker {
|
||||
val vfile = VirtualFileManager.getInstance().findFileByUrl("file://" + file.absolutePath) ?: return
|
||||
|
||||
val plugins = context.languagePlugins
|
||||
val extendableVisitor = UastExtendableVisitor(visitor, context, plugins.flatMap { it.visitorExtensions })
|
||||
|
||||
ApplicationManager.getApplication().runReadAction {
|
||||
val psiFile = PsiManager.getInstance(project).findFile(vfile)
|
||||
@@ -50,12 +53,12 @@ object UastChecker {
|
||||
when (psiFile) {
|
||||
is PsiJavaFile -> {
|
||||
val ufile = JavaUastLanguagePlugin.converter.convertWithParent(psiFile)
|
||||
ufile?.accept(visitor)
|
||||
ufile?.accept(extendableVisitor)
|
||||
}
|
||||
else -> for (plugin in plugins) {
|
||||
val ufile = plugin.converter.convertWithParent(psiFile)
|
||||
if (ufile != null) {
|
||||
ufile.accept(visitor)
|
||||
ufile.accept(extendableVisitor)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -71,7 +74,7 @@ object UastChecker {
|
||||
|
||||
val appliesToResourcesRefs = scanner.appliesToResourceRefs()
|
||||
|
||||
val visitor = object : UastVisitor() {
|
||||
val visitor = object : AbstractUastVisitor() {
|
||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
||||
if (applicableFunctionNames.isNotEmpty()) {
|
||||
if (node.kind == FUNCTION_CALL && node.functionName in applicableFunctionNames) {
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.uast;
|
||||
|
||||
public interface UastCallback {
|
||||
void invoke(UElement element);
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.jetbrains.uast
|
||||
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
interface UastConverter {
|
||||
fun convert(element: Any?, parent: UElement): UElement?
|
||||
fun convertWithParent(element: Any?): UElement?
|
||||
@@ -24,11 +26,11 @@ interface UastConverter {
|
||||
|
||||
interface UastLanguagePlugin {
|
||||
val converter: UastConverter
|
||||
val additionalCheckers: List<UastAdditionalChecker>
|
||||
val visitorExtensions: List<UastVisitorExtension>
|
||||
}
|
||||
|
||||
interface UastAdditionalChecker {
|
||||
operator fun invoke(element: UElement, callback: UastCallback, context: UastContext)
|
||||
interface UastVisitorExtension {
|
||||
operator fun invoke(element: UElement, visitor: UastVisitor, context: UastContext)
|
||||
}
|
||||
|
||||
object UastConverterUtils {
|
||||
|
||||
@@ -75,6 +75,12 @@ interface UElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for the [UElement] which was synthesized by an [UastExtendableVisitor].
|
||||
* A synthesized element is not processed by an [UastExtendableVisitor].
|
||||
*/
|
||||
interface SynthesizedUElement : UElement
|
||||
|
||||
/**
|
||||
* An interface for the [UElement] which has a name.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.uast.visitor
|
||||
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
class DelegatingUastVisitor(private val visitors: List<UastVisitor>): UastVisitor {
|
||||
override fun visitElement(node: UElement): Boolean {
|
||||
return visitors.all { it.visitElement(node) }
|
||||
}
|
||||
|
||||
override fun visitFile(node: UFile): Boolean {
|
||||
return visitors.all { it.visitFile(node) }
|
||||
}
|
||||
|
||||
override fun visitImportStatement(node: UImportStatement): Boolean {
|
||||
return visitors.all { it.visitImportStatement(node) }
|
||||
}
|
||||
|
||||
override fun visitAnnotation(node: UAnnotation): Boolean {
|
||||
return visitors.all { it.visitAnnotation(node) }
|
||||
}
|
||||
|
||||
override fun visitCatchClause(node: UCatchClause): Boolean {
|
||||
return visitors.all { it.visitCatchClause(node) }
|
||||
}
|
||||
|
||||
override fun visitType(node: UType): Boolean {
|
||||
return visitors.all { it.visitType(node) }
|
||||
}
|
||||
|
||||
override fun visitClass(node: UClass): Boolean {
|
||||
return visitors.all { it.visitClass(node) }
|
||||
}
|
||||
|
||||
override fun visitFunction(node: UFunction): Boolean {
|
||||
return visitors.all { it.visitFunction(node) }
|
||||
}
|
||||
|
||||
override fun visitVariable(node: UVariable): Boolean {
|
||||
return visitors.all { it.visitVariable(node) }
|
||||
}
|
||||
|
||||
override fun visitLabeledExpression(node: ULabeledExpression): Boolean {
|
||||
return visitors.all { it.visitLabeledExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitDeclarationsExpression(node: UDeclarationsExpression): Boolean {
|
||||
return visitors.all { it.visitDeclarationsExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitBlockExpression(node: UBlockExpression): Boolean {
|
||||
return visitors.all { it.visitBlockExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitQualifiedExpression(node: UQualifiedExpression): Boolean {
|
||||
return visitors.all { it.visitQualifiedExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitSimpleReferenceExpression(node: USimpleReferenceExpression): Boolean {
|
||||
return visitors.all { it.visitSimpleReferenceExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
||||
return visitors.all { it.visitCallExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitBinaryExpression(node: UBinaryExpression): Boolean {
|
||||
return visitors.all { it.visitBinaryExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType): Boolean {
|
||||
return visitors.all { it.visitBinaryExpressionWithType(node) }
|
||||
}
|
||||
|
||||
override fun visitParenthesizedExpression(node: UParenthesizedExpression): Boolean {
|
||||
return visitors.all { it.visitParenthesizedExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitUnaryExpression(node: UUnaryExpression): Boolean {
|
||||
return visitors.all { it.visitUnaryExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitPrefixExpression(node: UPrefixExpression): Boolean {
|
||||
return visitors.all { it.visitPrefixExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitPostfixExpression(node: UPostfixExpression): Boolean {
|
||||
return visitors.all { it.visitPostfixExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitSpecialExpressionList(node: USpecialExpressionList): Boolean {
|
||||
return visitors.all { it.visitSpecialExpressionList(node) }
|
||||
}
|
||||
|
||||
override fun visitIfExpression(node: UIfExpression): Boolean {
|
||||
return visitors.all { it.visitIfExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitSwitchExpression(node: USwitchExpression): Boolean {
|
||||
return visitors.all { it.visitSwitchExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitSwitchClauseExpression(node: USwitchClauseExpression): Boolean {
|
||||
return visitors.all { it.visitSwitchClauseExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitWhileExpression(node: UWhileExpression): Boolean {
|
||||
return visitors.all { it.visitWhileExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitDoWhileExpression(node: UDoWhileExpression): Boolean {
|
||||
return visitors.all { it.visitDoWhileExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitForExpression(node: UForExpression): Boolean {
|
||||
return visitors.all { it.visitForExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitForEachExpression(node: UForEachExpression): Boolean {
|
||||
return visitors.all { it.visitForEachExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitTryExpression(node: UTryExpression): Boolean {
|
||||
return visitors.all { it.visitTryExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitLiteralExpression(node: ULiteralExpression): Boolean {
|
||||
return visitors.all { it.visitLiteralExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitThisExpression(node: UThisExpression): Boolean {
|
||||
return visitors.all { it.visitThisExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitSuperExpression(node: USuperExpression): Boolean {
|
||||
return visitors.all { it.visitSuperExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitReturnExpression(node: UReturnExpression): Boolean {
|
||||
return visitors.all { it.visitReturnExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitBreakExpression(node: UBreakExpression): Boolean {
|
||||
return visitors.all { it.visitBreakExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitContinueExpression(node: UContinueExpression): Boolean {
|
||||
return visitors.all { it.visitContinueExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitThrowExpression(node: UThrowExpression): Boolean {
|
||||
return visitors.all { it.visitThrowExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitArrayAccessExpression(node: UArrayAccessExpression): Boolean {
|
||||
return visitors.all { it.visitArrayAccessExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitCallableReferenceExpression(node: UCallableReferenceExpression): Boolean {
|
||||
return visitors.all { it.visitCallableReferenceExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitClassLiteralExpression(node: UClassLiteralExpression): Boolean {
|
||||
return visitors.all { it.visitClassLiteralExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitLambdaExpression(node: ULambdaExpression): Boolean {
|
||||
return visitors.all { it.visitLambdaExpression(node) }
|
||||
}
|
||||
|
||||
override fun visitObjectLiteralExpression(node: UObjectLiteralExpression): Boolean {
|
||||
return visitors.all { it.visitObjectLiteralExpression(node) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.uast.visitor
|
||||
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
class UastExtendableVisitor(
|
||||
private val original: UastVisitor,
|
||||
private val context: UastContext,
|
||||
private val extensions: List<UastVisitorExtension>
|
||||
) : UastVisitor {
|
||||
private fun handleExtensions(node: UElement) {
|
||||
if (node !is SynthesizedUElement) {
|
||||
for (extension in extensions) {
|
||||
extension.invoke(node, this, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitElement(node: UElement): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitElement(node)
|
||||
}
|
||||
|
||||
override fun visitFile(node: UFile): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitFile(node)
|
||||
}
|
||||
|
||||
override fun visitImportStatement(node: UImportStatement): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitImportStatement(node)
|
||||
}
|
||||
|
||||
override fun visitAnnotation(node: UAnnotation): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitAnnotation(node)
|
||||
}
|
||||
|
||||
override fun visitCatchClause(node: UCatchClause): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitCatchClause(node)
|
||||
}
|
||||
|
||||
override fun visitType(node: UType): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitType(node)
|
||||
}
|
||||
|
||||
override fun visitClass(node: UClass): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitClass(node)
|
||||
}
|
||||
|
||||
override fun visitFunction(node: UFunction): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitFunction(node)
|
||||
}
|
||||
|
||||
override fun visitVariable(node: UVariable): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitVariable(node)
|
||||
}
|
||||
|
||||
override fun visitLabeledExpression(node: ULabeledExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitLabeledExpression(node)
|
||||
}
|
||||
|
||||
override fun visitDeclarationsExpression(node: UDeclarationsExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitDeclarationsExpression(node)
|
||||
}
|
||||
|
||||
override fun visitBlockExpression(node: UBlockExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitBlockExpression(node)
|
||||
}
|
||||
|
||||
override fun visitQualifiedExpression(node: UQualifiedExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitQualifiedExpression(node)
|
||||
}
|
||||
|
||||
override fun visitSimpleReferenceExpression(node: USimpleReferenceExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitSimpleReferenceExpression(node)
|
||||
}
|
||||
|
||||
override fun visitCallExpression(node: UCallExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitCallExpression(node)
|
||||
}
|
||||
|
||||
override fun visitBinaryExpression(node: UBinaryExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitBinaryExpression(node)
|
||||
}
|
||||
|
||||
override fun visitBinaryExpressionWithType(node: UBinaryExpressionWithType): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitBinaryExpressionWithType(node)
|
||||
}
|
||||
|
||||
override fun visitParenthesizedExpression(node: UParenthesizedExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitParenthesizedExpression(node)
|
||||
}
|
||||
|
||||
override fun visitUnaryExpression(node: UUnaryExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitUnaryExpression(node)
|
||||
}
|
||||
|
||||
override fun visitPrefixExpression(node: UPrefixExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitPrefixExpression(node)
|
||||
}
|
||||
|
||||
override fun visitPostfixExpression(node: UPostfixExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitPostfixExpression(node)
|
||||
}
|
||||
|
||||
override fun visitSpecialExpressionList(node: USpecialExpressionList): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitSpecialExpressionList(node)
|
||||
}
|
||||
|
||||
override fun visitIfExpression(node: UIfExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitIfExpression(node)
|
||||
}
|
||||
|
||||
override fun visitSwitchExpression(node: USwitchExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitSwitchExpression(node)
|
||||
}
|
||||
|
||||
override fun visitSwitchClauseExpression(node: USwitchClauseExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitSwitchClauseExpression(node)
|
||||
}
|
||||
|
||||
override fun visitWhileExpression(node: UWhileExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitWhileExpression(node)
|
||||
}
|
||||
|
||||
override fun visitDoWhileExpression(node: UDoWhileExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitDoWhileExpression(node)
|
||||
}
|
||||
|
||||
override fun visitForExpression(node: UForExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitForExpression(node)
|
||||
}
|
||||
|
||||
override fun visitForEachExpression(node: UForEachExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitForEachExpression(node)
|
||||
}
|
||||
|
||||
override fun visitTryExpression(node: UTryExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitTryExpression(node)
|
||||
}
|
||||
|
||||
override fun visitLiteralExpression(node: ULiteralExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitLiteralExpression(node)
|
||||
}
|
||||
|
||||
override fun visitThisExpression(node: UThisExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitThisExpression(node)
|
||||
}
|
||||
|
||||
override fun visitSuperExpression(node: USuperExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitSuperExpression(node)
|
||||
}
|
||||
|
||||
override fun visitReturnExpression(node: UReturnExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return super.visitReturnExpression(node)
|
||||
}
|
||||
|
||||
override fun visitBreakExpression(node: UBreakExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitBreakExpression(node)
|
||||
}
|
||||
|
||||
override fun visitContinueExpression(node: UContinueExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitContinueExpression(node)
|
||||
}
|
||||
|
||||
override fun visitThrowExpression(node: UThrowExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitThrowExpression(node)
|
||||
}
|
||||
|
||||
override fun visitArrayAccessExpression(node: UArrayAccessExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitArrayAccessExpression(node)
|
||||
}
|
||||
|
||||
override fun visitCallableReferenceExpression(node: UCallableReferenceExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitCallableReferenceExpression(node)
|
||||
}
|
||||
|
||||
override fun visitClassLiteralExpression(node: UClassLiteralExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitClassLiteralExpression(node)
|
||||
}
|
||||
|
||||
override fun visitLambdaExpression(node: ULambdaExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitLambdaExpression(node)
|
||||
}
|
||||
|
||||
override fun visitObjectLiteralExpression(node: UObjectLiteralExpression): Boolean {
|
||||
handleExtensions(node)
|
||||
return original.visitObjectLiteralExpression(node)
|
||||
}
|
||||
}
|
||||
+7
-5
@@ -17,8 +17,8 @@ package org.jetbrains.uast.visitor
|
||||
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
abstract class UastVisitor {
|
||||
open fun visitElement(node: UElement): Boolean = false
|
||||
interface UastVisitor {
|
||||
open fun visitElement(node: UElement): Boolean
|
||||
|
||||
open fun visitFile(node: UFile) = visitElement(node)
|
||||
open fun visitImportStatement(node: UImportStatement) = visitElement(node)
|
||||
@@ -31,7 +31,6 @@ abstract class UastVisitor {
|
||||
open fun visitFunction(node: UFunction) = visitElement(node)
|
||||
open fun visitVariable(node: UVariable) = visitElement(node)
|
||||
|
||||
|
||||
// Expressions
|
||||
open fun visitLabeledExpression(node: ULabeledExpression) = visitElement(node)
|
||||
open fun visitDeclarationsExpression(node: UDeclarationsExpression) = visitElement(node)
|
||||
@@ -82,7 +81,6 @@ abstract class UastVisitor {
|
||||
open fun afterVisitFunction(node: UFunction) {}
|
||||
open fun afterVisitVariable(node: UVariable) {}
|
||||
|
||||
|
||||
// Expressions
|
||||
open fun afterVisitLabeledExpression(node: ULabeledExpression) {}
|
||||
open fun afterVisitDeclarationsExpression(node: UDeclarationsExpression) {}
|
||||
@@ -119,4 +117,8 @@ abstract class UastVisitor {
|
||||
open fun afterVisitObjectLiteralExpression(node: UObjectLiteralExpression) {}
|
||||
}
|
||||
|
||||
object EmptyUastVisitor : UastVisitor()
|
||||
abstract class AbstractUastVisitor : UastVisitor {
|
||||
override fun visitElement(node: UElement): Boolean = false
|
||||
}
|
||||
|
||||
object EmptyUastVisitor : AbstractUastVisitor()
|
||||
@@ -22,7 +22,8 @@ import org.jetbrains.uast.java.expressions.JavaUSynchronizedExpression
|
||||
|
||||
object JavaUastLanguagePlugin : UastLanguagePlugin {
|
||||
override val converter: UastConverter = JavaConverter
|
||||
override val additionalCheckers = emptyList<UastAdditionalChecker>()
|
||||
override val visitorExtensions: List<UastVisitorExtension>
|
||||
get() = emptyList()
|
||||
}
|
||||
|
||||
internal object JavaConverter : UastConverter {
|
||||
|
||||
@@ -28,12 +28,12 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.uast.expressions.KotlinUBreakExpression
|
||||
import org.jetbrains.kotlin.uast.expressions.KotlinUContinueExpression
|
||||
import org.jetbrains.kotlin.uast.kinds.KotlinSpecialExpressionKinds
|
||||
import org.jetbrains.kotlin.uast.lint.PropertyAsCallAndroidUastAdditionalChecker
|
||||
import org.jetbrains.kotlin.uast.extensions.PropertyAsCallAndroidUastVisitorExtension
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
object KotlinUastLanguagePlugin : UastLanguagePlugin {
|
||||
override val converter: UastConverter = KotlinConverter
|
||||
override val additionalCheckers = listOf(PropertyAsCallAndroidUastAdditionalChecker())
|
||||
override val visitorExtensions = listOf(PropertyAsCallAndroidUastVisitorExtension())
|
||||
}
|
||||
|
||||
internal object KotlinConverter : UastConverter {
|
||||
|
||||
+6
-5
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.uast.lint
|
||||
package org.jetbrains.kotlin.uast.extensions
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
@@ -26,9 +26,10 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.uast.*
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.psi.PsiElementBacked
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
class PropertyAsCallAndroidUastAdditionalChecker : UastAdditionalChecker {
|
||||
override fun invoke(element: UElement, callback: UastCallback, context: UastContext) {
|
||||
class PropertyAsCallAndroidUastVisitorExtension : UastVisitorExtension {
|
||||
override fun invoke(element: UElement, visitor: UastVisitor, context: UastContext) {
|
||||
val expr = element as? KotlinUSimpleReferenceExpression ?: return
|
||||
if (expr is KotlinNameUSimpleReferenceExpression) return
|
||||
|
||||
@@ -46,7 +47,7 @@ class PropertyAsCallAndroidUastAdditionalChecker : UastAdditionalChecker {
|
||||
else
|
||||
null
|
||||
|
||||
val callExpression: UCallExpression = object : UCallExpression, PsiElementBacked {
|
||||
val callExpression: UCallExpression = object : UCallExpression, PsiElementBacked, SynthetizedUElement {
|
||||
override val parent = element.parent
|
||||
override val psi = ktElement
|
||||
|
||||
@@ -85,7 +86,7 @@ class PropertyAsCallAndroidUastAdditionalChecker : UastAdditionalChecker {
|
||||
}
|
||||
}
|
||||
|
||||
callback(callExpression)
|
||||
visitor.visitCallExpression(callExpression)
|
||||
}
|
||||
|
||||
private tailrec fun findAssignment(prev: PsiElement?, element: PsiElement?): KtBinaryExpression? = when (element) {
|
||||
+2
-2
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
import org.jetbrains.uast.visitor.AbstractUastVisitor
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractKotlinUastStructureTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
@@ -50,7 +50,7 @@ abstract class AbstractKotlinUastStructureTest : KotlinLightCodeInsightFixtureTe
|
||||
|
||||
private fun genTree(node: UElement): String {
|
||||
val builder = StringBuilder()
|
||||
val visitor = object : UastVisitor() {
|
||||
val visitor = object : AbstractUastVisitor() {
|
||||
private tailrec fun getParentCount(node: UElement): Int {
|
||||
val parent = node.parent ?: return 0
|
||||
return getParentCount(parent)
|
||||
|
||||
Reference in New Issue
Block a user