Replace UastConverter with UastLanguagePlugin, allow additional checkers
This commit is contained in:
+13
-2
@@ -16,12 +16,23 @@
|
||||
|
||||
package com.android.tools.klint.client.api;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.UastAdditionalChecker;
|
||||
import org.jetbrains.uast.UastConverter;
|
||||
import org.jetbrains.uast.java.JavaConverter;
|
||||
import org.jetbrains.uast.java.JavaUastLanguagePlugin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class JavaLintLanguageExtension extends LintLanguageExtension {
|
||||
@NotNull
|
||||
@Override
|
||||
public UastConverter getConverter() {
|
||||
return JavaConverter.INSTANCE;
|
||||
return JavaUastLanguagePlugin.INSTANCE.getConverter();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<UastAdditionalChecker> getAdditionalCheckers() {
|
||||
return JavaUastLanguagePlugin.INSTANCE.getAdditionalCheckers();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.io.Files;
|
||||
import org.jetbrains.uast.UastConverter;
|
||||
import org.jetbrains.uast.UastLanguagePlugin;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
@@ -386,7 +386,7 @@ public abstract class LintClient {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<UastConverter> getConverters() {
|
||||
public List<UastLanguagePlugin> getLanguagePlugins() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
@@ -1445,7 +1445,7 @@ public class LintDriver {
|
||||
if (ideaProject == null) {
|
||||
return;
|
||||
}
|
||||
List<UastConverter> converters = mClient.getConverters();
|
||||
List<UastLanguagePlugin> plugins = mClient.getLanguagePlugins();
|
||||
|
||||
for (JavaContext context : contexts) {
|
||||
fireEvent(LintListener.EventType.SCANNING_FILE, context);
|
||||
@@ -1456,10 +1456,10 @@ public class LintDriver {
|
||||
UastVisitor customVisitor = scanner.createUastVisitor(context);
|
||||
if (customVisitor != null) {
|
||||
UastChecker.INSTANCE.checkWithCustomHandler(
|
||||
ideaProject, context.file, converters, customVisitor);
|
||||
ideaProject, context.file, plugins, customVisitor);
|
||||
} else {
|
||||
UastChecker.INSTANCE.check(
|
||||
ideaProject, context.file, (UastScanner)check, converters, context);
|
||||
ideaProject, context.file, (UastScanner)check, plugins, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1498,7 +1498,7 @@ public class LintDriver {
|
||||
}
|
||||
|
||||
UastChecker checker = UastChecker.INSTANCE;
|
||||
List<UastConverter> converters = project.getClient().getConverters();
|
||||
List<UastLanguagePlugin> plugins = project.getClient().getLanguagePlugins();
|
||||
|
||||
for (File file : files) {
|
||||
if (!file.isFile()) {
|
||||
@@ -1506,7 +1506,7 @@ public class LintDriver {
|
||||
}
|
||||
|
||||
String path = file.getPath();
|
||||
if (!path.endsWith(DOT_JAVA) && !UastConverterUtils.isFileSupported(converters, path)) {
|
||||
if (!path.endsWith(DOT_JAVA) && !UastConverterUtils.isFileSupported(plugins, path)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1516,9 +1516,9 @@ public class LintDriver {
|
||||
for (UastScanner detector : detectors) {
|
||||
UastVisitor customHandler = detector.createUastVisitor(context);
|
||||
if (customHandler != null) {
|
||||
checker.checkWithCustomHandler(intellijProject, file, converters, customHandler);
|
||||
checker.checkWithCustomHandler(intellijProject, file, plugins, customHandler);
|
||||
} else {
|
||||
checker.check(intellijProject, file, detector, converters, context);
|
||||
checker.check(intellijProject, file, detector, plugins, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2043,9 +2043,8 @@ public class LintDriver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UastConverter> getConverters() {
|
||||
return mDelegate.getConverters();
|
||||
|
||||
public List<UastLanguagePlugin> getLanguagePlugins() {
|
||||
return mDelegate.getLanguagePlugins();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-12
@@ -16,22 +16,18 @@
|
||||
|
||||
package com.android.tools.klint.client.api;
|
||||
|
||||
import com.android.annotations.NonNull;
|
||||
import com.android.annotations.Nullable;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.uast.UastConverter;
|
||||
import org.jetbrains.uast.UastLanguagePlugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class LintLanguageExtension {
|
||||
public abstract class LintLanguageExtension implements UastLanguagePlugin {
|
||||
public static final ExtensionPointName<LintLanguageExtension> EP_NAME =
|
||||
ExtensionPointName.create("com.android.tools.lint.client.api.lintLanguageExtension");
|
||||
|
||||
@NonNull
|
||||
public abstract UastConverter getConverter();
|
||||
ExtensionPointName.create("com.android.tools.klint.client.api.lintLanguageExtension");
|
||||
|
||||
public static boolean isFileSupported(@Nullable Project project, String path) {
|
||||
LintLanguageExtension[] extensions = getExtensions(project);
|
||||
@@ -44,16 +40,14 @@ public abstract class LintLanguageExtension {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<UastConverter> getConverters(@Nullable Project project) {
|
||||
public static List<UastLanguagePlugin> getPlugins(@Nullable Project project) {
|
||||
if (project == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
LintLanguageExtension[] languageExtensions = project.getExtensions(EP_NAME);
|
||||
List<UastConverter> converters = new ArrayList<UastConverter>(languageExtensions.length);
|
||||
for (LintLanguageExtension extension : languageExtensions) {
|
||||
converters.add(extension.getConverter());
|
||||
}
|
||||
List<UastLanguagePlugin> converters = new ArrayList<UastLanguagePlugin>(languageExtensions.length);
|
||||
Collections.addAll(converters, languageExtensions);
|
||||
return converters;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,8 +155,8 @@ public class JavaContext extends Context implements UastAndroidContext {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<UastConverter> getConverters() {
|
||||
return getClient().getConverters();
|
||||
public List<UastLanguagePlugin> getLanguagePlugins() {
|
||||
return getClient().getLanguagePlugins();
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.Nullable
|
||||
|
||||
@@ -203,7 +203,7 @@ public enum Scope {
|
||||
scope.add(BINARY_RESOURCE_FILE);
|
||||
scope.add(RESOURCE_FOLDER);
|
||||
} else if (UastConverterUtils.isFileSupported(
|
||||
project.getClient().getConverters(), name)) {
|
||||
project.getClient().getLanguagePlugins(), name)) {
|
||||
scope.add(SOURCE_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-6
@@ -39,7 +39,7 @@ import com.intellij.psi.PsiElementFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
import org.jetbrains.uast.check.UastAndroidContext;
|
||||
import org.jetbrains.uast.java.JavaConverter;
|
||||
import org.jetbrains.uast.java.JavaUastLanguagePlugin;
|
||||
import org.jetbrains.uast.visitor.UastVisitor;
|
||||
|
||||
/**
|
||||
@@ -581,11 +581,12 @@ public abstract class PermissionRequirement {
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(
|
||||
context.getClient().getProject()).getElementFactory();
|
||||
|
||||
UElement node = JavaConverter.INSTANCE.convertWithParent(factory.createClassFromText(
|
||||
"class Test { void test() {\n"
|
||||
+ "boolean result = " + value
|
||||
+ ";\n}\n}"
|
||||
, null).getContainingFile());
|
||||
UElement node = JavaUastLanguagePlugin.INSTANCE.getConverter().
|
||||
convertWithParent(factory.createClassFromText(
|
||||
"class Test { void test() {\n"
|
||||
+ "boolean result = " + value
|
||||
+ ";\n}\n}"
|
||||
, null).getContainingFile());
|
||||
|
||||
if (node != null) {
|
||||
final AtomicReference<UExpression> reference = new AtomicReference<UExpression>();
|
||||
|
||||
+1
-1
@@ -148,7 +148,7 @@ public class AndroidLintExternalAnnotator extends ExternalAnnotator<State, State
|
||||
} else if (fileType == StdFileTypes.PROPERTIES) {
|
||||
scope = Scope.PROPERTY_SCOPE;
|
||||
} else {
|
||||
if (UastConverterUtils.isFileSupported(client.getConverters(), mainFile.getPath())) {
|
||||
if (UastConverterUtils.isFileSupported(client.getLanguagePlugins(), mainFile.getPath())) {
|
||||
scope = Scope.JAVA_FILE_SCOPE;
|
||||
} else {
|
||||
// #collectionInformation above should have prevented this
|
||||
|
||||
+5
-5
@@ -63,7 +63,7 @@ import org.jetbrains.android.sdk.AndroidSdkData;
|
||||
import org.jetbrains.android.sdk.AndroidSdkType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.uast.UastConverter;
|
||||
import org.jetbrains.uast.UastLanguagePlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -87,11 +87,11 @@ public class IntellijLintClient extends com.android.tools.klint.client.api.LintC
|
||||
@Nullable protected Map<com.android.tools.klint.detector.api.Project, Module> myModuleMap;
|
||||
|
||||
@NonNull
|
||||
private List<UastConverter> myConverters;
|
||||
private List<UastLanguagePlugin> myPlugins;
|
||||
|
||||
protected IntellijLintClient(@NonNull Project project) {
|
||||
myProject = project;
|
||||
myConverters = LintLanguageExtension.getConverters(project);
|
||||
myPlugins = LintLanguageExtension.getPlugins(project);
|
||||
}
|
||||
|
||||
/** Creates a lint client for batch inspections */
|
||||
@@ -393,8 +393,8 @@ public class IntellijLintClient extends com.android.tools.klint.client.api.LintC
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UastConverter> getConverters() {
|
||||
return myConverters;
|
||||
public List<UastLanguagePlugin> getLanguagePlugins() {
|
||||
return myPlugins;
|
||||
}
|
||||
|
||||
// Overridden such that lint doesn't complain about missing a bin dir property in the event
|
||||
|
||||
+3
-2
@@ -17,8 +17,9 @@
|
||||
package org.jetbrains.android.inspections.klint
|
||||
|
||||
import com.android.tools.klint.client.api.LintLanguageExtension
|
||||
import org.jetbrains.kotlin.uast.KotlinConverter
|
||||
import org.jetbrains.kotlin.uast.KotlinUastLanguagePlugin
|
||||
|
||||
class KotlinLintLanguageExtension : LintLanguageExtension() {
|
||||
override fun getConverter() = KotlinConverter
|
||||
override val converter = KotlinUastLanguagePlugin.converter
|
||||
override val additionalCheckers = KotlinUastLanguagePlugin.additionalCheckers
|
||||
}
|
||||
+3
-6
@@ -14,11 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.lint
|
||||
package org.jetbrains.uast.check
|
||||
|
||||
import com.android.tools.klint.client.api.LintLanguageExtension
|
||||
import org.jetbrains.kotlin.uast.KotlinConverter
|
||||
import org.jetbrains.uast.UastAdditionalChecker
|
||||
|
||||
class KotlinLintLanguageExtension : LintLanguageExtension() {
|
||||
override fun getConverter() = KotlinConverter
|
||||
}
|
||||
interface AndroidUastAdditionalChecker : UastAdditionalChecker
|
||||
@@ -26,7 +26,7 @@ import com.intellij.psi.PsiManager
|
||||
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.JavaConverter
|
||||
import org.jetbrains.uast.java.JavaUastLanguagePlugin
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
import java.io.File
|
||||
|
||||
@@ -41,12 +41,12 @@ object UastChecker {
|
||||
fun checkWithCustomHandler(
|
||||
project: Project,
|
||||
file: File,
|
||||
converters: List<UastConverter>,
|
||||
converters: List<UastLanguagePlugin>,
|
||||
visitor: UastVisitor) {
|
||||
check(project, file, converters, UastHandler { visitor.handle(it) })
|
||||
}
|
||||
|
||||
fun check(project: Project, file: File, converters: List<UastConverter>, handler: UastHandler) {
|
||||
fun check(project: Project, file: File, plugins: List<UastLanguagePlugin>, handler: UastHandler) {
|
||||
val vfile = VirtualFileManager.getInstance().findFileByUrl("file://" + file.absolutePath) ?: return
|
||||
ApplicationManager.getApplication().runReadAction {
|
||||
val psiFile = PsiManager.getInstance(project).findFile(vfile)
|
||||
@@ -54,11 +54,11 @@ object UastChecker {
|
||||
if (psiFile != null) {
|
||||
when (psiFile) {
|
||||
is PsiJavaFile -> {
|
||||
val ufile = JavaConverter.convert(psiFile)
|
||||
ufile.handleTraverse(handler)
|
||||
val ufile = JavaUastLanguagePlugin.converter.convertWithParent(psiFile)
|
||||
ufile?.handleTraverse(handler)
|
||||
}
|
||||
else -> for (converter in converters) {
|
||||
val ufile = converter.convertWithParent(psiFile)
|
||||
else -> for (plugin in plugins) {
|
||||
val ufile = plugin.converter.convertWithParent(psiFile)
|
||||
if (ufile != null) {
|
||||
ufile.handleTraverse(handler)
|
||||
break
|
||||
@@ -69,12 +69,20 @@ object UastChecker {
|
||||
}
|
||||
}
|
||||
|
||||
fun check(project: Project, file: File, scanner: UastScanner, converters: List<UastConverter>, context: UastAndroidContext) {
|
||||
fun check(project: Project, file: File, scanner: UastScanner, plugins: List<UastLanguagePlugin>, context: UastAndroidContext) {
|
||||
val applicableFunctionNames = scanner.applicableFunctionNames ?: emptyList()
|
||||
val applicableSuperClasses = scanner.applicableSuperClasses ?: emptyList()
|
||||
val applicableConstructorTypes = scanner.applicableConstructorTypes ?: emptyList()
|
||||
|
||||
check(project, file, converters, UastHandler { element ->
|
||||
val additionalCheckers = plugins.fold(mutableListOf<UastAdditionalChecker>()) { list, plugin ->
|
||||
for (checker in plugin.additionalCheckers) {
|
||||
if (checker is AndroidUastAdditionalChecker) list += checker
|
||||
}
|
||||
list
|
||||
}
|
||||
|
||||
var handler: UastHandler? = null
|
||||
handler = UastHandler { element ->
|
||||
when (element) {
|
||||
is UCallExpression -> {
|
||||
if (applicableFunctionNames.isNotEmpty()) {
|
||||
@@ -99,7 +107,13 @@ object UastChecker {
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
for (checker in additionalCheckers) {
|
||||
checker(element, handler!!, context)
|
||||
}
|
||||
}
|
||||
|
||||
check(project, file, plugins, handler)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,15 +16,15 @@
|
||||
package org.jetbrains.uast
|
||||
|
||||
interface UastContext {
|
||||
val converters: List<UastConverter>
|
||||
val languagePlugins: List<UastLanguagePlugin>
|
||||
|
||||
fun convert(element: Any?): UElement? {
|
||||
if (element == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
for (converter in converters) {
|
||||
val uelement = converter.convertWithParent(element)
|
||||
for (plugin in languagePlugins) {
|
||||
val uelement = plugin.converter.convertWithParent(element)
|
||||
if (uelement != null) {
|
||||
return uelement
|
||||
}
|
||||
|
||||
+11
-2
@@ -22,9 +22,18 @@ interface UastConverter {
|
||||
fun isFileSupported(path: String): Boolean
|
||||
}
|
||||
|
||||
interface UastLanguagePlugin {
|
||||
val converter: UastConverter
|
||||
val additionalCheckers: List<UastAdditionalChecker>
|
||||
}
|
||||
|
||||
interface UastAdditionalChecker {
|
||||
operator fun invoke(element: UElement, handler: UastHandler, context: UastContext)
|
||||
}
|
||||
|
||||
object UastConverterUtils {
|
||||
@JvmStatic
|
||||
fun isFileSupported(converters: List<UastConverter>, path: String): Boolean {
|
||||
return converters.any { it.isFileSupported(path) }
|
||||
fun isFileSupported(converters: List<UastLanguagePlugin>, path: String): Boolean {
|
||||
return converters.any { it.converter.isFileSupported(path) }
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -19,7 +19,12 @@ package org.jetbrains.uast.java
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
object JavaConverter : UastConverter {
|
||||
object JavaUastLanguagePlugin : UastLanguagePlugin {
|
||||
override val converter: UastConverter = JavaConverter
|
||||
override val additionalCheckers = emptyList<UastAdditionalChecker>()
|
||||
}
|
||||
|
||||
internal object JavaConverter : UastConverter {
|
||||
override fun isFileSupported(path: String): Boolean {
|
||||
return path.endsWith(".java", ignoreCase = true)
|
||||
}
|
||||
+9
-3
@@ -25,9 +25,15 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.uast.lint.PropertyAsCallAndroidUastAdditionalChecker
|
||||
import org.jetbrains.uast.*
|
||||
|
||||
object KotlinConverter : UastConverter {
|
||||
object KotlinUastLanguagePlugin : UastLanguagePlugin {
|
||||
override val converter: UastConverter = KotlinConverter
|
||||
override val additionalCheckers = listOf(PropertyAsCallAndroidUastAdditionalChecker())
|
||||
}
|
||||
|
||||
internal object KotlinConverter : UastConverter {
|
||||
override fun isFileSupported(path: String) = path.endsWith(".kt", false) || path.endsWith(".kts", false)
|
||||
|
||||
override fun convert(element: Any?, parent: UElement): UElement? {
|
||||
@@ -142,7 +148,7 @@ object KotlinConverter : UastConverter {
|
||||
is KtBlockExpression -> KotlinUBlockExpression(expression, parent)
|
||||
is KtConstantExpression -> KotlinULiteralExpression(expression, parent)
|
||||
is KtTryExpression -> KotlinUTryExpression(expression, parent)
|
||||
is KtArrayAccessExpression -> KotlinUArrayAccess(expression, parent)
|
||||
is KtArrayAccessExpression -> KotlinUArrayAccessExpression(expression, parent)
|
||||
is KtLambdaExpression -> KotlinULambdaExpression(expression, parent)
|
||||
is KtBinaryExpressionWithTypeRHS -> KotlinUBinaryExpressionWithType(expression, parent)
|
||||
|
||||
@@ -166,7 +172,7 @@ object KotlinConverter : UastConverter {
|
||||
|
||||
internal fun asSimpleReference(element: PsiElement?, parent: UElement): USimpleReferenceExpression? {
|
||||
if (element == null) return null
|
||||
return KotlinUSimpleReferenceExpression(element, KtPsiUtil.unquoteIdentifier(element.text), parent)
|
||||
return KotlinNameUSimpleReferenceExpression(element, KtPsiUtil.unquoteIdentifier(element.text), parent)
|
||||
}
|
||||
|
||||
internal fun convertOrEmpty(expression: KtExpression?, parent: UElement): UExpression {
|
||||
Reference in New Issue
Block a user