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="intellij-core" level="project" />
|
||||
<orderEntry type="module" module-name="android-annotations" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -685,7 +685,7 @@ public abstract class LintClient {
|
||||
@NonNull
|
||||
public IAndroidTarget[] getTargets() {
|
||||
if (mTargets == null) {
|
||||
LocalSdk localSdk = getSdk();
|
||||
SdkWrapper localSdk = getSdk();
|
||||
if (localSdk != null) {
|
||||
mTargets = localSdk.getTargets();
|
||||
} else {
|
||||
@@ -696,7 +696,7 @@ public abstract class LintClient {
|
||||
return mTargets;
|
||||
}
|
||||
|
||||
protected LocalSdk mSdk;
|
||||
protected SdkWrapper mSdk;
|
||||
|
||||
/**
|
||||
* Returns the SDK installation (used to look up platforms etc)
|
||||
@@ -704,11 +704,11 @@ public abstract class LintClient {
|
||||
* @return the SDK if known
|
||||
*/
|
||||
@Nullable
|
||||
public LocalSdk getSdk() {
|
||||
public SdkWrapper getSdk() {
|
||||
if (mSdk == null) {
|
||||
File sdkHome = getSdkHome();
|
||||
if (sdkHome != null) {
|
||||
mSdk = new LocalSdk(sdkHome);
|
||||
mSdk = SdkWrapper.createLocalSdk(sdkHome);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1927,7 +1927,7 @@ public class LintDriver {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public LocalSdk getSdk() {
|
||||
public SdkWrapper 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.Nullable;
|
||||
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.SdkWrapper;
|
||||
import com.android.tools.klint.detector.api.LintUtils;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -138,15 +135,9 @@ public class ApiLookup {
|
||||
@VisibleForTesting
|
||||
@Nullable
|
||||
static String getPlatformVersion(@NonNull LintClient client) {
|
||||
LocalSdk sdk = client.getSdk();
|
||||
SdkWrapper sdk = client.getSdk();
|
||||
if (sdk != null) {
|
||||
LocalPkgInfo pkgInfo = sdk.getPkgInfo(PkgType.PKG_PLATFORM_TOOLS);
|
||||
if (pkgInfo != null) {
|
||||
FullRevision version = pkgInfo.getDesc().getFullRevision();
|
||||
if (version != null) {
|
||||
return version.toShortString();
|
||||
}
|
||||
}
|
||||
return sdk.getPlatformVersion();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+9
@@ -4,6 +4,7 @@ import com.android.builder.model.AndroidProject
|
||||
import com.android.builder.model.SourceProvider
|
||||
import com.android.builder.model.Variant
|
||||
import com.android.tools.idea.gradle.util.GradleUtil
|
||||
import com.android.tools.klint.client.api.SdkWrapper
|
||||
import org.jetbrains.android.facet.AndroidFacet
|
||||
import kotlin.reflect.memberFunctions
|
||||
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
|
||||
|
||||
@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.ResourceFile;
|
||||
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.LocalResourceRepository;
|
||||
import com.android.tools.idea.sdk.IdeSdks;
|
||||
@@ -50,7 +48,6 @@ import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.net.HttpConfigurable;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.facet.AndroidRootUtil;
|
||||
import org.jetbrains.android.sdk.AndroidSdkData;
|
||||
import org.jetbrains.android.sdk.AndroidSdkType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -329,10 +326,10 @@ public class IntellijLintClient extends LintClient implements Disposable {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public LocalSdk getSdk() {
|
||||
public SdkWrapper getSdk() {
|
||||
if (mSdk == null) {
|
||||
Module module = getModule();
|
||||
LocalSdk sdk = getLocalSdk(module);
|
||||
SdkWrapper sdk = getLocalSdk(module);
|
||||
if (sdk != null) {
|
||||
mSdk = sdk;
|
||||
} else {
|
||||
@@ -354,14 +351,11 @@ public class IntellijLintClient extends LintClient implements Disposable {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static LocalSdk getLocalSdk(@Nullable Module module) {
|
||||
private static SdkWrapper getLocalSdk(@Nullable Module module) {
|
||||
if (module != null) {
|
||||
AndroidFacet facet = AndroidFacet.getInstance(module);
|
||||
if (facet != null) {
|
||||
AndroidSdkData sdkData = facet.getSdkData();
|
||||
if (sdkData != null) {
|
||||
return sdkData.getLocalSdk();
|
||||
}
|
||||
return IntellijLintUtils.getModelFacade(facet).getLocalSdk();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user