Remove as32 bunch files

This commit is contained in:
Vyacheslav Gerasimov
2019-04-19 18:43:46 +03:00
parent 952d2b6287
commit 2bc11cbd58
99 changed files with 0 additions and 7717 deletions
-8
View File
@@ -1,8 +0,0 @@
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m -Dfile.encoding=UTF-8
cacheRedirectorEnabled=true
#buildSrc.kotlin.repo=https://jcenter.bintray.com
#buildSrc.kotlin.version=1.1.50
intellijUltimateEnabled=false
-236
View File
@@ -1,236 +0,0 @@
-injars '<kotlin-compiler-jar-before-shrink>'(
!org/apache/log4j/jmx/Agent*,
!org/apache/log4j/net/JMS*,
!org/apache/log4j/net/SMTP*,
!org/apache/log4j/or/jms/MessageRenderer*,
!org/jdom/xpath/Jaxen*,
!org/jline/builtins/ssh/**,
!org/mozilla/javascript/xml/impl/xmlbeans/**,
!net/sf/cglib/**,
!META-INF/maven**,
**.class,**.properties,**.kt,**.kotlin_*,**.jnilib,**.so,**.dll,**.txt,**.caps,
META-INF/services/**,META-INF/native/**,META-INF/extensions/**,META-INF/MANIFEST.MF,
messages/**)
-outjars '<kotlin-compiler-jar>'
-dontnote **
-dontwarn com.intellij.util.ui.IsRetina*
-dontwarn com.intellij.util.RetinaImage*
-dontwarn apple.awt.*
-dontwarn dk.brics.automaton.*
-dontwarn org.fusesource.**
-dontwarn org.imgscalr.Scalr**
-dontwarn org.xerial.snappy.SnappyBundleActivator
-dontwarn com.intellij.util.CompressionUtil
-dontwarn com.intellij.util.SnappyInitializer
-dontwarn com.intellij.util.SVGLoader
-dontwarn com.intellij.util.SVGLoader$MyTranscoder
-dontwarn net.sf.cglib.**
-dontwarn org.objectweb.asm.** # this is ASM3, the old version that we do not use
-dontwarn com.sun.jna.NativeString
-dontwarn com.sun.jna.WString
-dontwarn com.intellij.psi.util.PsiClassUtil
-dontwarn org.apache.hadoop.io.compress.*
-dontwarn com.google.j2objc.annotations.Weak
-dontwarn org.iq80.snappy.HadoopSnappyCodec$SnappyCompressionInputStream
-dontwarn org.iq80.snappy.HadoopSnappyCodec$SnappyCompressionOutputStream
-dontwarn com.google.common.util.concurrent.*
-dontwarn org.apache.xerces.dom.**
-dontwarn org.apache.xerces.util.**
-dontwarn org.w3c.dom.ElementTraversal
-dontwarn javaslang.match.annotation.Unapply
-dontwarn javaslang.match.annotation.Patterns
-dontwarn javaslang.*
-dontwarn com.google.errorprone.**
-dontwarn com.google.j2objc.**
-dontwarn javax.crypto.**
-dontwarn java.lang.invoke.MethodHandle
-dontwarn org.jline.builtins.Nano$Buffer
-dontwarn net.jpountz.lz4.LZ4Factory
-dontwarn org.jetbrains.annotations.ReadOnly
-dontwarn org.jetbrains.annotations.Mutable
-dontwarn com.intellij.util.io.TarUtil
# Annotations from intellijCore/annotations.jar that not presented in org.jetbrains.annotations
-dontwarn org.jetbrains.annotations.Async*
-dontwarn org.jetbrains.annotations.Nls$Capitalization
# Depends on apache batick which has lots of dependencies
-dontwarn com.intellij.util.SVGLoader*
# The appropriate jar is either loaded separately or added explicitly to the classpath then needed
-dontwarn org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar
#-libraryjars '<rtjar>'
#-libraryjars '<jssejar>'
#-libraryjars '<bootstrap.runtime>'
#-libraryjars '<bootstrap.reflect>'
#-libraryjars '<bootstrap.script.runtime>'
#-libraryjars '<tools.jar>'
-dontoptimize
-dontobfuscate
-keep class org.fusesource.** { *; }
-keep class com.sun.jna.** { *; }
-keep class org.jetbrains.annotations.** {
public protected *;
}
-keep class javax.inject.** {
public protected *;
}
-keep class org.jetbrains.kotlin.** {
public protected *;
}
-keep class org.jetbrains.kotlin.compiler.plugin.** {
public protected *;
}
-keep class org.jetbrains.kotlin.extensions.** {
public protected *;
}
-keep class org.jetbrains.kotlin.protobuf.** {
public protected *;
}
-keep class org.jetbrains.kotlin.container.** { *; }
-keep class org.jetbrains.org.objectweb.asm.Opcodes { *; }
-keep class org.jetbrains.kotlin.codegen.extensions.** {
public protected *;
}
-keepclassmembers class com.intellij.openapi.vfs.VirtualFile {
public protected *;
}
-keep class com.intellij.openapi.vfs.StandardFileSystems {
public static *;
}
# needed for jar cache cleanup in the gradle plugin and compile daemon
-keepclassmembers class com.intellij.openapi.vfs.impl.ZipHandler {
public static void clearFileAccessorCache();
}
-keep class jet.** {
public protected *;
}
-keep class com.intellij.psi.** {
public protected *;
}
# This is needed so that the platform code which parses XML wouldn't fail, see KT-16968
# This API is used from org.jdom.input.SAXBuilder via reflection.
-keep class org.jdom.input.JAXPParserFactory { public ** createParser(...); }
# for kdoc & dokka
-keep class com.intellij.openapi.util.TextRange { *; }
-keep class com.intellij.lang.impl.PsiBuilderImpl* {
public protected *;
}
-keep class com.intellij.openapi.util.text.StringHash { *; }
# for j2k
-keep class com.intellij.codeInsight.NullableNotNullManager { public protected *; }
# for gradle (see KT-12549)
-keep class com.intellij.lang.properties.charset.Native2AsciiCharsetProvider { *; }
# for kotlin-build-common (consider repacking compiler together with kotlin-build-common and remove this part afterwards)
-keep class com.intellij.util.io.IOUtil { public *; }
-keep class com.intellij.openapi.util.io.FileUtil { public *; }
-keep class com.intellij.util.SystemProperties { public *; }
-keep class com.intellij.util.containers.hash.LinkedHashMap { *; }
-keep class com.intellij.util.containers.ConcurrentIntObjectMap { *; }
-keep class com.intellij.util.containers.ComparatorUtil { *; }
-keep class com.intellij.util.io.PersistentHashMapValueStorage { *; }
-keep class com.intellij.util.io.PersistentHashMap { *; }
-keep class com.intellij.util.io.BooleanDataDescriptor { *; }
-keep class com.intellij.util.io.EnumeratorStringDescriptor { *; }
-keep class com.intellij.util.io.ExternalIntegerKeyDescriptor { *; }
-keep class com.intellij.util.containers.hash.EqualityPolicy { *; }
-keep class com.intellij.util.containers.hash.EqualityPolicy.* { *; }
-keep class com.intellij.util.containers.Interner { *; }
-keep class gnu.trove.TIntHashSet { *; }
-keep class gnu.trove.TIntIterator { *; }
-keep class org.iq80.snappy.SlowMemory { *; }
-keep class javaslang.match.PatternsProcessor { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * {
** toString();
** hashCode();
void start();
void stop();
void dispose();
}
-keep class org.jetbrains.org.objectweb.asm.tree.AnnotationNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.ClassNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.LocalVariableNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.MethodNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.FieldNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.ParameterNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.TypeAnnotationNode { *; }
-keep class org.jetbrains.org.objectweb.asm.signature.SignatureReader { *; }
-keep class org.jetbrains.org.objectweb.asm.signature.SignatureVisitor { *; }
-keep class org.jetbrains.org.objectweb.asm.Type {
public protected *;
}
-keepclassmembers class org.jetbrains.org.objectweb.asm.ClassReader {
*** SKIP_CODE;
*** SKIP_DEBUG;
*** SKIP_FRAMES;
}
-keepclassmembers class com.intellij.openapi.project.Project {
** getBasePath();
}
# for kotlin-android-extensions in maven
-keep class com.intellij.openapi.module.ModuleServiceManager { public *; }
# for building kotlin-build-common-test
-keep class org.jetbrains.kotlin.build.SerializationUtilsKt { *; }
# for tools.jar
-keep class com.sun.tools.javac.** { *; }
-keep class com.sun.source.** { *; }
# for coroutines
-keep class kotlinx.coroutines.** { *; }
# for webdemo
-keep class com.intellij.openapi.progress.ProgressManager { *; }
# for kapt
-keep class com.intellij.openapi.project.Project { *; }
-keepclassmembers class com.intellij.util.PathUtil {
public static java.lang.String getJarPathForClass(java.lang.Class);
}
-keepclassmembers class com.intellij.util.PathUtil {
public static java.lang.String getJarPathForClass(java.lang.Class);
}
# remove when KT-18563 would be fixed
-keep class org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt { *; }
# used in LazyScriptDescriptor
-keep class org.jetbrains.kotlin.utils.addToStdlib.AddToStdlibKt { *; }
@@ -1,133 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.load.java.structure.impl
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiTypeParameter
import com.intellij.psi.search.SearchScope
import org.jetbrains.kotlin.asJava.KtLightClassMarker
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.psi.psiUtil.contains
class JavaClassImpl(psiClass: PsiClass) : JavaClassifierImpl<PsiClass>(psiClass), VirtualFileBoundJavaClass, JavaAnnotationOwnerImpl, JavaModifierListOwnerImpl {
init {
assert(psiClass !is PsiTypeParameter) { "PsiTypeParameter should be wrapped in JavaTypeParameter, not JavaClass: use JavaClassifier.create()" }
}
override val innerClassNames: Collection<Name>
get() = psi.innerClasses.mapNotNull { it.name?.takeIf(Name::isValidIdentifier)?.let(Name::identifier) }
override fun findInnerClass(name: Name): JavaClass? {
return psi.findInnerClassByName(name.asString(), false)?.let(::JavaClassImpl)
}
override val fqName: FqName?
get() {
val qualifiedName = psi.qualifiedName
return if (qualifiedName == null) null else FqName(qualifiedName)
}
override val name: Name
get() = KtPsiUtil.safeName(psi.name)
override val isInterface: Boolean
get() = psi.isInterface
override val isAnnotationType: Boolean
get() = psi.isAnnotationType
override val isEnum: Boolean
get() = psi.isEnum
override val outerClass: JavaClassImpl?
get() {
val outer = psi.containingClass
return if (outer == null) null else JavaClassImpl(outer)
}
override val typeParameters: List<JavaTypeParameter>
get() = typeParameters(psi.typeParameters)
override val supertypes: Collection<JavaClassifierType>
get() = classifierTypes(psi.superTypes)
override val methods: Collection<JavaMethod>
get() {
assertNotLightClass()
// We apply distinct here because PsiClass#getMethods() can return duplicate PSI methods, for example in Lombok (see KT-11778)
// Return type seems to be null for example for the 'clone' Groovy method generated by @AutoClone (see EA-73795)
return methods(psi.methods.filter { method -> !method.isConstructor && method.returnType != null }).distinct()
}
override val fields: Collection<JavaField>
get() {
assertNotLightClass()
return fields(psi.fields.filter { field ->
val name = field.name
// ex. Android plugin generates LightFields for resources started from '.' (.DS_Store file etc)
name != null && Name.isValidIdentifier(name)
})
}
override val constructors: Collection<JavaConstructor>
get() {
assertNotLightClass()
// See for example org.jetbrains.plugins.scala.lang.psi.light.ScFunctionWrapper,
// which is present in getConstructors(), but its isConstructor() returns false
return constructors(psi.constructors.filter { method -> method.isConstructor })
}
override val isAbstract: Boolean
get() = JavaElementUtil.isAbstract(this)
override val isStatic: Boolean
get() = JavaElementUtil.isStatic(this)
override val isFinal: Boolean
get() = JavaElementUtil.isFinal(this)
override val visibility: Visibility
get() = JavaElementUtil.getVisibility(this)
override val lightClassOriginKind: LightClassOriginKind?
get() = (psi as? KtLightClassMarker)?.originKind
override val virtualFile: VirtualFile?
get() = psi.containingFile?.virtualFile
override fun isFromSourceCodeInScope(scope: SearchScope): Boolean = psi.containingFile in scope
override fun getAnnotationOwnerPsi() = psi.modifierList
private fun assertNotLightClass() {
val psiClass = psi
if (psiClass !is KtLightClassMarker) return
val message = "Querying members of JavaClass created for $psiClass of type ${psiClass::class.java} defined in file ${psiClass.containingFile?.virtualFile?.canonicalPath}"
LOGGER.error(message)
}
companion object {
private val LOGGER = Logger.getInstance(JavaClassImpl::class.java)
}
}
@@ -1,78 +0,0 @@
/*
* Copyright 2010-2015 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.kotlin.load.kotlin
import com.intellij.ide.highlighter.JavaClassFileType
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.util.Computable
import com.intellij.openapi.vfs.VirtualFile
class KotlinBinaryClassCache : Disposable {
private class RequestCache {
internal var virtualFile: VirtualFile? = null
internal var modificationStamp: Long = 0
internal var result: KotlinClassFinder.Result? = null
fun cache(
file: VirtualFile,
result: KotlinClassFinder.Result?
): KotlinClassFinder.Result? {
virtualFile = file
this.result = result
modificationStamp = file.modificationStamp
return result
}
}
private val cache = object : ThreadLocal<RequestCache>() {
override fun initialValue(): RequestCache {
return RequestCache()
}
}
override fun dispose() {
// This is only relevant for tests. We create a new instance of Application for each test, and so a new instance of this service is
// also created for each test. However all tests share the same event dispatch thread, which would collect all instances of this
// thread-local if they're not removed properly. Each instance would transitively retain VFS resulting in OutOfMemoryError
cache.remove()
}
companion object {
fun getKotlinBinaryClassOrClassFileContent(
file: VirtualFile, fileContent: ByteArray? = null
): KotlinClassFinder.Result? {
if (file.fileType !== JavaClassFileType.INSTANCE) return null
val service = ServiceManager.getService(KotlinBinaryClassCache::class.java)
val requestCache = service.cache.get()
if (file.modificationStamp == requestCache.modificationStamp && file == requestCache.virtualFile) {
return requestCache.result
}
val aClass = ApplicationManager.getApplication().runReadAction(Computable {
@Suppress("DEPRECATION")
VirtualFileKotlinClass.create(file, fileContent)
})
return requestCache.cache(file, aClass)
}
}
}
File diff suppressed because it is too large Load Diff
-12
View File
@@ -1,12 +0,0 @@
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m -Dfile.encoding=UTF-8
cacheRedirectorEnabled=true
kotlin.compiler.effectSystemEnabled=true
kotlin.compiler.newInferenceEnabled=true
#maven.repository.mirror=http://repository.jetbrains.com/remote-repos/
#bootstrap.kotlin.repo=https://dl.bintray.com/kotlin/kotlin-dev
#bootstrap.kotlin.version=1.1.50-dev-1451
#signingRequired=true
intellijUltimateEnabled=false
-16
View File
@@ -1,16 +0,0 @@
versions.intellijSdk=181.5540.7
versions.androidBuildTools=r23.0.1
versions.idea.NodeJS=181.2784.17
versions.androidStudioRelease=3.2.0.25
versions.androidStudioBuild=181.4987877
versions.jar.guava=21.0
versions.jar.groovy-all=2.4.12
versions.jar.swingx-core=1.6.2
versions.jar.kxml2=2.3.0
versions.jar.streamex=0.6.5
versions.jar.gson=2.8.2
versions.jar.oro=2.0.8
versions.jar.snappy-in-java=0.5.1
ignore.jar.common=true
ignore.jar.lombok-ast=true
versions.gradle-api=4.4
@@ -1,81 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.android
import com.android.SdkConstants
import com.android.resources.ResourceType.*
import com.android.tools.idea.AndroidPsiUtils.ResourceReferenceType.FRAMEWORK
import com.android.tools.idea.rendering.GutterIconRenderer
import com.android.tools.idea.res.resolveColor
import com.android.tools.idea.res.resolveDrawable
import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.lang.annotation.Annotator
import com.intellij.psi.PsiElement
import org.jetbrains.android.AndroidColorAnnotator
import org.jetbrains.android.facet.AndroidFacet
import org.jetbrains.kotlin.android.ResourceReferenceAnnotatorUtil.*
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
import org.jetbrains.kotlin.psi.KtReferenceExpression
class AndroidResourceReferenceAnnotator : Annotator {
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
val reference = element as? KtReferenceExpression ?: return
val androidFacet = AndroidFacet.getInstance(element) ?: return
val referenceTarget = reference.getResourceReferenceTargetDescriptor() ?: return
val resourceType = referenceTarget.getAndroidResourceType() ?: return
if (resourceType != COLOR && resourceType != DRAWABLE && resourceType != MIPMAP) {
return
}
val referenceType = referenceTarget.getResourceReferenceType()
val configuration = pickConfiguration(androidFacet, androidFacet.module, element.containingFile) ?: return
val resourceValue = findResourceValue(
resourceType,
reference.text,
referenceType == FRAMEWORK,
androidFacet.module,
configuration
) ?: return
val resourceResolver = configuration.resourceResolver ?: return
if (resourceType == COLOR) {
val color = resourceResolver.resolveColor(resourceValue, element.project)
if (color != null) {
val annotation = holder.createInfoAnnotation(element, null)
annotation.gutterIconRenderer = ColorRenderer(element, color)
}
}
else {
var file = resourceResolver.resolveDrawable(resourceValue, element.project)
if (file != null && file.path.endsWith(SdkConstants.DOT_XML)) {
file = pickBitmapFromXml(file, resourceResolver, element.project)
}
val iconFile = AndroidColorAnnotator.pickBestBitmap(file)
if (iconFile != null) {
val annotation = holder.createInfoAnnotation(element, null)
annotation.gutterIconRenderer = GutterIconRenderer(resourceResolver, element, iconFile)
}
}
}
private fun KtReferenceExpression.getResourceReferenceTargetDescriptor(): JavaPropertyDescriptor? =
resolveToCall()?.resultingDescriptor as? JavaPropertyDescriptor
}
@@ -1,141 +0,0 @@
/*
* 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.kotlin.android
import com.android.SdkConstants
import com.android.SdkConstants.ANDROID_PKG
import com.android.SdkConstants.R_CLASS
import com.android.resources.ResourceType
import com.android.tools.idea.AndroidPsiUtils
import com.android.tools.idea.AndroidPsiUtils.ResourceReferenceType.*
import com.android.tools.idea.res.AndroidInternalRClassFinder
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import org.jetbrains.android.dom.AndroidAttributeValue
import org.jetbrains.android.dom.manifest.Manifest
import org.jetbrains.android.facet.AndroidFacet
import org.jetbrains.android.util.AndroidResourceUtil
import org.jetbrains.android.util.AndroidResourceUtil.isManifestJavaFile
import org.jetbrains.android.util.AndroidResourceUtil.isRJavaFile
import org.jetbrains.android.util.AndroidUtils
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtQualifiedExpression
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
internal fun KtClass.findComponentDeclarationInManifest(manifest: Manifest): AndroidAttributeValue<PsiClass>? {
val application = manifest.application ?: return null
val type = (unsafeResolveToDescriptor(BodyResolveMode.PARTIAL) as? ClassDescriptor)?.defaultType ?: return null
return when {
type.isSubclassOf(AndroidUtils.ACTIVITY_BASE_CLASS_NAME) ->
application.activities?.find { it.activityClass.value?.qualifiedName == fqName?.asString() }?.activityClass
type.isSubclassOf(AndroidUtils.SERVICE_CLASS_NAME) ->
application.services?.find { it.serviceClass.value?.qualifiedName == fqName?.asString() }?.serviceClass
type.isSubclassOf(AndroidUtils.RECEIVER_CLASS_NAME) ->
application.receivers?.find { it.receiverClass.value?.qualifiedName == fqName?.asString() }?.receiverClass
type.isSubclassOf(AndroidUtils.PROVIDER_CLASS_NAME) ->
application.providers?.find { it.providerClass.value?.qualifiedName == fqName?.asString() }?.providerClass
else -> null
}
}
internal fun PsiElement.getAndroidFacetForFile(): AndroidFacet? {
val file = containingFile ?: return null
return AndroidFacet.getInstance(file)
}
internal fun JavaPropertyDescriptor.getAndroidResourceType(): ResourceType? {
if (getResourceReferenceType() == NONE) {
return null
}
val containingClass = containingDeclaration as? JavaClassDescriptor ?: return null
return ResourceType.getEnum(containingClass.name.asString())
}
internal fun JavaPropertyDescriptor.getResourceReferenceType(): AndroidPsiUtils.ResourceReferenceType {
val containingClass = containingDeclaration as? JavaClassDescriptor ?: return NONE
val rClass = containingClass.containingDeclaration as? JavaClassDescriptor ?: return NONE
if (R_CLASS == rClass.name.asString()) {
return if ((rClass.containingDeclaration as? PackageFragmentDescriptor)?.fqName?.asString() == ANDROID_PKG) {
FRAMEWORK
}
else {
APP
}
}
return NONE
}
internal fun getReferredResourceOrManifestField(facet: AndroidFacet, expression: KtSimpleNameExpression, localOnly: Boolean)
= getReferredResourceOrManifestField(facet, expression, null, localOnly)
internal fun getReferredResourceOrManifestField(facet: AndroidFacet, expression: KtSimpleNameExpression,
className: String?, localOnly: Boolean): AndroidResourceUtil.MyReferredResourceFieldInfo? {
val resFieldName = expression.getReferencedName()
val resClassReference = expression.getPreviousInQualifiedChain() as? KtSimpleNameExpression ?: return null
val resClassName = resClassReference.getReferencedName()
if (resClassName.isEmpty() || className != null && className != resClassName) {
return null
}
val rClassReference = resClassReference.getPreviousInQualifiedChain() as? KtSimpleNameExpression ?: return null
val rClassDescriptor = rClassReference.analyze(BodyResolveMode.PARTIAL)
.get(BindingContext.REFERENCE_TARGET, rClassReference) as? ClassDescriptor ?: return null
val rClassShortName = rClassDescriptor.name.asString()
val fromManifest = AndroidUtils.MANIFEST_CLASS_NAME == rClassShortName
if (!fromManifest && AndroidUtils.R_CLASS_NAME != rClassShortName) {
return null
}
if (!localOnly) {
val qName = rClassDescriptor.fqNameSafe.asString()
if (SdkConstants.CLASS_R == qName || AndroidInternalRClassFinder.INTERNAL_R_CLASS_QNAME == qName) {
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, facet.module, true, false)
}
}
val containingFile = (rClassDescriptor.source.containingFile as? PsiSourceFile)?.psiFile ?: return null
if (if (fromManifest) !isManifestJavaFile(facet, containingFile) else !isRJavaFile(facet, containingFile)) {
return null
}
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, facet.module, false, false)
}
private fun KtExpression.getPreviousInQualifiedChain(): KtExpression? {
val receiverExpression = getQualifiedExpressionForSelector()?.receiverExpression
return (receiverExpression as? KtQualifiedExpression)?.selectorExpression ?: receiverExpression
}
@@ -1,43 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.android
import com.android.tools.idea.npw.template.ConvertJavaToKotlinProvider
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiJavaFile
import org.jetbrains.kotlin.android.configure.KotlinAndroidGradleModuleConfigurator
import org.jetbrains.kotlin.idea.actions.JavaToKotlinAction
import org.jetbrains.kotlin.idea.configuration.KotlinProjectConfigurator
import org.jetbrains.kotlin.idea.configuration.getCanBeConfiguredModules
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
class ConvertJavaToKotlinProviderImpl : ConvertJavaToKotlinProvider {
override fun configureKotlin(project: Project) {
val configurator = KotlinProjectConfigurator.EP_NAME.findExtension(KotlinAndroidGradleModuleConfigurator::class.java)
val nonConfiguredModules = getCanBeConfiguredModules(project, configurator)
configurator.configureSilently(project, nonConfiguredModules, bundledRuntimeVersion())
}
override fun getKotlinVersion(): String {
return bundledRuntimeVersion()
}
override fun convertToKotlin(project: Project, files: List<PsiJavaFile>): List<PsiFile> {
return JavaToKotlinAction.convertFiles(files, project, askExternalCodeProcessing = false)
}
}
@@ -1,138 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.android
import com.android.SdkConstants
import com.android.resources.ResourceType
import com.intellij.codeHighlighting.Pass
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler
import com.intellij.codeInsight.daemon.LineMarkerInfo
import com.intellij.codeInsight.daemon.LineMarkerProvider
import com.intellij.codeInsight.navigation.NavigationUtil
import com.intellij.icons.AllIcons
import com.intellij.ide.highlighter.XmlFileType
import com.intellij.navigation.GotoRelatedItem
import com.intellij.openapi.editor.markup.GutterIconRenderer
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.xml.XmlAttributeValue
import com.intellij.ui.awt.RelativePoint
import com.intellij.util.Function
import org.jetbrains.android.dom.manifest.Manifest
import org.jetbrains.android.facet.AndroidFacet
import org.jetbrains.android.resourceManagers.ModuleResourceManagers
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import java.awt.event.MouseEvent
import javax.swing.Icon
class KotlinAndroidLineMarkerProvider : LineMarkerProvider {
override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<*>? = null
override fun collectSlowLineMarkers(elements: List<PsiElement>, result: MutableCollection<LineMarkerInfo<PsiElement>>) {
elements.forEach {
(it as? KtClass)?.getLineMarkerInfo()?.let { marker -> result.add(marker) }
}
}
private fun KtClass.getLineMarkerInfo(): LineMarkerInfo<PsiElement>? {
val nameIdentifier = nameIdentifier ?: return null
val androidFacet = AndroidFacet.getInstance(this) ?: return null
val manifest = androidFacet.manifest ?: return null
val manifestItems = collectGoToRelatedManifestItems(manifest)
if (manifestItems.isEmpty() && !isClassWithLayoutXml()) {
return null
}
return LineMarkerInfo(
nameIdentifier,
nameIdentifier.textRange,
AllIcons.FileTypes.Xml,
Pass.LINE_MARKERS,
Function { "Related XML file" },
GutterIconNavigationHandler { e: MouseEvent, _: PsiElement ->
NavigationUtil
.getRelatedItemsPopup(
manifestItems + collectGoToRelatedLayoutItems(androidFacet),
"Go to Related Files")
.show(RelativePoint(e))
},
GutterIconRenderer.Alignment.RIGHT)
}
private fun KtClass.collectGoToRelatedLayoutItems(androidFacet: AndroidFacet): List<GotoRelatedItem> {
val resources = mutableSetOf<PsiFile>()
accept(object: KtVisitorVoid() {
override fun visitKtElement(element: KtElement) {
element.acceptChildren(this)
}
override fun visitReferenceExpression(expression: KtReferenceExpression) {
super.visitReferenceExpression(expression)
val resClassName = ResourceType.LAYOUT.getName()
val info = (expression as? KtSimpleNameExpression)?.let {
getReferredResourceOrManifestField(androidFacet, it, resClassName, true)
}
if (info == null || info.isFromManifest) {
return
}
val files = ModuleResourceManagers
.getInstance(androidFacet)
.localResourceManager
.findResourcesByFieldName(resClassName, info.fieldName)
.filterIsInstance<PsiFile>()
resources.addAll(files)
}
})
return resources.map { GotoRelatedLayoutItem(it) }
}
private fun KtClass.collectGoToRelatedManifestItems(manifest: Manifest): List<GotoRelatedItem> =
findComponentDeclarationInManifest(manifest)?.xmlAttributeValue?.let { listOf(GotoManifestItem(it)) } ?: emptyList()
private class GotoManifestItem(attributeValue: XmlAttributeValue) : GotoRelatedItem(attributeValue) {
override fun getCustomName(): String? = "AndroidManifest.xml"
override fun getCustomContainerName(): String? = ""
override fun getCustomIcon(): Icon? = XmlFileType.INSTANCE.icon
}
private class GotoRelatedLayoutItem(private val file: PsiFile) : GotoRelatedItem(file, "Layout Files") {
override fun getCustomContainerName(): String? = "(${file.containingDirectory.name})"
}
companion object {
private val CLASSES_WITH_LAYOUT_XML = arrayOf(
SdkConstants.CLASS_ACTIVITY,
SdkConstants.CLASS_FRAGMENT,
SdkConstants.CLASS_V4_FRAGMENT.oldName(),
SdkConstants.CLASS_V4_FRAGMENT.newName(),
"android.widget.Adapter")
private fun KtClass.isClassWithLayoutXml(): Boolean {
val type = (unsafeResolveToDescriptor(BodyResolveMode.PARTIAL) as? ClassDescriptor)?.defaultType ?: return false
return CLASSES_WITH_LAYOUT_XML.any { type.isSubclassOf(it, true) }
}
}
}
@@ -1,275 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.android;
import com.android.ide.common.rendering.api.ResourceNamespace;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.resources.ResourceResolver;
import com.android.ide.common.resources.AbstractResourceRepository;
import com.android.ide.common.resources.ResourceItem;
import com.android.resources.ResourceType;
import com.android.tools.idea.configurations.Configuration;
import com.android.tools.idea.configurations.ConfigurationManager;
import com.android.tools.idea.res.LocalResourceRepository;
import com.android.tools.idea.res.ResourceHelper;
import com.android.tools.idea.res.ResourceRepositoryManager;
import com.android.tools.idea.ui.resourcechooser.ColorPicker;
import com.android.utils.XmlUtils;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ui.ColorIcon;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.JBUI;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.util.List;
import static com.android.SdkConstants.*;
/**
* Contains copied privates from AndroidColorAnnotator, so we could use them for Kotlin AndroidResourceReferenceAnnotator
*/
public class ResourceReferenceAnnotatorUtil {
private static final int ICON_SIZE = 8;
@Nullable
public static File pickBitmapFromXml(@NotNull File file, @NotNull ResourceResolver resourceResolver, @NotNull Project project) {
try {
String xml = Files.toString(file, Charsets.UTF_8);
Document document = XmlUtils.parseDocumentSilently(xml, true);
if (document != null && document.getDocumentElement() != null) {
Element root = document.getDocumentElement();
String tag = root.getTagName();
Element target = null;
String attribute = null;
if ("vector".equals(tag)) {
// Vectors are handled in the icon cache
return file;
}
else if ("bitmap".equals(tag) || "nine-patch".equals(tag)) {
target = root;
attribute = ATTR_SRC;
}
else if ("selector".equals(tag) ||
"level-list".equals(tag) ||
"layer-list".equals(tag) ||
"transition".equals(tag)) {
NodeList children = root.getChildNodes();
for (int i = children.getLength() - 1; i >= 0; i--) {
Node item = children.item(i);
if (item.getNodeType() == Node.ELEMENT_NODE && TAG_ITEM.equals(item.getNodeName())) {
target = (Element)item;
if (target.hasAttributeNS(ANDROID_URI, ATTR_DRAWABLE)) {
attribute = ATTR_DRAWABLE;
break;
}
}
}
}
else if ("clip".equals(tag) || "inset".equals(tag) || "scale".equals(tag)) {
target = root;
attribute = ATTR_DRAWABLE;
} else {
// <shape> etc - no bitmap to be found
return null;
}
if (attribute != null && target.hasAttributeNS(ANDROID_URI, attribute)) {
String src = target.getAttributeNS(ANDROID_URI, attribute);
ResourceValue value = resourceResolver.findResValue(src, false);
if (value != null) {
return ResourceHelper.resolveDrawable(resourceResolver, value, project);
}
}
}
} catch (Throwable ignore) {
// Not logging for now; afraid to risk unexpected crashes in upcoming preview. TODO: Re-enable.
//Logger.getInstance(AndroidColorAnnotator.class).warn(String.format("Could not read/render icon image %1$s", file), e);
}
return null;
}
/** Looks up the resource item of the given type and name for the given configuration, if any */
@Nullable
public static ResourceValue findResourceValue(ResourceType type,
String name,
boolean isFramework,
Module module,
Configuration configuration) {
if (isFramework) {
AbstractResourceRepository frameworkResources = configuration.getFrameworkResources();
if (frameworkResources == null) {
return null;
}
List<ResourceItem> items = frameworkResources.getResourceItems(ResourceNamespace.ANDROID, type, name);
if (items.isEmpty()) {
return null;
}
return items.get(0).getResourceValue();
} else {
ResourceRepositoryManager repoManager = ResourceRepositoryManager.getOrCreateInstance(module);
if (repoManager == null) {
return null;
}
LocalResourceRepository appResources = repoManager.getAppResources(true); if (appResources == null) {
return null;
}
if (!appResources.hasResourceItem(type, name)) {
return null;
}
return appResources.getConfiguredValue(type, name, configuration.getFullConfig());
}
}
/** Picks a suitable configuration to use for resource resolution */
@Nullable
public static Configuration pickConfiguration(AndroidFacet facet, Module module, PsiFile file) {
VirtualFile virtualFile = file.getVirtualFile();
if(virtualFile == null) {
return null;
} else {
VirtualFile parent = virtualFile.getParent();
if(parent == null) {
return null;
} else {
String parentName = parent.getName();
VirtualFile layout;
if(!parentName.startsWith("layout")) {
layout = ResourceHelper.pickAnyLayoutFile(module, facet);
if(layout == null) {
return null;
}
} else {
layout = virtualFile;
}
return ConfigurationManager.getOrCreateInstance(module).getConfiguration(layout);
}
}
}
public static class ColorRenderer extends GutterIconRenderer {
private final PsiElement myElement;
private final Color myColor;
ColorRenderer(@NotNull PsiElement element, @Nullable Color color) {
myElement = element;
myColor = color;
}
@NotNull
@Override
public Icon getIcon() {
Color color = getCurrentColor();
return JBUI.scale(color == null ? EmptyIcon.create(ICON_SIZE) : new ColorIcon(ICON_SIZE, color));
}
@Nullable
private Color getCurrentColor() {
if (myColor != null) {
return myColor;
} else if (myElement instanceof XmlTag) {
return ResourceHelper.parseColor(((XmlTag)myElement).getValue().getText());
} else if (myElement instanceof XmlAttributeValue) {
return ResourceHelper.parseColor(((XmlAttributeValue)myElement).getValue());
} else {
return null;
}
}
@Override
public AnAction getClickAction() {
if (myColor != null) { // Cannot set colors that were derived
return null;
}
return new AnAction() {
@Override
public void actionPerformed(AnActionEvent e) {
final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
if (editor != null) {
// Need ARGB support in platform color chooser; see
// https://youtrack.jetbrains.com/issue/IDEA-123498
//final Color color =
// ColorChooser.chooseColor(editor.getComponent(), AndroidBundle.message("android.choose.color"), getCurrentColor());
final Color color = ColorPicker.showDialog(editor.getComponent(), "Choose Color", getCurrentColor(), true, null, false);
if (color != null) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
if (myElement instanceof XmlTag) {
((XmlTag)myElement).getValue().setText(ResourceHelper.colorToString(color));
} else if (myElement instanceof XmlAttributeValue) {
XmlAttribute attribute = PsiTreeUtil.getParentOfType(myElement, XmlAttribute.class);
if (attribute != null) {
attribute.setValue(ResourceHelper.colorToString(color));
}
}
}
});
}
}
}
};
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ColorRenderer that = (ColorRenderer)o;
// TODO: Compare with modification count in app resources (if not framework)
if (myColor != null ? !myColor.equals(that.myColor) : that.myColor != null) return false;
if (!myElement.equals(that.myElement)) return false;
return true;
}
@Override
public int hashCode() {
int result = myElement.hashCode();
result = 31 * result + (myColor != null ? myColor.hashCode() : 0);
return result;
}
}
}
@@ -1,65 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.android.configure
import com.android.tools.idea.gradle.project.model.JavaModuleModel
import com.android.tools.idea.gradle.project.sync.idea.data.service.AndroidProjectKeys
import com.android.tools.idea.io.FilePaths
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.project.ModuleData
import com.intellij.openapi.externalSystem.model.project.ProjectData
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.impl.libraries.LibraryEx
import com.intellij.openapi.roots.libraries.Library
import org.jetbrains.kotlin.idea.configuration.detectPlatformKindByPlugin
import org.jetbrains.kotlin.idea.framework.detectLibraryKind
import org.jetbrains.kotlin.idea.platform.tooling
import java.io.File
class KotlinAndroidGradleLibraryDataService : AbstractProjectDataService<JavaModuleModel, Void>() {
override fun getTargetDataKey() = AndroidProjectKeys.JAVA_MODULE_MODEL
override fun postProcess(
toImport: MutableCollection<DataNode<JavaModuleModel>>,
projectData: ProjectData?,
project: Project,
modelsProvider: IdeModifiableModelsProvider
) {
for (dataNode in toImport) {
@Suppress("UNCHECKED_CAST")
val targetLibraryKind = detectPlatformKindByPlugin(dataNode.parent as DataNode<ModuleData>)?.tooling?.libraryKind
if (targetLibraryKind != null) {
for (dep in dataNode.data.jarLibraryDependencies) {
val library = modelsProvider.findLibraryByBinaryPath(dep.binaryPath) as LibraryEx? ?: continue
if (library.kind == null) {
val model = modelsProvider.getModifiableLibraryModel(library) as LibraryEx.ModifiableModelEx
detectLibraryKind(model.getFiles(OrderRootType.CLASSES))?.let { model.kind = it }
}
}
}
}
}
private fun IdeModifiableModelsProvider.findLibraryByBinaryPath(path: File?): Library? {
if (path == null) return null
val url = FilePaths.pathToIdeaUrl(path)
return allLibraries.firstOrNull { url in getModifiableLibraryModel(it).getUrls(OrderRootType.CLASSES) }
}
}
@@ -1,236 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.android.configure
import com.android.tools.idea.gradle.project.sync.idea.data.service.AndroidProjectKeys
import com.android.tools.idea.gradle.util.ContentEntries.findParentContentEntry
import com.android.tools.idea.io.FilePaths
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.ProjectKeys
import com.intellij.openapi.externalSystem.model.project.ModuleData
import com.intellij.openapi.externalSystem.model.project.ProjectData
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService
import com.intellij.openapi.externalSystem.service.project.manage.ContentRootDataService.CREATE_EMPTY_DIRECTORIES
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.DependencyScope
import com.intellij.openapi.roots.ModifiableRootModel
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.util.SmartList
import com.intellij.util.containers.stream
import org.jetbrains.jps.model.java.JavaResourceRootType
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
import org.jetbrains.kotlin.gradle.KotlinCompilation
import org.jetbrains.kotlin.gradle.KotlinPlatform
import org.jetbrains.kotlin.gradle.KotlinSourceSet
import org.jetbrains.kotlin.idea.addModuleDependencyIfNeeded
import org.jetbrains.kotlin.idea.configuration.*
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
import java.io.File
import java.io.IOException
import org.jetbrains.kotlin.idea.configuration.kotlinSourceSet
class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<ModuleData, Void>() {
override fun getTargetDataKey() = ProjectKeys.MODULE
private fun shouldCreateEmptySourceRoots(
moduleDataNode: DataNode<ModuleData>,
module: Module
): Boolean {
val projectDataNode = ExternalSystemApiUtil.findParent(moduleDataNode, ProjectKeys.PROJECT) ?: return false
if (projectDataNode.getUserData<Boolean>(CREATE_EMPTY_DIRECTORIES) == true) return true
val projectSystemId = projectDataNode.data.owner
val externalSystemSettings = ExternalSystemApiUtil.getSettings(module.project, projectSystemId)
val path = ExternalSystemModulePropertyManager.getInstance(module).getRootProjectPath() ?: return false
return externalSystemSettings.getLinkedProjectSettings(path)?.isCreateEmptyContentRootDirectories ?: false
}
override fun postProcess(
toImport: MutableCollection<DataNode<ModuleData>>,
projectData: ProjectData?,
project: Project,
modelsProvider: IdeModifiableModelsProvider
) {
for (nodeToImport in toImport) {
val projectNode = ExternalSystemApiUtil.findParent(nodeToImport, ProjectKeys.PROJECT) ?: continue
val moduleData = nodeToImport.data
val module = modelsProvider.findIdeModule(moduleData) ?: continue
val shouldCreateEmptySourceRoots = shouldCreateEmptySourceRoots(nodeToImport, module)
val rootModel = modelsProvider.getModifiableRootModel(module)
val kotlinAndroidSourceSets = nodeToImport.kotlinAndroidSourceSets ?: emptyList()
for (sourceSetInfo in kotlinAndroidSourceSets) {
val compilation = sourceSetInfo.kotlinModule as? KotlinCompilation ?: continue
for (sourceSet in compilation.sourceSets) {
if (sourceSet.platform == KotlinPlatform.ANDROID) {
val sourceType = if (sourceSet.isTestModule) JavaSourceRootType.TEST_SOURCE else JavaSourceRootType.SOURCE
val resourceType = if (sourceSet.isTestModule) JavaResourceRootType.TEST_RESOURCE else JavaResourceRootType.RESOURCE
sourceSet.sourceDirs.forEach { addSourceRoot(it, sourceType, rootModel, shouldCreateEmptySourceRoots) }
sourceSet.resourceDirs.forEach { addSourceRoot(it, resourceType, rootModel, shouldCreateEmptySourceRoots) }
}
}
}
addExtraDependeeModules(nodeToImport, projectNode, modelsProvider, rootModel, false)
addExtraDependeeModules(nodeToImport, projectNode, modelsProvider, rootModel, true)
if (nodeToImport.kotlinAndroidSourceSets == null) {
continue
}
val androidModel = getAndroidModuleModel(nodeToImport) ?: continue
val variantName = androidModel.selectedVariant.name
val activeSourceSetInfos = nodeToImport.kotlinAndroidSourceSets?.filter { it.kotlinModule.name.startsWith(variantName) } ?: emptyList()
for (activeSourceSetInfo in activeSourceSetInfos) {
val activeCompilation = activeSourceSetInfo.kotlinModule as? KotlinCompilation ?: continue
for (sourceSet in activeCompilation.sourceSets) {
if (sourceSet.platform != KotlinPlatform.ANDROID) {
val sourceSetId = activeSourceSetInfo.sourceSetIdsByName[sourceSet.name] ?: continue
val sourceSetNode = ExternalSystemApiUtil.findFirstRecursively(projectNode) {
(it.data as? ModuleData)?.id == sourceSetId
} as? DataNode<out ModuleData>? ?: continue
val sourceSetData = sourceSetNode.data as? ModuleData ?: continue
val sourceSetModule = modelsProvider.findIdeModule(sourceSetData) ?: continue
addModuleDependencyIfNeeded(
rootModel,
sourceSetModule,
activeSourceSetInfo.isTestModule,
sourceSetNode.kotlinSourceSet?.isTestModule ?: false
)
}
}
}
val mainSourceSetInfo = activeSourceSetInfos.firstOrNull { it.kotlinModule.name == variantName }
if (mainSourceSetInfo != null) {
KotlinSourceSetDataService.configureFacet(moduleData, mainSourceSetInfo, nodeToImport, module, modelsProvider)
}
val kotlinFacet = KotlinFacet.get(module)
if (kotlinFacet != null) {
GradleProjectImportHandler.getInstances(project).forEach { it.importByModule(kotlinFacet, nodeToImport) }
}
}
}
private fun getDependeeModuleNodes(
moduleNode: DataNode<ModuleData>,
projectNode: DataNode<ProjectData>,
modelsProvider: IdeModifiableModelsProvider,
testScope: Boolean
): List<DataNode<out ModuleData>> {
val androidModel = getAndroidModuleModel(moduleNode)
if (androidModel != null) {
val dependencies = if (testScope) {
androidModel.selectedAndroidTestCompileDependencies
} else {
androidModel.selectedMainCompileLevel2Dependencies
} ?: return emptyList()
return dependencies
.moduleDependencies
.mapNotNull { projectNode.findChildModuleById(it.projectPath) }
}
val javaModel = getJavaModuleModel(moduleNode)
if (javaModel != null) {
val scope = if (testScope) DependencyScope.TEST.name else DependencyScope.COMPILE.name
val moduleNames = javaModel
.javaModuleDependencies
.filter { scope == it.scope ?: DependencyScope.COMPILE.name }
.mapTo(HashSet()) { it.moduleName }
return ExternalSystemApiUtil
.getChildren(projectNode, ProjectKeys.MODULE)
.filter { modelsProvider.findIdeModule(it.data)?.name in moduleNames }
}
return emptyList()
}
private fun List<DataNode<GradleSourceSetData>>.firstByPlatformOrNull(platform: KotlinPlatform) = firstOrNull {
it.kotlinSourceSet?.platform == platform
}
private fun addExtraDependeeModules(
moduleNode: DataNode<ModuleData>,
projectNode: DataNode<ProjectData>,
modelsProvider: IdeModifiableModelsProvider,
rootModel: ModifiableRootModel,
testScope: Boolean
) {
val dependeeModuleNodes = getDependeeModuleNodes(moduleNode, projectNode, modelsProvider, testScope)
val relevantNodes = dependeeModuleNodes
.flatMap { ExternalSystemApiUtil.getChildren(it, GradleSourceSetData.KEY) }
.filter {
val ktModule = it.kotlinSourceSet?.kotlinModule
ktModule != null && ktModule.isTestModule == testScope
}
val commonSourceSetName = KotlinSourceSet.commonName(testScope)
val isAndroidModule = getAndroidModuleModel(moduleNode) != null
val gradleSourceSetDataNodes = SmartList<DataNode<GradleSourceSetData>>()
.apply {
addIfNotNull(
(if (isAndroidModule) relevantNodes.firstByPlatformOrNull(KotlinPlatform.ANDROID) else null)
?: relevantNodes.firstByPlatformOrNull(KotlinPlatform.JVM)
)
addIfNotNull(
relevantNodes.firstOrNull {
it.kotlinSourceSet?.platform == KotlinPlatform.COMMON && it.kotlinSourceSet?.kotlinModule?.name == commonSourceSetName
}
)
}
val testKotlinModules =
gradleSourceSetDataNodes.filter { it.kotlinSourceSet?.isTestModule ?: false }.mapNotNull { modelsProvider.findIdeModule(it.data) }
.toSet()
gradleSourceSetDataNodes.forEach { node ->
val module = modelsProvider.findIdeModule(node.data) ?: return
addModuleDependencyIfNeeded(rootModel, module, testScope, node.kotlinSourceSet?.isTestModule ?: false)
val dependeeRootModel = modelsProvider.getModifiableRootModel(module)
dependeeRootModel.getModuleDependencies(testScope).forEach { transitiveDependee ->
addModuleDependencyIfNeeded(rootModel, transitiveDependee, testScope, testKotlinModules.contains(transitiveDependee))
}
}
}
private fun getAndroidModuleModel(moduleNode: DataNode<ModuleData>) =
ExternalSystemApiUtil.getChildren(moduleNode, AndroidProjectKeys.ANDROID_MODEL).firstOrNull()?.data
private fun getJavaModuleModel(moduleNode: DataNode<ModuleData>) =
ExternalSystemApiUtil.getChildren(moduleNode, AndroidProjectKeys.JAVA_MODULE_MODEL).firstOrNull()?.data
private fun addSourceRoot(
sourceRoot: File,
type: JpsModuleSourceRootType<*>,
rootModel: ModifiableRootModel,
shouldCreateEmptySourceRoots: Boolean
) {
val parent = findParentContentEntry(sourceRoot, rootModel.contentEntries.stream()) ?: return
val url = FilePaths.pathToIdeaUrl(sourceRoot)
parent.addSourceFolder(url, type)
if (shouldCreateEmptySourceRoots) {
ExternalSystemApiUtil.doWriteAction {
try {
VfsUtil.createDirectoryIfMissing(sourceRoot.path)
} catch (e: IOException) {
LOG.warn(String.format("Unable to create directory for the path: %s", sourceRoot.path), e)
}
}
}
}
companion object {
private val LOG = Logger.getInstance(KotlinAndroidGradleMPPModuleDataService::class.java)
}
}
@@ -1,82 +0,0 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.android.configure
import com.android.tools.idea.gradle.project.sync.GradleSyncInvoker
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtil
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.JavaSdkVersion
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.configuration.AndroidGradle
import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator
import org.jetbrains.kotlin.idea.configuration.getBuildSystemType
import org.jetbrains.kotlin.idea.util.projectStructure.version
import org.jetbrains.kotlin.idea.versions.MAVEN_STDLIB_ID_JDK7
import org.jetbrains.kotlin.idea.versions.hasJreSpecificRuntime
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
class KotlinAndroidGradleModuleConfigurator internal constructor() : KotlinWithGradleConfigurator() {
override val name: String = NAME
override val targetPlatform: TargetPlatform = JvmPlatform
override val presentableText: String = "Android with Gradle"
public override fun isApplicable(module: Module): Boolean = module.getBuildSystemType() == AndroidGradle
override val kotlinPluginName: String = KOTLIN_ANDROID
override fun getKotlinPluginExpression(forKotlinDsl: Boolean): String =
if (forKotlinDsl) "kotlin(\"android\")" else "id 'org.jetbrains.kotlin.android' "
override fun addElementsToFile(file: PsiFile, isTopLevelProjectFile: Boolean, version: String): Boolean {
val manipulator = getManipulator(file, false)
val sdk = ModuleUtil.findModuleForPsiElement(file)?.let { ModuleRootManager.getInstance(it).sdk }
val jvmTarget = getJvmTarget(sdk, version)
return if (isTopLevelProjectFile) {
manipulator.configureProjectBuildScript(kotlinPluginName, version)
}
else {
manipulator.configureModuleBuildScript(
kotlinPluginName,
getKotlinPluginExpression(file.isKtDsl()),
getStdlibArtifactName(sdk, version),
version,
jvmTarget
)
}
}
override fun getStdlibArtifactName(sdk: Sdk?, version: String): String {
if (sdk != null && hasJreSpecificRuntime(version)) {
val sdkVersion = sdk.version
if (sdkVersion != null && sdkVersion.isAtLeast(JavaSdkVersion.JDK_1_8)) {
// Android dex can't convert our kotlin-stdlib-jre8 artifact, so use jre7 instead (KT-16530)
return MAVEN_STDLIB_ID_JDK7
}
}
return super.getStdlibArtifactName(sdk, version)
}
@JvmSuppressWildcards
override fun configure(project: Project, excludeModules: Collection<Module>) {
super.configure(project, excludeModules)
// Sync after changing build scripts
GradleSyncInvoker.getInstance().requestProjectSync(project, GradleSyncInvoker.Request.projectModified())
}
companion object {
private val NAME = "android-gradle"
private val KOTLIN_ANDROID = "kotlin-android"
}
}
@@ -1,40 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.android.configure
import com.android.tools.idea.gradle.project.model.AndroidModuleModel
import com.android.tools.idea.gradle.project.sync.setup.post.ModuleSetupStep
import com.intellij.openapi.module.Module
import com.intellij.openapi.progress.ProgressIndicator
import org.jetbrains.android.facet.AndroidFacet
import org.jetbrains.kotlin.idea.configuration.compilerArgumentsBySourceSet
import org.jetbrains.kotlin.idea.configuration.configureFacetByCompilerArguments
import org.jetbrains.kotlin.idea.configuration.sourceSetName
import org.jetbrains.kotlin.idea.facet.KotlinFacet
class KotlinAndroidModuleSetupStep : ModuleSetupStep() {
override fun setUpModule(module: Module, progressIndicator: ProgressIndicator?) {
val facet = AndroidFacet.getInstance(module) ?: return
val androidModel = AndroidModuleModel.get(facet) ?: return
val sourceSetName = androidModel.selectedVariant.name
if (module.sourceSetName == sourceSetName) return
val argsInfo = module.compilerArgumentsBySourceSet?.get(sourceSetName) ?: return
val kotlinFacet = KotlinFacet.get(module) ?: return
module.sourceSetName = sourceSetName
configureFacetByCompilerArguments(kotlinFacet, argsInfo, null)
}
}
@@ -1,54 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.android.configure
import com.android.tools.idea.gradle.project.model.AndroidModuleModel
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.Key
import com.intellij.openapi.externalSystem.model.ProjectKeys
import com.intellij.openapi.externalSystem.model.project.ProjectData
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.configuration.GradleProjectImportHandler
import org.jetbrains.kotlin.idea.configuration.configureFacetByGradleModule
class KotlinGradleAndroidModuleModelProjectDataService : AbstractProjectDataService<AndroidModuleModel, Void>() {
companion object {
val KEY = Key<AndroidModuleModel>(AndroidModuleModel::class.qualifiedName!!, 0)
}
override fun getTargetDataKey() = KEY
override fun postProcess(
toImport: MutableCollection<DataNode<AndroidModuleModel>>,
projectData: ProjectData?,
project: Project,
modelsProvider: IdeModifiableModelsProvider
) {
super.postProcess(toImport, projectData, project, modelsProvider)
for (moduleModelNode in toImport) {
val moduleNode = ExternalSystemApiUtil.findParent(moduleModelNode, ProjectKeys.MODULE) ?: continue
val moduleData = moduleNode.data
val ideModule = modelsProvider.findIdeModule(moduleData) ?: continue
val sourceSetName = moduleModelNode.data.selectedVariant.name
val kotlinFacet = configureFacetByGradleModule(moduleNode, sourceSetName, ideModule, modelsProvider) ?: continue
GradleProjectImportHandler.getInstances(project).forEach { it.importByModule(kotlinFacet, moduleNode) }
}
}
}
@@ -1,258 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.android.folding
import com.android.SdkConstants.*
import com.android.ide.common.resources.configuration.FolderConfiguration
import com.android.ide.common.resources.configuration.LocaleQualifier
import com.android.resources.ResourceType
import com.android.tools.idea.folding.AndroidFoldingSettings
import com.android.tools.idea.res.LocalResourceRepository
import com.android.tools.idea.res.ResourceRepositoryManager
import com.intellij.lang.ASTNode
import com.intellij.lang.folding.FoldingBuilderEx
import com.intellij.lang.folding.FoldingDescriptor
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.editor.Document
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.SourceTreeToPsiMap
import org.jetbrains.android.facet.AndroidFacet
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.uast.*
import org.jetbrains.uast.visitor.AbstractUastVisitor
import java.util.regex.Pattern
class ResourceFoldingBuilder : FoldingBuilderEx() {
companion object {
// See lint's StringFormatDetector
private val FORMAT = Pattern.compile("%(\\d+\\$)?([-+#, 0(<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])")
private val FOLD_MAX_LENGTH = 60
private val UNIT_TEST_MODE: Boolean = ApplicationManager.getApplication().isUnitTestMode
private val RESOURCE_TYPES = listOf(ResourceType.STRING,
ResourceType.DIMEN,
ResourceType.INTEGER,
ResourceType.PLURALS)
}
private val isFoldingEnabled = AndroidFoldingSettings.getInstance().isCollapseAndroidStrings
override fun getPlaceholderText(node: ASTNode): String? {
tailrec fun UElement.unwrapReferenceAndGetValue(resources: LocalResourceRepository): String? = when (this) {
is UQualifiedReferenceExpression -> selector.unwrapReferenceAndGetValue(resources)
is UCallExpression -> (valueArguments.firstOrNull() as? UReferenceExpression)?.getAndroidResourceValue(resources, this)
else -> (this as? UReferenceExpression)?.getAndroidResourceValue(resources)
}
val element = SourceTreeToPsiMap.treeElementToPsi(node) ?: return null
val appResources = getAppResources(element) ?: return null
val uastContext = ServiceManager.getService(element.project, UastContext::class.java) ?: return null
return uastContext.convertElement(element, null, null)?.unwrapReferenceAndGetValue(appResources)
}
override fun buildFoldRegions(root: PsiElement, document: Document, quick: Boolean): Array<FoldingDescriptor> {
if (root !is KtFile || quick && !UNIT_TEST_MODE || !isFoldingEnabled || AndroidFacet.getInstance(root) == null) {
return emptyArray()
}
val file = root.toUElement()
val result = arrayListOf<FoldingDescriptor>()
file?.accept(object : AbstractUastVisitor() {
override fun visitSimpleNameReferenceExpression(node: USimpleNameReferenceExpression): Boolean {
node.getFoldingDescriptor()?.let { result.add(it) }
return super.visitSimpleNameReferenceExpression(node)
}
})
return result.toTypedArray()
}
override fun isCollapsedByDefault(node: ASTNode): Boolean = isFoldingEnabled
private fun UReferenceExpression.getFoldingDescriptor(): FoldingDescriptor? {
val resolved = resolve() ?: return null
val resourceType = resolved.getAndroidResourceType() ?: return null
if (resourceType !in RESOURCE_TYPES) return null
fun UElement.createFoldingDescriptor() = psi?.let { psi ->
val dependencies: Set<PsiElement> = setOf(psi)
FoldingDescriptor(psi.node, psi.textRange, null, dependencies)
}
val element = uastParent as? UQualifiedReferenceExpression ?: this
val getResourceValueCall = (element.uastParent as? UCallExpression)?.takeIf { it.isFoldableGetResourceValueCall() }
if (getResourceValueCall != null) {
val qualifiedCall = getResourceValueCall.uastParent as? UQualifiedReferenceExpression
if (qualifiedCall?.selector == getResourceValueCall) {
return qualifiedCall.createFoldingDescriptor()
}
return getResourceValueCall.createFoldingDescriptor()
}
return element.createFoldingDescriptor()
}
private fun UCallExpression.isFoldableGetResourceValueCall(): Boolean {
return methodName == "getString" ||
methodName == "getText" ||
methodName == "getInteger" ||
methodName?.startsWith("getDimension") ?: false ||
methodName?.startsWith("getQuantityString") ?: false
}
private fun PsiElement.getAndroidResourceType(): ResourceType? {
val elementType = parent as? PsiClass ?: return null
val elementPackage = elementType.parent as? PsiClass ?: return null
if (R_CLASS != elementPackage.name) return null
if (elementPackage.qualifiedName != "$ANDROID_PKG.$R_CLASS") {
return ResourceType.getEnum(elementType.name)
}
return null
}
private fun UReferenceExpression.getAndroidResourceValue(resources: LocalResourceRepository, call: UCallExpression? = null): String? {
val resourceType = resolve()?.getAndroidResourceType() ?: return null
val referenceConfig = FolderConfiguration().apply { localeQualifier = LocaleQualifier("xx") }
val key = resolvedName ?: return null
val resourceValue = resources.getResourceValue(resourceType, key, referenceConfig) ?: return null
val text = if (call != null) formatArguments(call, resourceValue) else resourceValue
if (resourceType == ResourceType.STRING || resourceType == ResourceType.PLURALS) {
return '"' + StringUtil.shortenTextWithEllipsis(text, FOLD_MAX_LENGTH - 2, 0) + '"'
}
else if (text.length <= 1) {
// Don't just inline empty or one-character replacements: they can't be expanded by a mouse click
// so are hard to use without knowing about the folding keyboard shortcut to toggle folding.
// This is similar to how IntelliJ 14 handles call parameters
return key + ": " + text
}
return StringUtil.shortenTextWithEllipsis(text, FOLD_MAX_LENGTH, 0)
}
private tailrec fun LocalResourceRepository.getResourceValue(
type: ResourceType,
name: String,
referenceConfig: FolderConfiguration): String? {
val value = getConfiguredValue(type, name, referenceConfig)?.value ?: return null
if (!value.startsWith('@')) {
return value
}
val (referencedTypeName, referencedName) = value.substring(1).split('/').takeIf { it.size == 2 } ?: return value
val referencedType = ResourceType.getEnum(referencedTypeName) ?: return value
return getResourceValue(referencedType, referencedName, referenceConfig)
}
// Converted from com.android.tools.idea.folding.InlinedResource#insertArguments
private fun formatArguments(callExpression: UCallExpression, formatString: String): String {
if (!formatString.contains('%')) {
return formatString
}
val args = callExpression.valueArguments
if (args.isEmpty() || !args.first().isPsiValid) {
return formatString
}
val matcher = FORMAT.matcher(formatString)
var index = 0
var prevIndex = 0
var nextNumber = 1
var start = 0
val sb = StringBuilder(2 * formatString.length)
while (true) {
if (matcher.find(index)) {
if ("%" == matcher.group(6)) {
index = matcher.end()
continue
}
val matchStart = matcher.start()
// Make sure this is not an escaped '%'
while (prevIndex < matchStart) {
val c = formatString[prevIndex]
if (c == '\\') {
prevIndex++
}
prevIndex++
}
if (prevIndex > matchStart) {
// We're in an escape, ignore this result
index = prevIndex
continue
}
index = matcher.end()
// Shouldn't throw a number format exception since we've already
// matched the pattern in the regexp
val number: Int
var numberString: String? = matcher.group(1)
if (numberString != null) {
// Strip off trailing $
numberString = numberString.substring(0, numberString.length - 1)
number = Integer.parseInt(numberString)
nextNumber = number + 1
}
else {
number = nextNumber++
}
if (number > 0 && number < args.size) {
val argExpression = args[number]
var value: Any? = argExpression.evaluate()
if (value == null) {
value = args[number].asSourceString()
}
for (i in start..matchStart - 1) {
sb.append(formatString[i])
}
sb.append("{")
sb.append(value)
sb.append('}')
start = index
}
}
else {
var i = start
val n = formatString.length
while (i < n) {
sb.append(formatString[i])
i++
}
break
}
}
return sb.toString()
}
private fun getAppResources(element: PsiElement): LocalResourceRepository? = ModuleUtilCore.findModuleForPsiElement(element)?.let {
ResourceRepositoryManager.getOrCreateInstance(it)?.getAppResources(false)
}
}
@@ -1,111 +0,0 @@
/*
* Copyright 2010-2015 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.kotlin.android.navigation
import org.jetbrains.android.util.AndroidResourceUtil
import com.intellij.psi.PsiElement
import org.jetbrains.android.facet.AndroidFacet
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.PsiClass
import org.jetbrains.android.util.AndroidUtils
import com.android.SdkConstants
import com.android.tools.idea.res.AndroidInternalRClassFinder
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.psi.KtExpression
fun getReferenceExpression(element: PsiElement?): KtSimpleNameExpression? {
return PsiTreeUtil.getParentOfType<KtSimpleNameExpression>(element, KtSimpleNameExpression::class.java)
}
// given 'R.a.b' returns info for all three parts of the expression 'a', 'b', 'R'
fun getInfo(
referenceExpression: KtSimpleNameExpression,
facet: AndroidFacet
): AndroidResourceUtil.MyReferredResourceFieldInfo? {
val info = getReferredInfo(referenceExpression, facet)
if (info != null) return info
val topMostQualified = referenceExpression.getParentQualified().getParentQualified() ?: return null
val selectorCandidate = topMostQualified.selectorExpression as? KtSimpleNameExpression ?: return null
return getReferredInfo(selectorCandidate, facet)
}
private fun KtExpression?.getParentQualified(): KtDotQualifiedExpression? {
return this?.parent as? KtDotQualifiedExpression
}
// returns info if passed expression is 'b' in 'R.a.b'
private fun getReferredInfo(
lastPart: KtSimpleNameExpression,
facet: AndroidFacet
): AndroidResourceUtil.MyReferredResourceFieldInfo? {
val resFieldName = lastPart.getReferencedName()
if (resFieldName.isEmpty()) return null
val middlePart = getReceiverAsSimpleNameExpression(lastPart) ?: return null
val resClassName = middlePart.getReferencedName()
if (resClassName.isEmpty()) return null
val firstPart = getReceiverAsSimpleNameExpression(middlePart) ?: return null
val resolvedClass = firstPart.mainReference.resolve() as? PsiClass ?: return null
//the following code is copied from
// org.jetbrains.android.util.AndroidResourceUtil.getReferredResourceOrManifestField
// (org.jetbrains.android.facet.AndroidFacet, com.intellij.psi.PsiReferenceExpression, java.lang.String, boolean)
val classShortName = resolvedClass.name
val fromManifest = AndroidUtils.MANIFEST_CLASS_NAME == classShortName
if (!fromManifest && AndroidUtils.R_CLASS_NAME != classShortName) {
return null
}
val qName = resolvedClass.qualifiedName
if (SdkConstants.CLASS_R == qName || AndroidInternalRClassFinder.INTERNAL_R_CLASS_QNAME == qName) {
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, facet.module, true, false)
}
val containingFile = resolvedClass.containingFile ?: return null
val isFromCorrectFile =
if (fromManifest) AndroidResourceUtil.isManifestJavaFile(facet, containingFile)
else AndroidResourceUtil.isRJavaFile(facet, containingFile)
if (!isFromCorrectFile) {
return null
}
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, facet.module, false, fromManifest)
}
private fun getReceiverAsSimpleNameExpression(exp: KtSimpleNameExpression): KtSimpleNameExpression? {
val receiver = exp.getReceiverExpression()
return when (receiver) {
is KtSimpleNameExpression -> {
receiver
}
is KtDotQualifiedExpression -> {
receiver.selectorExpression as? KtSimpleNameExpression
}
else -> null
}
}
@@ -1,98 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.android.quickfix
import com.android.SdkConstants
import com.android.tools.lint.checks.ApiDetector.REQUIRES_API_ANNOTATION
import com.intellij.codeInsight.FileModificationService
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.android.inspections.lint.AndroidLintQuickFix
import org.jetbrains.android.inspections.lint.AndroidQuickfixContexts
import org.jetbrains.android.util.AndroidBundle
import org.jetbrains.kotlin.android.hasBackingField
import org.jetbrains.kotlin.idea.util.addAnnotation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
class AddTargetApiQuickFix(
val api: Int,
val useRequiresApi: Boolean,
val useNewName: Boolean = false
) : AndroidLintQuickFix {
private companion object {
val FQNAME_TARGET_API = FqName(SdkConstants.FQCN_TARGET_API)
}
override fun isApplicable(startElement: PsiElement, endElement: PsiElement, contextType: AndroidQuickfixContexts.ContextType): Boolean =
getAnnotationContainer(startElement, useRequiresApi) != null
override fun getName(): String = getAnnotationValue(false).let {
if (useRequiresApi) {
// Not Available in Android plugin 2.0
// AndroidBundle.message("android.lint.fix.add.requires.api", it)
"Add @RequiresApi($it) Annotation"
} else {
AndroidBundle.message("android.lint.fix.add.target.api", it)
}
}
override fun apply(startElement: PsiElement, endElement: PsiElement, context: AndroidQuickfixContexts.Context) {
val annotationContainer = getAnnotationContainer(startElement, useRequiresApi) ?: return
if (!FileModificationService.getInstance().preparePsiElementForWrite(annotationContainer)) {
return
}
if (annotationContainer is KtModifierListOwner) {
annotationContainer.addAnnotation(
if (useRequiresApi)
if (useNewName) FqName(REQUIRES_API_ANNOTATION.newName())
else FqName(REQUIRES_API_ANNOTATION.oldName())
else FQNAME_TARGET_API,
getAnnotationValue(true),
whiteSpaceText = if (annotationContainer.isNewLineNeededForAnnotation()) "\n" else " ")
}
}
private fun KtElement.isNewLineNeededForAnnotation() = !(this is KtParameter || this is KtTypeParameter || this is KtPropertyAccessor)
private fun getAnnotationValue(fullyQualified: Boolean) = getVersionField(api, fullyQualified)
private fun getAnnotationContainer(element: PsiElement, useRequiresApi: Boolean): PsiElement? {
return PsiTreeUtil.findFirstParent(element) {
if (useRequiresApi)
it.isRequiresApiAnnotationValidTarget()
else
it.isTargetApiAnnotationValidTarget()
}
}
private fun PsiElement.isRequiresApiAnnotationValidTarget(): Boolean {
return this is KtClassOrObject ||
(this is KtFunction && this !is KtFunctionLiteral) ||
(this is KtProperty && !isLocal && hasBackingField()) ||
this is KtPropertyAccessor
}
private fun PsiElement.isTargetApiAnnotationValidTarget(): Boolean {
return this is KtClassOrObject ||
(this is KtFunction && this !is KtFunctionLiteral) ||
this is KtPropertyAccessor
}
}
@@ -1,94 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.android.quickfix
import com.intellij.codeInsight.FileModificationService
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.android.inspections.lint.AndroidLintQuickFix
import org.jetbrains.android.inspections.lint.AndroidQuickfixContexts
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.codeInsight.surroundWith.statement.KotlinIfSurrounder
import org.jetbrains.kotlin.idea.core.ShortenReferences
import org.jetbrains.kotlin.idea.inspections.findExistingEditor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class AddTargetVersionCheckQuickFix(val api: Int) : AndroidLintQuickFix {
override fun apply(startElement: PsiElement, endElement: PsiElement, context: AndroidQuickfixContexts.Context) {
val targetExpression = getTargetExpression(startElement)
val project = targetExpression?.project ?: return
val editor = targetExpression.findExistingEditor() ?: return
val file = targetExpression.containingFile
val documentManager = PsiDocumentManager.getInstance(project)
val document = documentManager.getDocument(file) ?: return
if (!FileModificationService.getInstance().prepareFileForWrite(file)) {
return
}
val surrounder = getSurrounder(targetExpression, "\"VERSION.SDK_INT < ${getVersionField(api, false)}\"")
val conditionRange = surrounder.surroundElements(project, editor, arrayOf(targetExpression)) ?: return
val conditionText = "android.os.Build.VERSION.SDK_INT >= ${getVersionField(api, true)}"
document.replaceString(conditionRange.startOffset, conditionRange.endOffset, conditionText)
documentManager.commitDocument(document)
ShortenReferences.DEFAULT.process(documentManager.getPsiFile(document) as KtFile,
conditionRange.startOffset,
conditionRange.startOffset + conditionText.length)
}
override fun isApplicable(startElement: PsiElement, endElement: PsiElement, contextType: AndroidQuickfixContexts.ContextType): Boolean =
getTargetExpression(startElement) != null
override fun getName(): String = "Surround with if (VERSION.SDK_INT >= VERSION_CODES.${getVersionField(api, false)}) { ... }"
private fun getTargetExpression(element: PsiElement): KtElement? {
var current = PsiTreeUtil.getParentOfType(element, KtExpression::class.java)
while (current != null) {
if (current.parent is KtBlockExpression ||
current.parent is KtContainerNode ||
current.parent is KtWhenEntry ||
current.parent is KtFunction ||
current.parent is KtPropertyAccessor ||
current.parent is KtProperty ||
current.parent is KtReturnExpression ||
current.parent is KtDestructuringDeclaration) {
break
}
current = PsiTreeUtil.getParentOfType(current, KtExpression::class.java, true)
}
return current
}
private fun getSurrounder(element: KtElement, todoText: String?): KotlinIfSurrounder {
val used = element.analyze(BodyResolveMode.PARTIAL_WITH_CFA)[BindingContext.USED_AS_EXPRESSION, element] ?: false
return if (used) {
object : KotlinIfSurrounder() {
override fun getCodeTemplate(): String = "if (a) { \n} else {\nTODO(${todoText ?: ""})\n}"
}
} else {
KotlinIfSurrounder()
}
}
}
@@ -1,84 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.android.quickfix
import com.android.SdkConstants.SUPPORT_ANNOTATIONS_PREFIX
import com.android.support.AndroidxName
import com.android.tools.lint.checks.ApiDetector
import com.android.tools.lint.checks.CommentDetector
import com.android.tools.lint.checks.ParcelDetector
import com.android.tools.lint.detector.api.Issue
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.android.inspections.lint.AndroidLintQuickFix
import org.jetbrains.android.inspections.lint.AndroidLintQuickFixProvider
import java.util.regex.Pattern
class KotlinAndroidQuickFixProvider : AndroidLintQuickFixProvider {
override fun getQuickFixes(
issue: Issue,
startElement: PsiElement,
endElement: PsiElement,
message: String,
data: Any?
): Array<AndroidLintQuickFix> {
val fixes: Array<AndroidLintQuickFix> = when (issue) {
ApiDetector.UNSUPPORTED, ApiDetector.INLINED -> getApiQuickFixes(issue, startElement, message)
ParcelDetector.ISSUE -> arrayOf(ParcelableQuickFix())
else -> emptyArray()
}
if (issue != CommentDetector.STOP_SHIP) {
return fixes + SuppressLintQuickFix(issue.id)
}
return fixes
}
fun getApiQuickFixes(issue: Issue, element: PsiElement, message: String): Array<AndroidLintQuickFix> {
val api = getRequiredVersion(message)
if (api == -1) {
return AndroidLintQuickFix.EMPTY_ARRAY
}
val project = element.project
if (JavaPsiFacade.getInstance(project).findClass(REQUIRES_API_ANNOTATION.newName(), GlobalSearchScope.allScope(project)) != null) {
return arrayOf(AddTargetApiQuickFix(api, true, true), AddTargetApiQuickFix(api, false, true), AddTargetVersionCheckQuickFix(api))
}
if (JavaPsiFacade.getInstance(project).findClass(REQUIRES_API_ANNOTATION.oldName(), GlobalSearchScope.allScope(project)) != null) {
return arrayOf(AddTargetApiQuickFix(api, true), AddTargetApiQuickFix(api, false), AddTargetVersionCheckQuickFix(api))
}
return arrayOf(AddTargetApiQuickFix(api, false), AddTargetVersionCheckQuickFix(api))
}
private fun getRequiredVersion(errorMessage: String): Int {
val pattern = Pattern.compile("\\s(\\d+)\\s")
val matcher = pattern.matcher(errorMessage)
if (matcher.find()) {
return Integer.parseInt(matcher.group(1))
}
return -1
}
companion object {
val REQUIRES_API_ANNOTATION = AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "RequiresApi")
}
}
@@ -1,388 +0,0 @@
/*
* Copyright 2000-2009 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.kotlin.android;
import com.android.SdkConstants;
import com.android.tools.idea.rendering.RenderSecurityManager;
import com.android.tools.idea.startup.AndroidCodeStyleSettingsModifier;
import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInspection.GlobalInspectionTool;
import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.ex.GlobalInspectionToolWrapper;
import com.intellij.codeInspection.ex.InspectionManagerEx;
import com.intellij.facet.FacetManager;
import com.intellij.facet.ModifiableFacetModel;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.codeStyle.CodeStyleSchemes;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.testFramework.InspectionTestUtil;
import com.intellij.testFramework.ThreadTracker;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
import com.intellij.testFramework.fixtures.JavaTestFixtureFactory;
import com.intellij.testFramework.fixtures.TestFixtureBuilder;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import com.intellij.testFramework.fixtures.impl.GlobalInspectionContextForTests;
import com.intellij.util.ArrayUtil;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.facet.AndroidRootUtil;
import org.jetbrains.android.formatter.AndroidXmlCodeStyleSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.picocontainer.MutablePicoContainer;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Copied from AS 2.3 sources
*/
@SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"})
public abstract class AndroidTestCase extends AndroidTestBase {
protected Module myModule;
protected List<Module> myAdditionalModules;
protected AndroidFacet myFacet;
protected CodeStyleSettings mySettings;
private List<String> myAllowedRoots = new ArrayList<>();
private boolean myUseCustomSettings;
@Override
protected void setUp() throws Exception {
super.setUp();
VfsRootAccess.allowRootAccess(KotlinTestUtils.getHomeDirectory());
TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName());
myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture());
JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
File moduleRoot = new File(myFixture.getTempDirPath());
if (!moduleRoot.exists()) {
assertTrue(moduleRoot.mkdirs());
}
initializeModuleFixtureBuilderWithSrcAndGen(moduleFixtureBuilder, moduleRoot.toString());
ArrayList<MyAdditionalModuleData> modules = new ArrayList<>();
configureAdditionalModules(projectBuilder, modules);
myFixture.setUp();
myFixture.setTestDataPath(getTestDataPath());
myModule = moduleFixtureBuilder.getFixture().getModule();
// Must be done before addAndroidFacet, and must always be done, even if a test provides
// its own custom manifest file. However, in that case, we will delete it shortly below.
createManifest();
myFacet = addAndroidFacet(myModule);
LanguageLevel languageLevel = getLanguageLevel();
if (languageLevel != null) {
LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(myModule.getProject());
if (extension != null) {
extension.setLanguageLevel(languageLevel);
}
}
// TODO: myFixture.copyDirectoryToProject(getResDir(), "res");
myAdditionalModules = new ArrayList<>();
for (MyAdditionalModuleData data : modules) {
Module additionalModule = data.myModuleFixtureBuilder.getFixture().getModule();
myAdditionalModules.add(additionalModule);
AndroidFacet facet = addAndroidFacet(additionalModule);
facet.getProperties().PROJECT_TYPE = data.myProjectType;
String rootPath = getAdditionalModulePath(data.myDirName);
myFixture.copyDirectoryToProject(getResDir(), rootPath + "/res");
myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, rootPath + '/' + SdkConstants.FN_ANDROID_MANIFEST_XML);
if (data.myIsMainModuleDependency) {
ModuleRootModificationUtil.addDependency(myModule, additionalModule);
}
}
if (providesCustomManifest()) {
deleteManifest();
}
if (RenderSecurityManager.RESTRICT_READS) {
// Unit test class loader includes disk directories which security manager does not allow access to
RenderSecurityManager.sEnabled = false;
}
ArrayList<String> allowedRoots = new ArrayList<>();
collectAllowedRoots(allowedRoots);
// TODO: registerAllowedRoots(allowedRoots, myTestRootDisposable);
mySettings = CodeStyleSettingsManager.getSettings(getProject()).clone();
AndroidCodeStyleSettingsModifier.modify(mySettings);
CodeStyleSettingsManager.getInstance(getProject()).setTemporarySettings(mySettings);
myUseCustomSettings = getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS;
getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS = true;
// Layoutlib rendering thread will be shutdown when the app is closed so do not report it as a leak
ThreadTracker.longRunningThreadCreated(ApplicationManager.getApplication(), "Layoutlib");
}
@Override
protected void tearDown() throws Exception {
try {
Sdk androidSdk = ProjectJdkTable.getInstance().findJdk(ANDROID_SDK_NAME);
if (androidSdk != null) {
ApplicationManager.getApplication().runWriteAction(() -> ProjectJdkTable.getInstance().removeJdk(androidSdk));
}
CodeStyleSettingsManager.getInstance(getProject()).dropTemporarySettings();
myModule = null;
myAdditionalModules = null;
myFixture.tearDown();
myFixture = null;
myFacet = null;
getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS = myUseCustomSettings;
if (RenderSecurityManager.RESTRICT_READS) {
RenderSecurityManager.sEnabled = true;
}
}
finally {
super.tearDown();
VfsRootAccess.disallowRootAccess(KotlinTestUtils.getHomeDirectory());
}
}
private static void initializeModuleFixtureBuilderWithSrcAndGen(JavaModuleFixtureBuilder moduleFixtureBuilder, String moduleRoot) {
moduleFixtureBuilder.addContentRoot(moduleRoot);
//noinspection ResultOfMethodCallIgnored
new File(moduleRoot + "/src/").mkdir();
moduleFixtureBuilder.addSourceRoot("src");
//noinspection ResultOfMethodCallIgnored
new File(moduleRoot + "/gen/").mkdir();
moduleFixtureBuilder.addSourceRoot("gen");
}
/**
* Returns the path that any additional modules registered by
* {@link #configureAdditionalModules(TestFixtureBuilder, List)} or
* {@link #addModuleWithAndroidFacet(TestFixtureBuilder, List, String, int, boolean)} are
* installed into.
*/
protected static String getAdditionalModulePath(@NotNull String moduleName) {
return "/additionalModules/" + moduleName;
}
/**
* Indicates whether this class provides its own {@code AndroidManifest.xml} for its tests. If
* {@code true}, then {@link #setUp()} calls {@link #deleteManifest()} before finishing.
*/
protected boolean providesCustomManifest() {
return false;
}
/**
* Get the "res" directory for this SDK. Children classes can override this if they need to
* provide a custom "res" location for tests.
*/
protected String getResDir() {
return "res";
}
/**
* Defines the project level to set for the test project, or null to get the default language
* level associated with the test project.
*/
@Nullable
protected LanguageLevel getLanguageLevel() {
return null;
}
protected static AndroidXmlCodeStyleSettings getAndroidCodeStyleSettings() {
return AndroidXmlCodeStyleSettings.getInstance(CodeStyleSchemes.getInstance().getDefaultScheme().getCodeStyleSettings());
}
/**
* Hook point for child test classes to register directories that can be safely accessed by all
* of its tests.
*
* @see {@link VfsRootAccess}
*/
protected void collectAllowedRoots(List<String> roots) throws IOException {
}
private void registerAllowedRoots(List<String> roots, @NotNull Disposable disposable) {
List<String> newRoots = new ArrayList<>(roots);
newRoots.removeAll(myAllowedRoots);
String[] newRootsArray = ArrayUtil.toStringArray(newRoots);
VfsRootAccess.allowRootAccess(newRootsArray);
myAllowedRoots.addAll(newRoots);
Disposer.register(disposable, () -> {
VfsRootAccess.disallowRootAccess(newRootsArray);
myAllowedRoots.removeAll(newRoots);
});
}
public static AndroidFacet addAndroidFacet(Module module) {
return addAndroidFacet(module, true);
}
private static AndroidFacet addAndroidFacet(Module module, boolean attachSdk) {
FacetManager facetManager = FacetManager.getInstance(module);
AndroidFacet facet = facetManager.createFacet(AndroidFacet.getFacetType(), "Android", null);
if (attachSdk) {
addLatestAndroidSdk(module);
}
ModifiableFacetModel facetModel = facetManager.createModifiableModel();
facetModel.addFacet(facet);
ApplicationManager.getApplication().runWriteAction(facetModel::commit);
return facet;
}
protected void configureAdditionalModules(
@NotNull TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder, @NotNull List<MyAdditionalModuleData> modules) {
}
protected final void addModuleWithAndroidFacet(
@NotNull TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder,
@NotNull List<MyAdditionalModuleData> modules,
@NotNull String dirName,
int projectType) {
// By default, created module is declared as a main module's dependency
addModuleWithAndroidFacet(projectBuilder, modules, dirName, projectType, true);
}
protected final void addModuleWithAndroidFacet(
@NotNull TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder,
@NotNull List<MyAdditionalModuleData> modules,
@NotNull String dirName,
int projectType,
boolean isMainModuleDependency) {
JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
String moduleDirPath = myFixture.getTempDirPath() + getAdditionalModulePath(dirName);
//noinspection ResultOfMethodCallIgnored
new File(moduleDirPath).mkdirs();
initializeModuleFixtureBuilderWithSrcAndGen(moduleFixtureBuilder, moduleDirPath);
modules.add(new MyAdditionalModuleData(moduleFixtureBuilder, dirName, projectType, isMainModuleDependency));
}
protected void createManifest() throws IOException {
myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, SdkConstants.FN_ANDROID_MANIFEST_XML);
}
protected final void createProjectProperties() throws IOException {
myFixture.copyFileToProject(SdkConstants.FN_PROJECT_PROPERTIES, SdkConstants.FN_PROJECT_PROPERTIES);
}
protected final void deleteManifest() throws IOException {
deleteManifest(myModule);
}
protected final void deleteManifest(final Module module) throws IOException {
AndroidFacet facet = AndroidFacet.getInstance(module);
assertNotNull(facet);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
String manifestRelativePath = facet.getProperties().MANIFEST_FILE_RELATIVE_PATH;
VirtualFile manifest = AndroidRootUtil.getFileByRelativeModulePath(module, manifestRelativePath, true);
if (manifest != null) {
try {
manifest.delete(this);
}
catch (IOException e) {
fail("Could not delete default manifest");
}
}
}
});
}
protected final void doGlobalInspectionTest(
@NotNull GlobalInspectionTool inspection, @NotNull String globalTestDir, @NotNull AnalysisScope scope) {
doGlobalInspectionTest(new GlobalInspectionToolWrapper(inspection), globalTestDir, scope);
}
/**
* Given an inspection and a path to a directory that contains an "expected.xml" file, run the
* inspection on the current test project and verify that its output matches that of the
* expected file.
*/
protected final void doGlobalInspectionTest(
@NotNull GlobalInspectionToolWrapper wrapper, @NotNull String globalTestDir, @NotNull AnalysisScope scope) {
myFixture.enableInspections(wrapper.getTool());
scope.invalidate();
InspectionManagerEx inspectionManager = (InspectionManagerEx)InspectionManager.getInstance(getProject());
GlobalInspectionContextForTests globalContext =
CodeInsightTestFixtureImpl.createGlobalContextForTool(scope, getProject(), inspectionManager, wrapper);
InspectionTestUtil.runTool(wrapper, scope, globalContext);
InspectionTestUtil.compareToolResults(globalContext, wrapper, false, getTestDataPath() + globalTestDir);
}
protected static class MyAdditionalModuleData {
final JavaModuleFixtureBuilder myModuleFixtureBuilder;
final String myDirName;
final int myProjectType;
final boolean myIsMainModuleDependency;
private MyAdditionalModuleData(
@NotNull JavaModuleFixtureBuilder moduleFixtureBuilder, @NotNull String dirName, int projectType, boolean isMainModuleDependency) {
myModuleFixtureBuilder = moduleFixtureBuilder;
myDirName = dirName;
myProjectType = projectType;
myIsMainModuleDependency = isMainModuleDependency;
}
}
@NotNull
protected <T> T registerApplicationComponent(@NotNull Class<T> key, @NotNull T instance) throws Exception {
MutablePicoContainer picoContainer = (MutablePicoContainer)ApplicationManager.getApplication().getPicoContainer();
@SuppressWarnings("unchecked")
T old = (T)picoContainer.getComponentInstance(key.getName());
picoContainer.unregisterComponent(key.getName());
picoContainer.registerComponentInstance(key.getName(), instance);
return old;
}
@NotNull
protected <T> T registerProjectComponent(@NotNull Class<T> key, @NotNull T instance) {
MutablePicoContainer picoContainer = (MutablePicoContainer)getProject().getPicoContainer();
@SuppressWarnings("unchecked")
T old = (T)picoContainer.getComponentInstance(key.getName());
picoContainer.unregisterComponent(key.getName());
picoContainer.registerComponentInstance(key.getName(), instance);
return old;
}
}
@@ -1,376 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.gradle
import com.intellij.openapi.roots.DependencyScope
import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.impl.ModuleOrderEntryImpl
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.PathUtil
import junit.framework.TestCase
import org.jetbrains.kotlin.idea.codeInsight.gradle.MultiplePluginVersionGradleImportingTestCase
import org.jetbrains.kotlin.idea.codeInsight.gradle.facetSettings
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.util.rootManager
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.junit.Test
class MultiplatformProjectImportingTest : MultiplePluginVersionGradleImportingTestCase() {
private fun legacyMode() = gradleVersion.split(".")[0].toInt() < 4
private fun getDependencyLibraryUrls(moduleName: String) =
getRootManager(moduleName)
.orderEntries
.filterIsInstance<LibraryOrderEntry>()
.flatMap { it.getUrls(OrderRootType.CLASSES).map { it.replace(projectPath, "") } }
private fun assertProductionOnTestDependency(moduleName: String, depModuleName: String, expected: Boolean) {
val depOrderEntry = getModule(moduleName)
.rootManager
.orderEntries
.filterIsInstance<ModuleOrderEntryImpl>()
.first { it.moduleName == depModuleName }
assert(depOrderEntry.isProductionOnTestDependency == expected)
}
private fun assertFileInModuleScope(file: VirtualFile, moduleName: String) {
assert(getModule(moduleName).getModuleWithDependenciesAndLibrariesScope(true).contains(file))
}
override fun isApplicableTest(): Boolean {
return shouldRunTest(gradleKotlinPluginVersion, gradleVersion)
}
@Test
fun testPlatformToCommonDependency() {
val files = configureByFiles()
importProject()
assertModuleModuleDepScope("jvm", "common", DependencyScope.COMPILE)
assertModuleModuleDepScope("js", "common", DependencyScope.COMPILE)
assertProductionOnTestDependency("jvm", "common", false)
assertProductionOnTestDependency("js", "common", false)
val commonTestFile = files.find { it.path.contains("common") }!!
}
@Test
fun testPlatformToCommonExpectedByDependency() {
configureByFiles()
importProject()
assertModuleModuleDepScope("jvm", "common1", DependencyScope.COMPILE)
assertModuleModuleDepScope("jvm", "common2", DependencyScope.COMPILE)
assertModuleModuleDepScope("js", "common1", DependencyScope.COMPILE)
assertNoDepForModule("js", "common2")
}
@Test
fun testPlatformToCommonExpByInComposite() { // renamed from testPlatformToCommonExpectedByDependencyInComposite due to lack support of long names under Windows
configureByFiles()
importProject()
TestCase.assertEquals(listOf("common"), facetSettings("jvm").implementedModuleNames)
TestCase.assertEquals(listOf("common"), facetSettings("js").implementedModuleNames)
assertModuleModuleDepScope("jvm", "common", DependencyScope.COMPILE)
assertModuleModuleDepScope("js", "common", DependencyScope.COMPILE)
}
@Test
fun testPlatformToCommonDependencyRoot() {
configureByFiles()
importProject()
assertModuleModuleDepScope("jvm", "foo", DependencyScope.COMPILE)
assertModuleModuleDepScope("js", "foo", DependencyScope.COMPILE)
}
@Test
fun testMultiProject() {
configureByFiles()
importProject()
assertModuleModuleDepScope("jvm-app", "common-app", DependencyScope.COMPILE)
assertModuleModuleDepScope("jvm-app", "common-lib", DependencyScope.COMPILE)
if (legacyMode()) {
assertModuleModuleDepScope(
"jvm-app",
"jvm-lib",
DependencyScope.COMPILE, DependencyScope.RUNTIME, DependencyScope.PROVIDED, DependencyScope.TEST
)
} else {
assertModuleModuleDepScope(
"jvm-app",
"jvm-lib",
DependencyScope.COMPILE
)
}
assertModuleModuleDepScope("js-app", "common-app", DependencyScope.COMPILE)
assertModuleModuleDepScope("js-app", "common-lib", DependencyScope.COMPILE)
if (legacyMode()) {
assertModuleModuleDepScope(
"js-app",
"js-lib",
DependencyScope.COMPILE, DependencyScope.RUNTIME, DependencyScope.PROVIDED, DependencyScope.TEST
)
} else {
assertModuleModuleDepScope(
"js-app",
"js-lib",
DependencyScope.COMPILE
)
}
}
@Test
fun testDependenciesReachableViaImpl() {
configureByFiles()
importProject()
if (legacyMode()) {
assertModuleModuleDepScope(
"jvm-app",
"jvm-lib2",
DependencyScope.COMPILE, DependencyScope.RUNTIME, DependencyScope.PROVIDED, DependencyScope.TEST
)
} else {
assertModuleModuleDepScope(
"jvm-app",
"jvm-lib2",
DependencyScope.COMPILE
)
}
if (legacyMode()) {
assertModuleModuleDepScope(
"jvm-app",
"jvm-lib1",
DependencyScope.COMPILE, DependencyScope.RUNTIME, DependencyScope.PROVIDED, DependencyScope.TEST
)
} else {
assertModuleModuleDepScope(
"jvm-app",
"jvm-lib1",
DependencyScope.COMPILE
)
}
assertModuleModuleDepScope("jvm-app","common-lib1", DependencyScope.COMPILE)
assertModuleModuleDepScope("jvm-app", "common-lib2",DependencyScope.COMPILE)
}
@Test
fun testTransitiveImplement() {
configureByFiles()
val isResolveModulePerSourceSet = getCurrentExternalProjectSettings().isResolveModulePerSourceSet
try {
currentExternalProjectSettings.isResolveModulePerSourceSet = true
importProject()
assertModuleModuleDepScope("project2", "project1", DependencyScope.COMPILE)
if (legacyMode()) {
assertModuleModuleDepScope(
"project3",
"project2",
DependencyScope.COMPILE, DependencyScope.RUNTIME, DependencyScope.PROVIDED, DependencyScope.TEST
)
} else {
assertModuleModuleDepScope(
"project3",
"project2",
DependencyScope.COMPILE
)
}
assertModuleModuleDepScope("project3", "project1", DependencyScope.COMPILE)
currentExternalProjectSettings.isResolveModulePerSourceSet = false
importProject()
assertModuleModuleDepScope("project2", "project1", DependencyScope.COMPILE)
if (legacyMode()) {
assertModuleModuleDepScope(
"project3",
"project2",
DependencyScope.COMPILE, DependencyScope.RUNTIME, DependencyScope.PROVIDED, DependencyScope.TEST
)
} else {
assertModuleModuleDepScope(
"project3",
"project2",
DependencyScope.COMPILE
)
}
assertModuleModuleDepScope("project3", "project1", DependencyScope.COMPILE)
} finally {
currentExternalProjectSettings.isResolveModulePerSourceSet = isResolveModulePerSourceSet
}
}
@Test
fun testTransitiveImplementWithNonDefaultConfig() {
configureByFiles()
val isResolveModulePerSourceSet = getCurrentExternalProjectSettings().isResolveModulePerSourceSet
try {
currentExternalProjectSettings.isResolveModulePerSourceSet = true
importProject()
assertModuleModuleDepScope("project2", "project1", DependencyScope.COMPILE)
assertModuleModuleDepScope(
"project3",
"project2",
DependencyScope.COMPILE, DependencyScope.RUNTIME, DependencyScope.PROVIDED, DependencyScope.TEST
)
assertNoDepForModule("project3", "project1")
TestCase.assertEquals(
listOf("jar:///project2/build/libs/project2-jar.jar!/"),
getDependencyLibraryUrls("project3")
)
currentExternalProjectSettings.isResolveModulePerSourceSet = false
importProject()
/*
* Note that currently such dependencies can't be imported correctly in "No separate module per source set" mode
* due to IDEA importer limitations
*/
assertModuleModuleDepScope("project2", "project1", DependencyScope.COMPILE)
assertModuleModuleDepScope("project3", "project2", DependencyScope.TEST, DependencyScope.PROVIDED, DependencyScope.RUNTIME)
assertModuleModuleDepScope("project3", "project1", DependencyScope.COMPILE)
TestCase.assertEquals(
emptyList<String>(),
getDependencyLibraryUrls("project3")
)
} finally {
currentExternalProjectSettings.isResolveModulePerSourceSet = isResolveModulePerSourceSet
}
}
@Test
fun testTransitiveImplementWithAndroid() {
configureByFiles()
createProjectSubFile(
"local.properties", """
sdk.dir=/${KotlinTestUtils.getAndroidSdkSystemIndependentPath()}
"""
)
val isResolveModulePerSourceSet = getCurrentExternalProjectSettings().isResolveModulePerSourceSet
try {
currentExternalProjectSettings.isResolveModulePerSourceSet = true
importProject()
assertModuleModuleDepScope("project3", "project2", DependencyScope.COMPILE)
assertModuleModuleDepScope("project3", "project1", DependencyScope.COMPILE)
TestCase.assertEquals(listOf("project1"), facetSettings("project2").implementedModuleNames)
currentExternalProjectSettings.isResolveModulePerSourceSet = false
importProject()
assertModuleModuleDepScope("project3", "project2", DependencyScope.COMPILE)
assertModuleModuleDepScope("project3", "project1", DependencyScope.COMPILE)
TestCase.assertEquals(listOf("project1"), facetSettings("project2").implementedModuleNames)
} finally {
currentExternalProjectSettings.isResolveModulePerSourceSet = isResolveModulePerSourceSet
}
}
@Test
fun simpleAndroidAppWithCommonModule() {
configureByFiles()
createProjectSubFile(
"local.properties", """
sdk.dir=/${KotlinTestUtils.getAndroidSdkSystemIndependentPath()}
"""
)
val isResolveModulePerSourceSet = getCurrentExternalProjectSettings().isResolveModulePerSourceSet
try {
currentExternalProjectSettings.isResolveModulePerSourceSet = true
importProject()
assertModuleModuleDepScope("app", "cmn", DependencyScope.COMPILE)
TestCase.assertEquals(listOf("cmn"), facetSettings("jvm").implementedModuleNames)
currentExternalProjectSettings.isResolveModulePerSourceSet = false
importProject()
assertModuleModuleDepScope("app", "cmn", DependencyScope.COMPILE)
TestCase.assertEquals(listOf("cmn"), facetSettings("jvm").implementedModuleNames)
} finally {
currentExternalProjectSettings.isResolveModulePerSourceSet = isResolveModulePerSourceSet
}
}
@Test
fun testJsTestOutputFile() {
configureByFiles()
importProject()
TestCase.assertEquals(
projectPath + "/project2/build/classes/${if (legacyMode()) "" else "kotlin/"}test/project2_test.js",
PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2"))!!.configuration.settings.testOutputPath)
)
}
@Test
fun testJsProductionOutputFile() {
configureByFiles()
importProject()
TestCase.assertEquals(
projectPath + "/project2/build/classes/${if (legacyMode()) "" else "kotlin/"}main/project2.js",
PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2"))!!.configuration.settings.productionOutputPath)
)
}
@Test
fun testJsTestOutputFileInProjectWithAndroid() {
configureByFiles()
createProjectSubFile(
"local.properties", """
sdk.dir=/${KotlinTestUtils.getAndroidSdkSystemIndependentPath()}
"""
)
importProject()
TestCase.assertEquals(
projectPath + "/project2/build/classes/${if (legacyMode()) "" else "kotlin/"}test/project2_test.js",
PathUtil.toSystemIndependentName(KotlinFacet.get(getModule("project2"))!!.configuration.settings.testOutputPath)
)
}
override fun testDataDirName(): String {
return "multiplatform"
}
}
@@ -1,51 +0,0 @@
/*
* Copyright 2010-2015 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.kotlin.idea.framework;
import com.intellij.framework.library.LibraryVersionProperties;
import com.intellij.openapi.roots.libraries.LibraryPresentationProvider;
import com.intellij.openapi.roots.libraries.LibraryProperties;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.idea.KotlinIcons;
import javax.swing.*;
import java.util.List;
public class JavaRuntimePresentationProvider extends LibraryPresentationProvider<LibraryVersionProperties> {
public static JavaRuntimePresentationProvider getInstance() {
return LibraryPresentationProvider.EP_NAME.findExtension(JavaRuntimePresentationProvider.class);
}
protected JavaRuntimePresentationProvider() {
super(JavaRuntimeLibraryDescription.Companion.getKOTLIN_JAVA_RUNTIME_KIND());
}
@Nullable
@Override
public Icon getIcon(@Nullable LibraryVersionProperties properties) {
return KotlinIcons.SMALL_LOGO;
}
@Nullable
@Override
public LibraryVersionProperties detect(@NotNull List<VirtualFile> classesRoots) {
String version = JavaRuntimeDetectionUtil.getJavaRuntimeVersion(classesRoots);
return version == null ? null : new LibraryVersionProperties(version);
}
}
@@ -1,21 +0,0 @@
description = "Kotlin Gradle Tooling support"
plugins {
kotlin("jvm")
id("jps-compatible")
}
dependencies {
compile(kotlinStdlib())
compile(project(":compiler:cli-common"))
compile(intellijPluginDep("gradle"))
compileOnly(intellijDep()) { includeJars("slf4j-api-1.7.10") }
}
sourceSets {
"main" { projectDefault() }
"test" {}
}
runtimeJar()
@@ -1,5 +0,0 @@
<idea-plugin>
<extensions defaultExtensionNs="com.intellij">
<externalAnnotator language="kotlin" implementationClass="org.jetbrains.android.inspections.lint.AndroidLintExternalAnnotator"/>
</extensions>
</idea-plugin>
-122
View File
@@ -1,122 +0,0 @@
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="android-lint.xml" xpointer="xpointer(/idea-plugin/*)"/>
<extensions defaultExtensionNs="com.intellij">
<gotoDeclarationHandler implementation="org.jetbrains.kotlin.android.navigation.KotlinAndroidGotoDeclarationHandler"/>
<moduleService serviceInterface="org.jetbrains.kotlin.android.synthetic.res.AndroidLayoutXmlFileManager"
serviceImplementation="org.jetbrains.kotlin.android.synthetic.idea.res.IDEAndroidLayoutXmlFileManager"/>
<psi.treeChangePreprocessor implementation="org.jetbrains.kotlin.android.synthetic.idea.AndroidPsiTreeChangePreprocessor"/>
<errorHandler implementation="org.jetbrains.kotlin.android.synthetic.idea.AndroidExtensionsReportSubmitter"/>
<gotoDeclarationHandler implementation="org.jetbrains.kotlin.android.synthetic.idea.AndroidGotoDeclarationHandler"/>
<localInspection implementationClass="org.jetbrains.kotlin.android.inspection.IllegalIdentifierInspection"
displayName="Illegal Android Identifier"
groupName="Kotlin Android"
enabledByDefault="true"
level="ERROR"/>
<localInspection implementationClass="org.jetbrains.kotlin.android.inspection.TypeParameterFindViewByIdInspection"
displayName="Cast can be converted to findViewById with type parameter"
groupName="Kotlin Android"
enabledByDefault="true"
cleanupTool="true"
level="WEAK WARNING"
language="kotlin" />
<codeInsight.lineMarkerProvider language="kotlin" implementationClass="org.jetbrains.kotlin.android.KotlinAndroidLineMarkerProvider"/>
<intentionAction>
<className>org.jetbrains.kotlin.android.intention.KotlinAndroidAddStringResource</className>
<category>Kotlin Android</category>
</intentionAction>
<externalProjectDataService implementation="org.jetbrains.kotlin.android.configure.KotlinGradleAndroidModuleModelProjectDataService"/>
<intentionAction>
<className>org.jetbrains.kotlin.android.intention.AddActivityToManifest</className>
<category>Kotlin Android</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.android.intention.AddServiceToManifest</className>
<category>Kotlin Android</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.android.intention.AddBroadcastReceiverToManifest</className>
<category>Kotlin Android</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.android.intention.ImplementParcelableAction</className>
<category>Kotlin Android</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.android.intention.RemoveParcelableAction</className>
<category>Kotlin Android</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.android.intention.RedoParcelableAction</className>
<category>Kotlin Android</category>
</intentionAction>
<codeInsight.unresolvedReferenceQuickFixProvider
implementation="org.jetbrains.kotlin.android.inspection.KotlinAndroidResourceQuickFixProvider"/>
<lang.foldingBuilder language="kotlin" implementationClass="org.jetbrains.kotlin.android.folding.ResourceFoldingBuilder" />
<annotator language="kotlin" implementationClass="org.jetbrains.kotlin.android.AndroidResourceReferenceAnnotator" />
<referencesSearch implementation="org.jetbrains.kotlin.AndroidExtensionsReferenceSearchExecutor"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.android.configure.KotlinAndroidGradleLibraryDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.android.configure.KotlinAndroidGradleMPPModuleDataService"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
<projectResolve implementation="org.jetbrains.kotlin.android.synthetic.idea.AndroidExtensionsProjectResolverExtension"/>
<projectResolve implementation="org.jetbrains.kotlin.android.configure.KotlinAndroidMPPGradleProjectResolver"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<expressionCodegenExtension implementation="org.jetbrains.kotlin.android.synthetic.idea.IDEAndroidExtensionsExpressionCodegenExtension"/>
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.android.synthetic.AndroidExtensionPropertiesComponentContainerContributor"/>
<classBuilderFactoryInterceptorExtension implementation="org.jetbrains.kotlin.android.synthetic.idea.IDEAndroidOnDestroyClassBuilderInterceptorExtension"/>
<packageFragmentProviderExtension implementation="org.jetbrains.kotlin.android.synthetic.idea.res.IDEAndroidPackageFragmentProviderExtension"/>
<simpleNameReferenceExtension implementation="org.jetbrains.kotlin.android.synthetic.idea.AndroidSimpleNameReferenceExtension"/>
<kotlinIndicesHelperExtension implementation="org.jetbrains.kotlin.android.synthetic.idea.AndroidIndicesHelperExtension"/>
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.android.synthetic.idea.AndroidExtensionsGradleImportHandler"/>
<quickFixContributor implementation="org.jetbrains.kotlin.android.quickfix.AndroidQuickFixRegistrar"/>
<projectConfigurator implementation="org.jetbrains.kotlin.android.configure.KotlinAndroidGradleModuleConfigurator"/>
<gradleModelFacade implementation="org.jetbrains.kotlin.android.configure.AndroidGradleModelFacade"/>
<completionInformationProvider implementation="org.jetbrains.kotlin.AndroidExtensionsCompletionInformationProvider" />
<expressionCodegenExtension implementation="org.jetbrains.kotlin.android.parcel.IDEParcelableCodegenExtension"/>
<syntheticResolveExtension implementation="org.jetbrains.kotlin.android.parcel.IDEParcelableResolveExtension"/>
<classBuilderFactoryInterceptorExtension implementation="org.jetbrains.kotlin.android.synthetic.codegen.ParcelableClinitClassBuilderInterceptorExtension"/>
<quickFixContributor implementation="org.jetbrains.kotlin.android.parcel.quickfixes.ParcelableQuickFixContributor"/>
<androidDexer implementation="org.jetbrains.kotlin.android.debugger.AndroidDexerImpl"/>
<highlighterExtension implementation="org.jetbrains.kotlin.android.AndroidHighlighterExtension"/>
</extensions>
<extensions defaultExtensionNs="com.android.tools.idea">
<npw.template.convertJavaToKotlinProvider implementation="org.jetbrains.kotlin.android.ConvertJavaToKotlinProviderImpl"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.android">
<androidLintQuickFixProvider implementation="org.jetbrains.kotlin.android.quickfix.KotlinAndroidQuickFixProvider" />
</extensions>
<extensions defaultExtensionNs="com.android.gradle.sync">
<postSyncModuleSetupStep implementation="org.jetbrains.kotlin.android.configure.KotlinAndroidModuleSetupStep"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin.android.model">
<androidModuleInfoProvider implementation="org.jetbrains.kotlin.android.model.impl.AndroidModuleInfoProviderImpl"/>
</extensions>
</idea-plugin>
-81
View File
@@ -1,81 +0,0 @@
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude" version="2" url="http://kotlinlang.org" allow-bundled-update="true">
<id>org.jetbrains.kotlin</id>
<name>Kotlin</name>
<description><![CDATA[
The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<br>
<a href="http://kotlinlang.org/docs/tutorials/getting-started.html">Getting Started in IntelliJ IDEA</a><br>
<a href="http://kotlinlang.org/docs/tutorials/kotlin-android.html">Getting Started in Android Studio</a><br>
<a href="http://slack.kotlinlang.org/">Public Slack</a><br>
<a href="https://youtrack.jetbrains.com/issues/KT">Issue tracker</a><br>
]]></description>
<version>@snapshot@</version>
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
<idea-version since-build="181.5281" until-build="181.*"/>
<depends>com.intellij.modules.platform</depends>
<depends>com.intellij.modules.androidstudio</depends>
<!-- required for Kotlin/Native plugin -->
<depends optional="true">org.jetbrains.kotlin.native.platform.deps</depends>
<depends optional="true" config-file="junit.xml">JUnit</depends>
<depends optional="true" config-file="gradle.xml">org.jetbrains.plugins.gradle</depends>
<depends optional="true" config-file="maven.xml">org.jetbrains.idea.maven</depends>
<depends optional="true" config-file="testng-j.xml">TestNG-J</depends>
<depends optional="true" config-file="kotlin-copyright.xml">com.intellij.copyright</depends>
<depends optional="true" config-file="android.xml">org.jetbrains.android</depends>
<depends optional="true" config-file="coverage.xml">Coverage</depends>
<depends optional="true" config-file="i18n.xml">com.intellij.java-i18n</depends>
<depends optional="true" config-file="injection.xml">org.intellij.intelliLang</depends>
<depends optional="true" config-file="decompiler.xml">org.jetbrains.java.decompiler</depends>
<depends optional="true" config-file="git4idea.xml">Git4Idea</depends>
<depends optional="true" config-file="stream-debugger.xml">org.jetbrains.debugger.streams</depends>
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
<depends>com.intellij.modules.java</depends>
<depends optional="true" config-file="javaScriptDebug.xml">JavaScriptDebugger</depends>
<!-- CIDR-PLUGIN-PLACEHOLDER-END -->
<xi:include href="plugin-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
<!-- CIDR-PLUGIN-EXCLUDE-START -->
<xi:include href="jvm.xml" xpointer="xpointer(/idea-plugin/*)"/>
<!-- CIDR-PLUGIN-EXCLUDE-END -->
<xi:include href="native.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="tipsAndTricks.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="extensions/ide.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="kotlinx-serialization.xml" xpointer="xpointer(/idea-plugin/*)"/>
<project-components>
<component>
<!-- This is a workaround for IDEA < 183. For details, see IDEA-200525. -->
<implementation-class>org.jetbrains.kotlin.idea.caches.ProjectRootModificationTrackerFixer</implementation-class>
</component>
</project-components>
<extensionPoints>
<xi:include href="extensions/compiler.xml" xpointer="xpointer(/idea-plugin/extensionPoints/*)"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.pluginUpdateVerifier"
interface="org.jetbrains.kotlin.idea.update.PluginUpdateVerifier"/>
</extensionPoints>
<xi:include href="plugin-kotlin-extensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<pluginUpdateVerifier implementation="org.jetbrains.kotlin.idea.update.GooglePluginUpdateVerifier"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"
serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/>
</extensions>
</idea-plugin>
@@ -1,243 +0,0 @@
/*
* Copyright 2010-2015 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.kotlin.idea.actions
import com.intellij.codeInsight.navigation.NavigationUtil
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.ide.scratch.ScratchFileService
import com.intellij.ide.scratch.ScratchRootType
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.MessageType
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.ui.ex.MessagesEx
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileVisitor
import com.intellij.openapi.wm.WindowManager
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiErrorElement
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiManager
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
import org.jetbrains.kotlin.idea.j2k.JavaToKotlinConverterFactory
import org.jetbrains.kotlin.idea.refactoring.toPsiFile
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.idea.util.application.progressIndicatorNullable
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.j2k.ConverterSettings
import org.jetbrains.kotlin.j2k.FilesResult
import org.jetbrains.kotlin.psi.KtFile
import java.io.File
import java.io.IOException
import java.util.*
class JavaToKotlinAction : AnAction() {
companion object {
private fun uniqueKotlinFileName(javaFile: VirtualFile): String {
val ioFile = File(javaFile.path.replace('/', File.separatorChar))
var i = 0
while (true) {
val fileName = javaFile.nameWithoutExtension + (if (i > 0) i else "") + ".kt"
if (!ioFile.resolveSibling(fileName).exists()) return fileName
i++
}
}
val title = "Convert Java to Kotlin"
private fun saveResults(javaFiles: List<PsiJavaFile>, convertedTexts: List<String>): List<VirtualFile> {
val result = ArrayList<VirtualFile>()
for ((psiFile, text) in javaFiles.zip(convertedTexts)) {
try {
val document = PsiDocumentManager.getInstance(psiFile.project).getDocument(psiFile)
if (document == null) {
MessagesEx.error(psiFile.project, "Failed to save conversion result: couldn't find document for " + psiFile.name).showLater()
continue
}
document.replaceString(0, document.textLength, text)
FileDocumentManager.getInstance().saveDocument(document)
val virtualFile = psiFile.virtualFile
if (ScratchRootType.getInstance().containsFile(virtualFile)) {
val mapping = ScratchFileService.getInstance().scratchesMapping
mapping.setMapping(virtualFile, KotlinFileType.INSTANCE.language)
}
else {
val fileName = uniqueKotlinFileName(virtualFile)
virtualFile.rename(this, fileName)
}
}
catch (e: IOException) {
MessagesEx.error(psiFile.project, e.message ?: "").showLater()
}
}
return result
}
fun convertFiles(
javaFiles: List<PsiJavaFile>, project: Project,
enableExternalCodeProcessing: Boolean = true,
askExternalCodeProcessing: Boolean = true
): List<KtFile> {
var converterResult: FilesResult? = null
fun convert() {
val converter =
JavaToKotlinConverterFactory.createJavaToKotlinConverter(
project,
ConverterSettings.defaultSettings,
IdeaJavaToKotlinServices
)
converterResult = converter.filesToKotlin(
javaFiles,
JavaToKotlinConverterFactory.createPostProcessor(formatCode = true),
progress = ProgressManager.getInstance().progressIndicatorNullable!!
)
}
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(
::convert,
title,
true,
project)) return emptyList()
var externalCodeUpdate: (() -> Unit)? = null
if (enableExternalCodeProcessing && converterResult!!.externalCodeProcessing != null) {
val question = "Some code in the rest of your project may require corrections after performing this conversion. Do you want to find such code and correct it too?"
if (!askExternalCodeProcessing || (Messages.showYesNoDialog(project, question, title, Messages.getQuestionIcon()) == Messages.YES)) {
ProgressManager.getInstance().runProcessWithProgressSynchronously(
{
runReadAction {
externalCodeUpdate = converterResult!!.externalCodeProcessing!!.prepareWriteOperation(
ProgressManager.getInstance().progressIndicatorNullable!!
)
}
},
title,
true,
project)
}
}
return project.executeWriteCommand("Convert files from Java to Kotlin", null) {
CommandProcessor.getInstance().markCurrentCommandAsGlobal(project)
val newFiles = saveResults(javaFiles, converterResult!!.results)
externalCodeUpdate?.invoke()
PsiDocumentManager.getInstance(project).commitAllDocuments()
newFiles.singleOrNull()?.let {
FileEditorManager.getInstance(project).openFile(it, true)
}
newFiles.map { it.toPsiFile(project) as KtFile }
}
}
}
override fun actionPerformed(e: AnActionEvent) {
val javaFiles = selectedJavaFiles(e).filter { it.isWritable }.toList()
val project = CommonDataKeys.PROJECT.getData(e.dataContext)!!
if (javaFiles.isEmpty()) {
val statusBar = WindowManager.getInstance().getStatusBar(project)
JBPopupFactory.getInstance()
.createHtmlTextBalloonBuilder("Nothing to convert:<br>No writable Java files found", MessageType.ERROR, null)
.createBalloon()
.showInCenterOf(statusBar.component)
}
val firstSyntaxError = javaFiles.asSequence().map { PsiTreeUtil.findChildOfType(it, PsiErrorElement::class.java) }.firstOrNull()
if (firstSyntaxError != null) {
val count = javaFiles.filter { PsiTreeUtil.hasErrorElements(it) }.count()
val question = firstSyntaxError.containingFile.name +
(if (count > 1) " and ${count - 1} more Java files" else " file") +
" contain syntax errors, the conversion result may be incorrect"
val okText = "Investigate Errors"
val cancelText = "Proceed with Conversion"
if (Messages.showOkCancelDialog(
project,
question,
title,
okText,
cancelText,
Messages.getWarningIcon()
) == Messages.OK) {
NavigationUtil.activateFileWithPsiElement(firstSyntaxError.navigationElement)
return
}
}
convertFiles(javaFiles, project)
}
override fun update(e: AnActionEvent) {
val virtualFiles = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) ?: return
val project = e.project ?: return
e.presentation.isEnabled = isAnyJavaFileSelected(project, virtualFiles)
}
private fun isAnyJavaFileSelected(project: Project, files: Array<VirtualFile>): Boolean {
if (files.any { it.isDirectory }) return true // Giving up on directories
val manager = PsiManager.getInstance(project)
return files.any { it.extension == JavaFileType.DEFAULT_EXTENSION && manager.findFile(it) is PsiJavaFile && it.isWritable }
}
private fun selectedJavaFiles(e: AnActionEvent): Sequence<PsiJavaFile> {
val virtualFiles = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) ?: return sequenceOf()
val project = e.project ?: return sequenceOf()
return allJavaFiles(virtualFiles, project)
}
private fun allJavaFiles(filesOrDirs: Array<VirtualFile>, project: Project): Sequence<PsiJavaFile> {
val manager = PsiManager.getInstance(project)
return allFiles(filesOrDirs)
.asSequence()
.mapNotNull { manager.findFile(it) as? PsiJavaFile }
}
private fun allFiles(filesOrDirs: Array<VirtualFile>): Collection<VirtualFile> {
val result = ArrayList<VirtualFile>()
for (file in filesOrDirs) {
VfsUtilCore.visitChildrenRecursively(file, object : VirtualFileVisitor<Unit>() {
override fun visitFile(file: VirtualFile): Boolean {
result.add(file)
return true
}
})
}
return result
}
}
@@ -1,124 +0,0 @@
/*
* Copyright 2010-2015 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.kotlin.idea.refactoring.changeSignature.ui
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiClassOwner
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiReference
import com.intellij.psi.search.searches.MethodReferencesSearch
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.refactoring.changeSignature.CallerChooserBase
import com.intellij.refactoring.changeSignature.MethodNodeBase
import com.intellij.ui.ColoredTreeCellRenderer
import com.intellij.ui.JBColor
import com.intellij.ui.SimpleTextAttributes
import com.intellij.ui.treeStructure.Tree
import com.intellij.util.Consumer
import com.intellij.util.ui.UIUtil
import org.jetbrains.kotlin.asJava.getRepresentativeLightMethod
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMethodDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.hierarchy.calls.CalleeReferenceProcessor
import org.jetbrains.kotlin.idea.hierarchy.calls.KotlinCallHierarchyNodeDescriptor
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import java.util.*
class KotlinCallerChooser(
declaration: PsiElement,
project: Project,
title: String,
previousTree: Tree?,
callback: Consumer<Set<PsiElement>>
): CallerChooserBase<PsiElement>(declaration, project, title, previousTree, "dummy." + KotlinFileType.EXTENSION, callback) {
override fun createTreeNode(method: PsiElement, called: HashSet<PsiElement>, cancelCallback: Runnable): KotlinMethodNode {
return KotlinMethodNode(method, called, myProject, cancelCallback)
}
override fun findDeepestSuperMethods(method: PsiElement) =
method.toLightMethods().singleOrNull()?.findDeepestSuperMethods()
override fun getEmptyCallerText() =
"Caller text \nwith highlighted callee call would be shown here"
override fun getEmptyCalleeText() =
"Callee text would be shown here"
}
class KotlinMethodNode(
method: PsiElement?,
called: HashSet<PsiElement>,
project: Project,
cancelCallback: Runnable
): MethodNodeBase<PsiElement>(method?.namedUnwrappedElement ?: method, called, project, cancelCallback) {
override fun createNode(caller: PsiElement, called: HashSet<PsiElement>) =
KotlinMethodNode(caller, called, myProject, myCancelCallback)
override fun customizeRendererText(renderer: ColoredTreeCellRenderer) {
val descriptor = when (myMethod) {
is KtFunction -> myMethod.unsafeResolveToDescriptor() as FunctionDescriptor
is KtClass -> (myMethod.unsafeResolveToDescriptor() as ClassDescriptor).unsubstitutedPrimaryConstructor ?: return
is PsiMethod -> myMethod.getJavaMethodDescriptor() ?: return
else -> throw AssertionError("Invalid declaration: ${myMethod.getElementTextWithContext()}")
}
val containerName = generateSequence<DeclarationDescriptor>(descriptor) { it.containingDeclaration }
.firstOrNull { it is ClassDescriptor }
?.name
val renderedFunction = KotlinCallHierarchyNodeDescriptor.renderNamedFunction(descriptor)
val renderedFunctionWithContainer =
containerName?.let {
"${if (it.isSpecial) "[Anonymous]" else it.asString()}.$renderedFunction"
} ?: renderedFunction
val attributes = if (isEnabled)
SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, UIUtil.getTreeForeground())
else
SimpleTextAttributes.EXCLUDED_ATTRIBUTES
renderer.append(renderedFunctionWithContainer, attributes)
val packageName = (myMethod.containingFile as? PsiClassOwner)?.packageName ?: ""
renderer.append(" ($packageName)", SimpleTextAttributes(SimpleTextAttributes.STYLE_ITALIC, JBColor.GRAY))
}
override fun computeCallers(): List<PsiElement> {
if (myMethod == null) return emptyList()
val callers = LinkedHashSet<PsiElement>()
val processor = object: CalleeReferenceProcessor(false) {
override fun onAccept(ref: PsiReference, element: PsiElement) {
if ((element is KtFunction || element is KtClass || element is PsiMethod) && element !in myCalled) {
callers.add(element)
}
}
}
val query = myMethod.getRepresentativeLightMethod()?.let { MethodReferencesSearch.search(it, it.useScope, true) }
?: ReferencesSearch.search(myMethod, myMethod.useScope)
query.forEach { processor.process(it) }
return callers.toList()
}
}
@@ -1,33 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.reporter
import com.intellij.diagnostic.ITNReporter
import com.intellij.openapi.diagnostic.IdeaLoggingEvent
import com.intellij.openapi.diagnostic.SubmittedReportInfo
import com.intellij.util.Consumer
import java.awt.Component
abstract class ITNReporterCompat : ITNReporter() {
final override fun submit(
events: Array<IdeaLoggingEvent>,
additionalInfo: String?,
parentComponent: Component?,
consumer: Consumer<SubmittedReportInfo>
): Boolean {
return submitCompat(events, additionalInfo, parentComponent, consumer)
}
open fun submitCompat(
events: Array<IdeaLoggingEvent>,
additionalInfo: String?,
parentComponent: Component?,
consumer: Consumer<SubmittedReportInfo>
): Boolean {
@Suppress("IncompatibleAPI")
return super.submit(events, additionalInfo, parentComponent, consumer)
}
}
@@ -1,39 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("DEPRECATION")
package org.jetbrains.kotlin.idea
import com.intellij.featureStatistics.FeatureStatisticsBundleProvider
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.extensions.Extensions
import java.lang.IllegalStateException
private const val CIDR_FEATURE_STATISTICS_PROVIDER_FQNAME = "com.jetbrains.cidr.lang.OCFeatureStatisticsBundleProvider"
// Remove the function, when there's no dependency to cidr during running Kotlin tests.
fun registerAdditionalResourceBundleInTests() {
if (!ApplicationManager.getApplication().isUnitTestMode) {
return
}
val isAlreadyRegistered = FeatureStatisticsBundleProvider.EP_NAME.extensions.any { provider ->
provider.javaClass.name == CIDR_FEATURE_STATISTICS_PROVIDER_FQNAME
}
if (isAlreadyRegistered) {
throw IllegalStateException("Remove this registration for the current platform: bundle is already registered.")
}
val cidrFSBundleProviderClass = try {
Class.forName(CIDR_FEATURE_STATISTICS_PROVIDER_FQNAME)
} catch (_: ClassNotFoundException) {
throw IllegalStateException("Remove this registration for the current platform: class wasn't found.")
}
val cidrFSBundleProvider = cidrFSBundleProviderClass.newInstance() as FeatureStatisticsBundleProvider
Extensions.getRootArea().getExtensionPoint(FeatureStatisticsBundleProvider.EP_NAME).registerExtension(cidrFSBundleProvider)
}
@@ -1,152 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.update
import com.intellij.ide.plugins.IdeaPluginDescriptor
import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.ide.plugins.PluginNode
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.kotlin.idea.util.isDev
import org.jetbrains.kotlin.idea.util.isEap
import java.io.IOException
import java.net.URL
import java.util.*
import javax.xml.bind.JAXBContext
import javax.xml.bind.JAXBException
import javax.xml.bind.annotation.*
class GooglePluginUpdateVerifier : PluginUpdateVerifier() {
override val verifierName: String
get() = "Android Studio"
// Verifies if a plugin can be installed in Android Studio 3.2+.
// Currently used only by KotlinPluginUpdater.
override fun verify(pluginDescriptor: IdeaPluginDescriptor): PluginVerifyResult? {
if (pluginDescriptor.pluginId.idString != KOTLIN_PLUGIN_ID) {
return null
}
val version = pluginDescriptor.version
if (isEap(version) || isDev(version)) {
return PluginVerifyResult.accept()
}
try {
val url = URL(METADATA_FILE_URL)
val stream = url.openStream()
val context = JAXBContext.newInstance(PluginCompatibility::class.java)
val unmarshaller = context.createUnmarshaller()
val pluginCompatibility = unmarshaller.unmarshal(stream) as PluginCompatibility
val release = getRelease(pluginCompatibility)
?: return PluginVerifyResult.decline("No verified versions for this build.")
return if (release.plugins().any { KOTLIN_PLUGIN_ID == it.id && version == it.version })
PluginVerifyResult.accept()
else
PluginVerifyResult.decline("Version to be verified.")
} catch (e: Exception) {
LOG.info("Exception when verifying plugin ${pluginDescriptor.pluginId.idString} version $version", e)
return when (e) {
is IOException ->
PluginVerifyResult.decline("unable to connect to compatibility verification repository")
is JAXBException -> PluginVerifyResult.decline("unable to parse compatibility verification metadata")
else -> PluginVerifyResult.decline("exception during verification ${e.message}")
}
}
}
private fun getRelease(pluginCompatibility: PluginCompatibility): StudioRelease? {
for (studioRelease in pluginCompatibility.releases()) {
if (buildInRange(studioRelease.name, studioRelease.sinceBuild, studioRelease.untilBuild)) {
return studioRelease
}
}
return null
}
private fun buildInRange(name: String?, sinceBuild: String?, untilBuild: String?): Boolean {
val descriptor = PluginNode()
descriptor.name = name
descriptor.sinceBuild = sinceBuild
descriptor.untilBuild = untilBuild
return PluginManagerCore.isCompatible(descriptor)
}
companion object {
private const val KOTLIN_PLUGIN_ID = "org.jetbrains.kotlin"
private const val METADATA_FILE_URL = "https://dl.google.com/android/studio/plugins/compatibility.xml"
private val LOG = Logger.getInstance(GooglePluginUpdateVerifier::class.java)
private fun PluginCompatibility.releases() = studioRelease ?: emptyArray()
private fun StudioRelease.plugins() = ideaPlugin ?: emptyArray()
@XmlRootElement(name = "plugin-compatibility")
@XmlAccessorType(XmlAccessType.FIELD)
class PluginCompatibility {
@XmlElement(name = "studio-release")
var studioRelease: Array<StudioRelease>? = null
override fun toString(): String {
return "PluginCompatibility(studioRelease=${Arrays.toString(studioRelease)})"
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class StudioRelease {
@XmlAttribute(name = "until-build")
var untilBuild: String? = null
@XmlAttribute(name = "since-build")
var sinceBuild: String? = null
@XmlAttribute
var name: String? = null
@XmlAttribute
var channel: String? = null
@XmlElement(name = "idea-plugin")
var ideaPlugin: Array<IdeaPlugin>? = null
override fun toString(): String {
return "StudioRelease(" +
"untilBuild=$untilBuild, name=$name, ideaPlugin=${Arrays.toString(ideaPlugin)}, " +
"sinceBuild=$sinceBuild, channel=$channel" +
")"
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class IdeaPlugin {
@XmlAttribute
var id: String? = null
@XmlAttribute
var sha256: String? = null
@XmlAttribute
var channel: String? = null
@XmlAttribute
var version: String? = null
@XmlElement(name = "idea-version")
var ideaVersion: IdeaVersion? = null
override fun toString(): String {
return "IdeaPlugin(id=$id, sha256=$sha256, ideaVersion=$ideaVersion, channel=$channel, version=$version)"
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class IdeaVersion {
@XmlAttribute(name = "until-build")
var untilBuild: String? = null
@XmlAttribute(name = "since-build")
var sinceBuild: String? = null
override fun toString(): String {
return "IdeaVersion(untilBuild=$untilBuild, sinceBuild=$sinceBuild)"
}
}
}
}
@@ -1,35 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.update
import com.intellij.ide.plugins.IdeaPluginDescriptor
import com.intellij.openapi.util.registry.Registry
import org.jetbrains.kotlin.idea.PluginUpdateStatus
// Do an additional verification with PluginUpdateVerifier. Enabled only in AS 3.2+
fun verify(updateStatus: PluginUpdateStatus.Update): PluginUpdateStatus {
@Suppress("InvalidBundleOrProperty")
val pluginVerifierEnabled = Registry.`is`("kotlin.plugin.update.verifier.enabled", true)
if (!pluginVerifierEnabled) {
return updateStatus
}
val pluginDescriptor: IdeaPluginDescriptor = updateStatus.pluginDescriptor
val pluginVerifiers = PluginUpdateVerifier.EP_NAME.extensions
for (pluginVerifier in pluginVerifiers) {
val verifyResult = pluginVerifier.verify(pluginDescriptor) ?: continue
if (!verifyResult.verified) {
return PluginUpdateStatus.Unverified(
pluginVerifier.verifierName,
verifyResult.declineMessage,
updateStatus
)
}
}
return updateStatus
}
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
@@ -1,5 +0,0 @@
// "Remove function body" "true"
abstract class A() {
/*1*/
abstract fun foo() // 3
}
@@ -1,9 +0,0 @@
// "class org.jetbrains.kotlin.idea.quickfix.AddArrayOfTypeFix" "false"
// ACTION: Create test
// ACTION: Do not show hints for current method
// ACTION: Make internal
// ACTION: Make private
// ACTION: To raw string literal
// ACTION: Do not show hints for current method
@ArrAnn(<caret>"123") class My
@@ -1,7 +0,0 @@
// "Suppress for declarations annotated by 'xxx.XXX'" "true"
package xxx
annotation class XXX
@XXX
class <caret>UnusedClass
@@ -1,7 +0,0 @@
// "Suppress for declarations annotated by 'xxx.XXX'" "true"
package xxx
annotation class XXX
@XXX
class <caret>UnusedClass
@@ -1,13 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jps.build
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.messages.CompilerMessage
fun jpsReportInternalBuilderError(context: CompileContext, error: Throwable) {
KotlinBuilder.LOG.info(error)
}
@@ -1,78 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.android.model.impl
import com.android.builder.model.SourceProvider
import com.android.tools.idea.gradle.project.GradleProjectInfo
import com.android.tools.idea.gradle.project.model.AndroidModuleModel
import com.android.tools.idea.res.ResourceRepositoryManager
import com.intellij.openapi.module.Module
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.android.facet.AndroidFacet
import org.jetbrains.kotlin.android.model.AndroidModuleInfoProvider
import java.io.File
class AndroidModuleInfoProviderImpl(override val module: Module) : AndroidModuleInfoProvider {
private val androidFacet: AndroidFacet?
get() = AndroidFacet.getInstance(module)
private val androidModuleModel: AndroidModuleModel?
get() = AndroidModuleModel.get(module)
override fun isAndroidModule() = androidFacet != null
override fun isGradleModule() = GradleProjectInfo.getInstance(module.project).isBuildWithGradle
override fun getAllResourceDirectories(): List<VirtualFile> {
return androidFacet?.allResourceDirectories ?: emptyList()
}
override fun getApplicationPackage() = androidFacet?.manifest?.`package`?.toString()
override fun getMainSourceProvider(): AndroidModuleInfoProvider.SourceProviderMirror? {
return androidFacet?.mainSourceProvider?.let(::SourceProviderMirrorImpl)
}
override fun getApplicationResourceDirectories(createIfNecessary: Boolean): Collection<VirtualFile> {
return ResourceRepositoryManager.getOrCreateInstance(module)?.getAppResources(createIfNecessary)?.resourceDirs ?: emptyList()
}
override fun getAllSourceProviders(): List<AndroidModuleInfoProvider.SourceProviderMirror> {
val androidModuleModel = this.androidModuleModel ?: return emptyList()
return androidModuleModel.allSourceProviders.map(::SourceProviderMirrorImpl)
}
override fun getActiveSourceProviders(): List<AndroidModuleInfoProvider.SourceProviderMirror> {
val androidModuleModel = this.androidModuleModel ?: return emptyList()
return androidModuleModel.activeSourceProviders.map(::SourceProviderMirrorImpl)
}
override fun getFlavorSourceProviders(): List<AndroidModuleInfoProvider.SourceProviderMirror> {
val androidModuleModel = this.androidModuleModel ?: return emptyList()
val getFlavorSourceProvidersMethod = try {
AndroidFacet::class.java.getMethod("getFlavorSourceProviders")
} catch (e: NoSuchMethodException) {
null
}
return if (getFlavorSourceProvidersMethod != null) {
@Suppress("UNCHECKED_CAST")
val sourceProviders = getFlavorSourceProvidersMethod.invoke(androidFacet) as? List<SourceProvider>
sourceProviders?.map(::SourceProviderMirrorImpl) ?: emptyList()
} else {
androidModuleModel.flavorSourceProviders.map(::SourceProviderMirrorImpl)
}
}
private class SourceProviderMirrorImpl(val sourceProvider: SourceProvider) :
AndroidModuleInfoProvider.SourceProviderMirror {
override val name: String
get() = sourceProvider.name
override val resDirectories: Collection<File>
get() = sourceProvider.resDirectories
}
}
@@ -1,197 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.kapt.idea
import com.android.ide.common.gradle.model.IdeBaseArtifact
import com.android.tools.idea.gradle.project.model.AndroidModuleModel
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.ProjectKeys
import com.intellij.openapi.externalSystem.model.project.*
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.tooling.model.idea.IdeaModule
import org.jetbrains.kotlin.gradle.AbstractKotlinGradleModelBuilder
import org.jetbrains.kotlin.idea.framework.GRADLE_SYSTEM_ID
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
import java.io.File
import java.io.Serializable
import java.lang.Exception
import java.lang.reflect.Modifier
interface KaptSourceSetModel : Serializable {
val sourceSetName: String
val isTest: Boolean
val generatedSourcesDir: String
val generatedClassesDir: String
val generatedKotlinSourcesDir: String
val generatedSourcesDirFile get() = generatedSourcesDir.takeIf { it.isNotEmpty() }?.let(::File)
val generatedClassesDirFile get() = generatedClassesDir.takeIf { it.isNotEmpty() }?.let(::File)
val generatedKotlinSourcesDirFile get() = generatedKotlinSourcesDir.takeIf { it.isNotEmpty() }?.let(::File)
}
class KaptSourceSetModelImpl(
override val sourceSetName: String,
override val isTest: Boolean,
override val generatedSourcesDir: String,
override val generatedClassesDir: String,
override val generatedKotlinSourcesDir: String
) : KaptSourceSetModel
interface KaptGradleModel : Serializable {
val isEnabled: Boolean
val buildDirectory: File
val sourceSets: List<KaptSourceSetModel>
}
class KaptGradleModelImpl(
override val isEnabled: Boolean,
override val buildDirectory: File,
override val sourceSets: List<KaptSourceSetModel>
) : KaptGradleModel
internal typealias AndroidGradleModel = AndroidModuleModel
@Suppress("unused")
class KaptProjectResolverExtension : AbstractProjectResolverExtension() {
private companion object {
private val LOG = Logger.getInstance(KaptProjectResolverExtension::class.java)
}
override fun getExtraProjectModelClasses() = setOf(KaptGradleModel::class.java)
override fun getToolingExtensionsClasses() = setOf(KaptModelBuilderService::class.java, Unit::class.java)
override fun populateModuleExtraModels(gradleModule: IdeaModule, ideModule: DataNode<ModuleData>) {
val kaptModel = resolverCtx.getExtraProject(gradleModule, KaptGradleModel::class.java)
if (kaptModel != null && kaptModel.isEnabled) {
for (sourceSet in kaptModel.sourceSets) {
populateAndroidModuleModelIfNeeded(ideModule, sourceSet)
val sourceSetDataNode = ideModule.findGradleSourceSet(sourceSet.sourceSetName) ?: continue
fun addSourceSet(path: String, type: ExternalSystemSourceType) {
val contentRootData = ContentRootData(GRADLE_SYSTEM_ID, path)
contentRootData.storePath(type, path)
sourceSetDataNode.createChild(ProjectKeys.CONTENT_ROOT, contentRootData)
}
val sourceType = if (sourceSet.isTest) ExternalSystemSourceType.TEST_GENERATED else ExternalSystemSourceType.SOURCE_GENERATED
sourceSet.generatedSourcesDirFile?.let { addSourceSet(it.absolutePath, sourceType) }
sourceSet.generatedKotlinSourcesDirFile?.let { addSourceSet(it.absolutePath, sourceType) }
sourceSet.generatedClassesDirFile?.let { generatedClassesDir ->
val libraryData = LibraryData(GRADLE_SYSTEM_ID, "kaptGeneratedClasses")
libraryData.addPath(LibraryPathType.BINARY, generatedClassesDir.absolutePath)
val libraryDependencyData = LibraryDependencyData(sourceSetDataNode.data, libraryData, LibraryLevel.MODULE)
sourceSetDataNode.createChild(ProjectKeys.LIBRARY_DEPENDENCY, libraryDependencyData)
}
}
}
super.populateModuleExtraModels(gradleModule, ideModule)
}
private fun populateAndroidModuleModelIfNeeded(ideModule: DataNode<ModuleData>, sourceSet: KaptSourceSetModel) {
ideModule.findAndroidModuleModel()?.let { androidModelAny ->
// We can cast to AndroidModuleModel cause we already checked in findAndroidModuleModel() that the class exists
val generatedKotlinSources = sourceSet.generatedKotlinSourcesDirFile ?: return
val androidModel = androidModelAny.data as? AndroidModuleModel ?: return
val variant = androidModel.findVariantByName(sourceSet.sourceSetName) ?: return
val mainArtifact = variant.mainArtifact
if (mainArtifact is IdeBaseArtifact) {
mainArtifact.addGeneratedSourceFolder(generatedKotlinSources)
}
}
}
private fun DataNode<ModuleData>.findAndroidModuleModel(): DataNode<*>? {
val modelClassName = "com.android.tools.idea.gradle.project.model.AndroidModuleModel"
val node = children.firstOrNull { it.key.dataType == modelClassName } ?: return null
return if (!hasClassInClasspath(modelClassName)) null else node
}
private fun hasClassInClasspath(name: String): Boolean {
return try {
Class.forName(name) != null
} catch (thr: Throwable) {
false
}
}
private fun DataNode<ModuleData>.findGradleSourceSet(sourceSetName: String): DataNode<GradleSourceSetData>? {
val moduleName = data.id
for (child in children) {
val gradleSourceSetData = child.data as? GradleSourceSetData ?: continue
if (gradleSourceSetData.id == "$moduleName:$sourceSetName") {
@Suppress("UNCHECKED_CAST")
return child as DataNode<GradleSourceSetData>?
}
}
return null
}
}
class KaptModelBuilderService : AbstractKotlinGradleModelBuilder() {
override fun getErrorMessageBuilder(project: Project, e: Exception): ErrorMessageBuilder {
return ErrorMessageBuilder.create(project, e, "Gradle import errors")
.withDescription("Unable to build kotlin-kapt plugin configuration")
}
override fun canBuild(modelName: String?): Boolean = modelName == KaptGradleModel::class.java.name
override fun buildAll(modelName: String?, project: Project): Any {
val kaptPlugin: Plugin<*>? = project.plugins.findPlugin("kotlin-kapt")
val kaptIsEnabled = kaptPlugin != null
val sourceSets = mutableListOf<KaptSourceSetModel>()
if (kaptIsEnabled) {
project.getAllTasks(false)[project]?.forEach { compileTask ->
if (compileTask.javaClass.name !in kotlinCompileTaskClasses) return@forEach
val sourceSetName = compileTask.getSourceSetName()
val isTest = sourceSetName.toLowerCase().endsWith("test")
val kaptGeneratedSourcesDir = getKaptDirectory("getKaptGeneratedSourcesDir", project, sourceSetName)
val kaptGeneratedClassesDir = getKaptDirectory("getKaptGeneratedClassesDir", project, sourceSetName)
val kaptGeneratedKotlinSourcesDir = getKaptDirectory("getKaptGeneratedKotlinSourcesDir", project, sourceSetName)
sourceSets += KaptSourceSetModelImpl(
sourceSetName, isTest, kaptGeneratedSourcesDir, kaptGeneratedClassesDir, kaptGeneratedKotlinSourcesDir)
}
}
return KaptGradleModelImpl(kaptIsEnabled, project.buildDir, sourceSets)
}
private fun getKaptDirectory(funName: String, project: Project, sourceSetName: String): String {
val kotlinKaptPlugin = project.plugins.findPlugin("kotlin-kapt") ?: return ""
val targetMethod = kotlinKaptPlugin::class.java.methods.firstOrNull {
Modifier.isStatic(it.modifiers) && it.name == funName && it.parameterCount == 2
} ?: return ""
return (targetMethod(null, project, sourceSetName) as? File)?.absolutePath ?: ""
}
}
@@ -1,56 +0,0 @@
/*
* Copyright 2010-2017 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.kotlin.samWithReceiver.ide
/*
import org.jetbrains.kotlin.annotation.plugin.ide.AbstractMavenImportHandler
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedCompilerPluginSetup
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedCompilerPluginSetup.PluginOption
import org.jetbrains.kotlin.samWithReceiver.SamWithReceiverCommandLineProcessor
import org.jetbrains.kotlin.utils.PathUtil
class SamWithReceiverMavenProjectImportHandler : AbstractMavenImportHandler() {
private companion object {
val ANNOTATION_PARAMETER_PREFIX = "sam-with-receiver:${SamWithReceiverCommandLineProcessor.ANNOTATION_OPTION.name}="
}
override val compilerPluginId = SamWithReceiverCommandLineProcessor.PLUGIN_ID
override val pluginName = "samWithReceiver"
override val mavenPluginArtifactName = "kotlin-maven-sam-with-receiver"
override val pluginJarFileFromIdea = PathUtil.kotlinPathsForIdeaPlugin.allOpenPluginJarPath
override fun getOptions(enabledCompilerPlugins: List<String>, compilerPluginOptions: List<String>): List<PluginOption>? {
if ("sam-with-receiver" !in enabledCompilerPlugins) {
return null
}
val annotations = mutableListOf<String>()
for ((presetName, presetAnnotations) in SamWithReceiverCommandLineProcessor.SUPPORTED_PRESETS) {
if (presetName in enabledCompilerPlugins) {
annotations.addAll(presetAnnotations)
}
}
annotations.addAll(compilerPluginOptions.mapNotNull { text ->
if (!text.startsWith(ANNOTATION_PARAMETER_PREFIX)) return@mapNotNull null
text.substring(ANNOTATION_PARAMETER_PREFIX.length)
})
return annotations.map { PluginOption(SamWithReceiverCommandLineProcessor.ANNOTATION_OPTION.name, it) }
}
}
*/
-3
View File
@@ -1,3 +0,0 @@
/*
This build should not be invoked in AS
*/
@@ -1,32 +0,0 @@
/*
plugins {
kotlin("jvm")
}
dependencies {
compileOnly(project(":idea"))
compileOnly(project(":idea:idea-maven"))
compileOnly(project(":idea:idea-gradle"))
compileOnly(project(":idea:idea-jvm"))
compile(intellijDep())
runtimeOnly(files(toolsJar()))
}
val intellijUltimateEnabled : Boolean by rootProject.extra
val ideaUltimatePluginDir: File by rootProject.extra
val ideaUltimateSandboxDir: File by rootProject.extra
if (intellijUltimateEnabled) {
runIdeTask("runUltimate", ideaUltimatePluginDir, ideaUltimateSandboxDir) {
dependsOn(":dist", ":ideaPlugin", ":ultimate:ideaUltimatePlugin")
}
}
*/