From 21a2115501f1f91e6f8ccd3b27d44cfad8583830 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 6 Apr 2016 18:22:17 +0300 Subject: [PATCH] Uast: Add Uast visitor extensions instead of additional checkers --- .../client/api/JavaLintLanguageExtension.java | 6 +- .../tools/klint/client/api/LintDriver.java | 2 - .../tools/klint/detector/api/Detector.java | 1 + .../checks/AlwaysShowActionDetector.java | 4 +- .../klint/checks/AnnotationDetector.java | 4 +- .../android/tools/klint/checks/ApiDetector.kt | 3 +- .../tools/klint/checks/AssertDetector.java | 3 +- .../tools/klint/checks/CallSuperDetector.java | 5 +- .../tools/klint/checks/CleanupDetector.java | 4 +- .../tools/klint/checks/CutPasteDetector.java | 4 +- .../tools/klint/checks/IconDetector.java | 7 +- .../klint/checks/JavaPerformanceDetector.java | 5 +- .../checks/JavaScriptInterfaceDetector.java | 4 +- .../tools/klint/checks/OverdrawDetector.java | 3 +- .../tools/klint/checks/ParcelDetector.java | 3 +- .../klint/checks/PermissionRequirement.java | 4 +- .../tools/klint/checks/RtlDetector.java | 3 +- .../tools/klint/checks/SdCardDetector.java | 3 +- .../tools/klint/checks/SecurityDetector.java | 5 +- .../klint/checks/SharedPrefsDetector.java | 4 +- .../klint/checks/StringFormatDetector.java | 4 +- .../checks/SupportAnnotationDetector.java | 6 +- .../tools/klint/checks/ToastDetector.java | 4 +- .../klint/checks/UnusedResourceDetector.java | 6 +- .../klint/checks/ViewHolderDetector.java | 6 +- .../klint/checks/WrongImportDetector.java | 3 +- .../inspections/klint/AndroidModelFacade.kt | 2 +- .../klint/KotlinLintLanguageExtension.kt | 2 +- .../org/jetbrains/uast/check/UastChecker.kt | 9 +- .../src/org/jetbrains/uast/UastCallback.java | 20 -- .../org/jetbrains/uast/UastLanguagePlugin.kt | 8 +- .../jetbrains/uast/baseElements/UElement.kt | 6 + .../uast/visitor/DelegatingUastVisitor.kt | 189 ++++++++++++++ .../uast/visitor/UastExtendableVisitor.kt | 244 ++++++++++++++++++ .../uast/{ => visitor}/UastVisitor.kt | 12 +- .../uast/java/JavaUastLanguagePlugin.kt | 3 +- .../kotlin/uast/KotlinUastLanguagePlugin.kt | 4 +- ...pertyAsCallAndroidUastVisitorExtension.kt} | 11 +- .../AbstractKotlinUastStructureTest.kt | 4 +- 39 files changed, 529 insertions(+), 91 deletions(-) delete mode 100644 plugins/uast-common/src/org/jetbrains/uast/UastCallback.java create mode 100644 plugins/uast-common/src/org/jetbrains/uast/visitor/DelegatingUastVisitor.kt create mode 100644 plugins/uast-common/src/org/jetbrains/uast/visitor/UastExtendableVisitor.kt rename plugins/uast-common/src/org/jetbrains/uast/{ => visitor}/UastVisitor.kt (96%) rename plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/{lint/PropertyAsCallAndroidUastAdditionalChecker.kt => extensions/PropertyAsCallAndroidUastVisitorExtension.kt} (91%) diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaLintLanguageExtension.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaLintLanguageExtension.java index d884ef1c398..546dee07971 100644 --- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaLintLanguageExtension.java +++ b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/JavaLintLanguageExtension.java @@ -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 getAdditionalCheckers() { - return JavaUastLanguagePlugin.INSTANCE.getAdditionalCheckers(); + public List getVisitorExtensions() { + return JavaUastLanguagePlugin.INSTANCE.getVisitorExtensions(); } } diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java index f85ed599246..0e3adb523e5 100644 --- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java +++ b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java @@ -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; diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Detector.java b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Detector.java index 41914c0564c..f385e30a287 100644 --- a/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Detector.java +++ b/plugins/lint/lint-api/src/com/android/tools/klint/detector/api/Detector.java @@ -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; diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AlwaysShowActionDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AlwaysShowActionDetector.java index 2d75b789934..4b64d61cbf3 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AlwaysShowActionDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AlwaysShowActionDetector.java @@ -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) { diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AnnotationDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AnnotationDetector.java index f239e076f1a..218c069c2cd 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AnnotationDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AnnotationDetector.java @@ -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) { diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.kt b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.kt index ace616590f8..33bec65556c 100755 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.kt +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiDetector.kt @@ -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 { diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AssertDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AssertDetector.java index 01835b3f725..94da417556b 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AssertDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/AssertDetector.java @@ -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)) { diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CallSuperDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CallSuperDetector.java index 9c16fa762e9..4a84742e8dc 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CallSuperDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CallSuperDetector.java @@ -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; diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CleanupDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CleanupDetector.java index 1f35dd8b398..f43285acd35 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CleanupDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CleanupDetector.java @@ -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 mVariables; private boolean mContainsCleanup; diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CutPasteDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CutPasteDetector.java index 305b73475c8..c7ef9e5545e 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CutPasteDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/CutPasteDetector.java @@ -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; diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/IconDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/IconDetector.java index d3df008a013..66f0d1d0a3a 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/IconDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/IconDetector.java @@ -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 diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaPerformanceDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaPerformanceDetector.java index 55c3075dcc0..c73272d135e 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaPerformanceDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaPerformanceDetector.java @@ -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 mVariables; public AssignmentTracker(Collection variables) { diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaScriptInterfaceDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaScriptInterfaceDetector.java index 87229f158f2..1a7dc086cae 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaScriptInterfaceDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/JavaScriptInterfaceDetector.java @@ -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; diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/OverdrawDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/OverdrawDetector.java index 95d52bc4815..1c7b1168e68 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/OverdrawDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/OverdrawDetector.java @@ -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; diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ParcelDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ParcelDetector.java index b97dbfa7672..a6a92b1d6f1 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ParcelDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ParcelDetector.java @@ -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) { diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionRequirement.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionRequirement.java index 65cdc01f8da..0b37e07e3ec 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionRequirement.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/PermissionRequirement.java @@ -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 reference = new AtomicReference(); - node.accept(new UastVisitor() { + node.accept(new AbstractUastVisitor() { @Override public boolean visitVariable(@NotNull UVariable node) { reference.set(node.getInitializer()); diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RtlDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RtlDetector.java index a43819f3681..421f20ec1f5 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RtlDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/RtlDetector.java @@ -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) { diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SdCardDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SdCardDetector.java index 07c2ccb77b2..44262431113 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SdCardDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SdCardDetector.java @@ -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) { diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SecurityDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SecurityDetector.java index 9092ed96e73..352802d660f 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SecurityDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SecurityDetector.java @@ -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$ diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SharedPrefsDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SharedPrefsDetector.java index 8c764ee9b47..4020af57aa2 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SharedPrefsDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SharedPrefsDetector.java @@ -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 */ diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/StringFormatDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/StringFormatDetector.java index 5c979565007..fc08a5f269e 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/StringFormatDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/StringFormatDetector.java @@ -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 */ diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SupportAnnotationDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SupportAnnotationDetector.java index 747c0c1e311..31dddd726cb 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SupportAnnotationDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/SupportAnnotationDetector.java @@ -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) { diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ToastDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ToastDetector.java index 7b9602a3d52..eef080fc64a 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ToastDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ToastDetector.java @@ -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 */ diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/UnusedResourceDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/UnusedResourceDetector.java index e4ec4db5756..7ba0759741c 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/UnusedResourceDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/UnusedResourceDetector.java @@ -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 diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewHolderDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewHolderDetector.java index 6439689c12e..c31da96815e 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewHolderDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ViewHolderDetector.java @@ -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 mNodes; private boolean mHaveConditional; diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/WrongImportDetector.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/WrongImportDetector.java index e9a4226052c..6a93c321ac6 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/WrongImportDetector.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/WrongImportDetector.java @@ -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) { diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidModelFacade.kt b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidModelFacade.kt index b397078d556..cfa1fc8f015 100644 --- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidModelFacade.kt +++ b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidModelFacade.kt @@ -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 } diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/KotlinLintLanguageExtension.kt b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/KotlinLintLanguageExtension.kt index b95397efc03..e8269d99d9f 100644 --- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/KotlinLintLanguageExtension.kt +++ b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/KotlinLintLanguageExtension.kt @@ -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 } \ No newline at end of file diff --git a/plugins/lint/uast-android/src/org/jetbrains/uast/check/UastChecker.kt b/plugins/lint/uast-android/src/org/jetbrains/uast/check/UastChecker.kt index 52b6c140dab..0b3aca8c759 100644 --- a/plugins/lint/uast-android/src/org/jetbrains/uast/check/UastChecker.kt +++ b/plugins/lint/uast-android/src/org/jetbrains/uast/check/UastChecker.kt @@ -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) { diff --git a/plugins/uast-common/src/org/jetbrains/uast/UastCallback.java b/plugins/uast-common/src/org/jetbrains/uast/UastCallback.java deleted file mode 100644 index ec95608e72b..00000000000 --- a/plugins/uast-common/src/org/jetbrains/uast/UastCallback.java +++ /dev/null @@ -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); -} diff --git a/plugins/uast-common/src/org/jetbrains/uast/UastLanguagePlugin.kt b/plugins/uast-common/src/org/jetbrains/uast/UastLanguagePlugin.kt index 5f9e873ed39..cab926584d5 100644 --- a/plugins/uast-common/src/org/jetbrains/uast/UastLanguagePlugin.kt +++ b/plugins/uast-common/src/org/jetbrains/uast/UastLanguagePlugin.kt @@ -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 + val visitorExtensions: List } -interface UastAdditionalChecker { - operator fun invoke(element: UElement, callback: UastCallback, context: UastContext) +interface UastVisitorExtension { + operator fun invoke(element: UElement, visitor: UastVisitor, context: UastContext) } object UastConverterUtils { diff --git a/plugins/uast-common/src/org/jetbrains/uast/baseElements/UElement.kt b/plugins/uast-common/src/org/jetbrains/uast/baseElements/UElement.kt index 044777452a4..cfc7bd1a27f 100644 --- a/plugins/uast-common/src/org/jetbrains/uast/baseElements/UElement.kt +++ b/plugins/uast-common/src/org/jetbrains/uast/baseElements/UElement.kt @@ -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. */ diff --git a/plugins/uast-common/src/org/jetbrains/uast/visitor/DelegatingUastVisitor.kt b/plugins/uast-common/src/org/jetbrains/uast/visitor/DelegatingUastVisitor.kt new file mode 100644 index 00000000000..c5d4338f1f0 --- /dev/null +++ b/plugins/uast-common/src/org/jetbrains/uast/visitor/DelegatingUastVisitor.kt @@ -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 { + 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) } + } +} \ No newline at end of file diff --git a/plugins/uast-common/src/org/jetbrains/uast/visitor/UastExtendableVisitor.kt b/plugins/uast-common/src/org/jetbrains/uast/visitor/UastExtendableVisitor.kt new file mode 100644 index 00000000000..a3e2696f49f --- /dev/null +++ b/plugins/uast-common/src/org/jetbrains/uast/visitor/UastExtendableVisitor.kt @@ -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 +) : 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) + } +} \ No newline at end of file diff --git a/plugins/uast-common/src/org/jetbrains/uast/UastVisitor.kt b/plugins/uast-common/src/org/jetbrains/uast/visitor/UastVisitor.kt similarity index 96% rename from plugins/uast-common/src/org/jetbrains/uast/UastVisitor.kt rename to plugins/uast-common/src/org/jetbrains/uast/visitor/UastVisitor.kt index 5578578d882..971ec2e5a5d 100644 --- a/plugins/uast-common/src/org/jetbrains/uast/UastVisitor.kt +++ b/plugins/uast-common/src/org/jetbrains/uast/visitor/UastVisitor.kt @@ -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() \ No newline at end of file +abstract class AbstractUastVisitor : UastVisitor { + override fun visitElement(node: UElement): Boolean = false +} + +object EmptyUastVisitor : AbstractUastVisitor() \ No newline at end of file diff --git a/plugins/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt b/plugins/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt index 2c732164324..eb067d7fc19 100644 --- a/plugins/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt +++ b/plugins/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt @@ -22,7 +22,8 @@ import org.jetbrains.uast.java.expressions.JavaUSynchronizedExpression object JavaUastLanguagePlugin : UastLanguagePlugin { override val converter: UastConverter = JavaConverter - override val additionalCheckers = emptyList() + override val visitorExtensions: List + get() = emptyList() } internal object JavaConverter : UastConverter { diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinUastLanguagePlugin.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinUastLanguagePlugin.kt index 47bef979715..af68ba79ecc 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinUastLanguagePlugin.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/KotlinUastLanguagePlugin.kt @@ -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 { diff --git a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/lint/PropertyAsCallAndroidUastAdditionalChecker.kt b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/extensions/PropertyAsCallAndroidUastVisitorExtension.kt similarity index 91% rename from plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/lint/PropertyAsCallAndroidUastAdditionalChecker.kt rename to plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/extensions/PropertyAsCallAndroidUastVisitorExtension.kt index cf4f3c9494a..b69f524e2dc 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/lint/PropertyAsCallAndroidUastAdditionalChecker.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/kotlin/uast/extensions/PropertyAsCallAndroidUastVisitorExtension.kt @@ -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) { diff --git a/plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/AbstractKotlinUastStructureTest.kt b/plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/AbstractKotlinUastStructureTest.kt index ab0ec3c7b8c..fcaf48d68aa 100644 --- a/plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/AbstractKotlinUastStructureTest.kt +++ b/plugins/uast-kotlin/test/org.jetbrains.kotlin.uast/AbstractKotlinUastStructureTest.kt @@ -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)