Lint: support both IJ 15 and Android Studio 2.0 (different Android plugins)
Dirty hack :(
This commit is contained in:
@@ -14,5 +14,6 @@
|
|||||||
<orderEntry type="library" name="android-plugin" level="project" />
|
<orderEntry type="library" name="android-plugin" level="project" />
|
||||||
<orderEntry type="library" name="intellij-core" level="project" />
|
<orderEntry type="library" name="intellij-core" level="project" />
|
||||||
<orderEntry type="module" module-name="android-annotations" />
|
<orderEntry type="module" module-name="android-annotations" />
|
||||||
|
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
@@ -685,7 +685,7 @@ public abstract class LintClient {
|
|||||||
@NonNull
|
@NonNull
|
||||||
public IAndroidTarget[] getTargets() {
|
public IAndroidTarget[] getTargets() {
|
||||||
if (mTargets == null) {
|
if (mTargets == null) {
|
||||||
LocalSdk localSdk = getSdk();
|
SdkWrapper localSdk = getSdk();
|
||||||
if (localSdk != null) {
|
if (localSdk != null) {
|
||||||
mTargets = localSdk.getTargets();
|
mTargets = localSdk.getTargets();
|
||||||
} else {
|
} else {
|
||||||
@@ -696,7 +696,7 @@ public abstract class LintClient {
|
|||||||
return mTargets;
|
return mTargets;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected LocalSdk mSdk;
|
protected SdkWrapper mSdk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the SDK installation (used to look up platforms etc)
|
* Returns the SDK installation (used to look up platforms etc)
|
||||||
@@ -704,11 +704,11 @@ public abstract class LintClient {
|
|||||||
* @return the SDK if known
|
* @return the SDK if known
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public LocalSdk getSdk() {
|
public SdkWrapper getSdk() {
|
||||||
if (mSdk == null) {
|
if (mSdk == null) {
|
||||||
File sdkHome = getSdkHome();
|
File sdkHome = getSdkHome();
|
||||||
if (sdkHome != null) {
|
if (sdkHome != null) {
|
||||||
mSdk = new LocalSdk(sdkHome);
|
mSdk = SdkWrapper.createLocalSdk(sdkHome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1927,7 +1927,7 @@ public class LintDriver {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public LocalSdk getSdk() {
|
public SdkWrapper getSdk() {
|
||||||
return mDelegate.getSdk();
|
return mDelegate.getSdk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.android.tools.klint.client.api
|
||||||
|
|
||||||
|
import com.android.sdklib.IAndroidTarget
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class SdkWrapper(val sdk: Any) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val PROGRESS_INDICATOR_CLASS_NAME = "com.android.repository.api.ConsoleProgressIndicator"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun createLocalSdk(file: File): SdkWrapper? {
|
||||||
|
try {
|
||||||
|
val clazz = Class.forName("com.android.sdklib.repository.local.LocalSdk")
|
||||||
|
return SdkWrapper(clazz.getConstructor(File::class.java).newInstance(file))
|
||||||
|
}
|
||||||
|
catch (t: Throwable) {
|
||||||
|
try {
|
||||||
|
val clazz = Class.forName("com.android.sdklib.repositoryv2.AndroidSdkHandler")
|
||||||
|
return SdkWrapper(clazz.getMethod("getInstance", File::class.java).invoke(null, file))
|
||||||
|
}
|
||||||
|
catch (t2: Throwable) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTargets(): Array<IAndroidTarget>? {
|
||||||
|
try {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return sdk.javaClass.getMethod("getTargets").invoke(sdk) as? Array<IAndroidTarget>
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
try {
|
||||||
|
val targets = sdk.javaClass
|
||||||
|
.getMethod("getAndroidTargetManager", Class.forName(PROGRESS_INDICATOR_CLASS_NAME))
|
||||||
|
.invoke(sdk, createProgressIndicator()) as? Collection<IAndroidTarget> ?: return null
|
||||||
|
return targets.toTypedArray()
|
||||||
|
}
|
||||||
|
catch (t2: Throwable) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPlatformVersion(): String? {
|
||||||
|
try {
|
||||||
|
val pkgPlatformTools = Class.forName("com.android.sdklib.repository.descriptors.PkgType")
|
||||||
|
.getField("PKG_PLATFORM_TOOLS").get(null)
|
||||||
|
val pkgInfo = sdk.javaClass.declaredMethods
|
||||||
|
.first { it.name == "getPkgInfo" && it.parameterTypes.size == 1 }
|
||||||
|
.invoke(sdk, pkgPlatformTools)
|
||||||
|
if (pkgInfo != null) {
|
||||||
|
val desc = pkgInfo.javaClass.getMethod("getDesc").invoke(pkgInfo)
|
||||||
|
val version = desc.javaClass.getMethod("getFullRevision").invoke(desc)
|
||||||
|
if (version != null) {
|
||||||
|
return version.javaClass.getMethod("toShortString").invoke(version) as? String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
try {
|
||||||
|
val pkgPlatformTools = Class.forName("com.android.SdkConstants")
|
||||||
|
.getField("FD_PLATFORM_TOOLS").get(null)
|
||||||
|
val pkgInfo = sdk.javaClass.declaredMethods
|
||||||
|
.first { it.name == "getLocalPackage" && it.parameterTypes.size == 2 }
|
||||||
|
.invoke(sdk, pkgPlatformTools, createProgressIndicator())
|
||||||
|
if (pkgInfo != null) {
|
||||||
|
val version = pkgInfo.javaClass.getMethod("getVersion").invoke(pkgInfo)
|
||||||
|
return version.javaClass.getMethod("toShortString").invoke(version) as? String
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ignore: Throwable) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createProgressIndicator(): Any {
|
||||||
|
return Class.forName(PROGRESS_INDICATOR_CLASS_NAME).newInstance()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,11 +22,8 @@ import static com.android.SdkConstants.DOT_XML;
|
|||||||
import com.android.annotations.NonNull;
|
import com.android.annotations.NonNull;
|
||||||
import com.android.annotations.Nullable;
|
import com.android.annotations.Nullable;
|
||||||
import com.android.annotations.VisibleForTesting;
|
import com.android.annotations.VisibleForTesting;
|
||||||
import com.android.sdklib.repository.FullRevision;
|
|
||||||
import com.android.sdklib.repository.descriptors.PkgType;
|
|
||||||
import com.android.sdklib.repository.local.LocalPkgInfo;
|
|
||||||
import com.android.sdklib.repository.local.LocalSdk;
|
|
||||||
import com.android.tools.klint.client.api.LintClient;
|
import com.android.tools.klint.client.api.LintClient;
|
||||||
|
import com.android.tools.klint.client.api.SdkWrapper;
|
||||||
import com.android.tools.klint.detector.api.LintUtils;
|
import com.android.tools.klint.detector.api.LintUtils;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
@@ -138,15 +135,9 @@ public class ApiLookup {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@Nullable
|
@Nullable
|
||||||
static String getPlatformVersion(@NonNull LintClient client) {
|
static String getPlatformVersion(@NonNull LintClient client) {
|
||||||
LocalSdk sdk = client.getSdk();
|
SdkWrapper sdk = client.getSdk();
|
||||||
if (sdk != null) {
|
if (sdk != null) {
|
||||||
LocalPkgInfo pkgInfo = sdk.getPkgInfo(PkgType.PKG_PLATFORM_TOOLS);
|
return sdk.getPlatformVersion();
|
||||||
if (pkgInfo != null) {
|
|
||||||
FullRevision version = pkgInfo.getDesc().getFullRevision();
|
|
||||||
if (version != null) {
|
|
||||||
return version.toShortString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+9
@@ -4,6 +4,7 @@ import com.android.builder.model.AndroidProject
|
|||||||
import com.android.builder.model.SourceProvider
|
import com.android.builder.model.SourceProvider
|
||||||
import com.android.builder.model.Variant
|
import com.android.builder.model.Variant
|
||||||
import com.android.tools.idea.gradle.util.GradleUtil
|
import com.android.tools.idea.gradle.util.GradleUtil
|
||||||
|
import com.android.tools.klint.client.api.SdkWrapper
|
||||||
import org.jetbrains.android.facet.AndroidFacet
|
import org.jetbrains.android.facet.AndroidFacet
|
||||||
import kotlin.reflect.memberFunctions
|
import kotlin.reflect.memberFunctions
|
||||||
import kotlin.reflect.staticFunctions
|
import kotlin.reflect.staticFunctions
|
||||||
@@ -19,6 +20,14 @@ class AndroidModelFacade(val facet: AndroidFacet) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getLocalSdk(): SdkWrapper? {
|
||||||
|
val sdkData = facet.sdkData ?: return null
|
||||||
|
val localSdk = sdkData.javaClass.kotlin.memberFunctions
|
||||||
|
.firstOrNull { it.name == "getLocalSdk" || it.name == "getSdkHandler" }
|
||||||
|
?.call(sdkData) ?: return null
|
||||||
|
return SdkWrapper(localSdk)
|
||||||
|
}
|
||||||
|
|
||||||
fun isModelReady() = model != null
|
fun isModelReady() = model != null
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
|||||||
+4
-10
@@ -7,8 +7,6 @@ import com.android.ide.common.repository.ResourceVisibilityLookup;
|
|||||||
import com.android.ide.common.res2.AbstractResourceRepository;
|
import com.android.ide.common.res2.AbstractResourceRepository;
|
||||||
import com.android.ide.common.res2.ResourceFile;
|
import com.android.ide.common.res2.ResourceFile;
|
||||||
import com.android.ide.common.res2.ResourceItem;
|
import com.android.ide.common.res2.ResourceItem;
|
||||||
import com.android.sdklib.repository.local.LocalSdk;
|
|
||||||
import com.android.tools.idea.gradle.util.Projects;
|
|
||||||
import com.android.tools.idea.rendering.AppResourceRepository;
|
import com.android.tools.idea.rendering.AppResourceRepository;
|
||||||
import com.android.tools.idea.rendering.LocalResourceRepository;
|
import com.android.tools.idea.rendering.LocalResourceRepository;
|
||||||
import com.android.tools.idea.sdk.IdeSdks;
|
import com.android.tools.idea.sdk.IdeSdks;
|
||||||
@@ -50,7 +48,6 @@ import com.intellij.util.containers.HashMap;
|
|||||||
import com.intellij.util.net.HttpConfigurable;
|
import com.intellij.util.net.HttpConfigurable;
|
||||||
import org.jetbrains.android.facet.AndroidFacet;
|
import org.jetbrains.android.facet.AndroidFacet;
|
||||||
import org.jetbrains.android.facet.AndroidRootUtil;
|
import org.jetbrains.android.facet.AndroidRootUtil;
|
||||||
import org.jetbrains.android.sdk.AndroidSdkData;
|
|
||||||
import org.jetbrains.android.sdk.AndroidSdkType;
|
import org.jetbrains.android.sdk.AndroidSdkType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -329,10 +326,10 @@ public class IntellijLintClient extends LintClient implements Disposable {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public LocalSdk getSdk() {
|
public SdkWrapper getSdk() {
|
||||||
if (mSdk == null) {
|
if (mSdk == null) {
|
||||||
Module module = getModule();
|
Module module = getModule();
|
||||||
LocalSdk sdk = getLocalSdk(module);
|
SdkWrapper sdk = getLocalSdk(module);
|
||||||
if (sdk != null) {
|
if (sdk != null) {
|
||||||
mSdk = sdk;
|
mSdk = sdk;
|
||||||
} else {
|
} else {
|
||||||
@@ -354,14 +351,11 @@ public class IntellijLintClient extends LintClient implements Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static LocalSdk getLocalSdk(@Nullable Module module) {
|
private static SdkWrapper getLocalSdk(@Nullable Module module) {
|
||||||
if (module != null) {
|
if (module != null) {
|
||||||
AndroidFacet facet = AndroidFacet.getInstance(module);
|
AndroidFacet facet = AndroidFacet.getInstance(module);
|
||||||
if (facet != null) {
|
if (facet != null) {
|
||||||
AndroidSdkData sdkData = facet.getSdkData();
|
return IntellijLintUtils.getModelFacade(facet).getLocalSdk();
|
||||||
if (sdkData != null) {
|
|
||||||
return sdkData.getLocalSdk();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user