as31: Misc: Fix compilation
This commit is contained in:
committed by
Nikolay Krasko
parent
8568bde4df
commit
a9cdccc6de
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 virtualFileKotlinClass: VirtualFileKotlinClass? = null
|
||||
|
||||
fun cache(file: VirtualFile, aClass: VirtualFileKotlinClass?): VirtualFileKotlinClass? {
|
||||
virtualFile = file
|
||||
virtualFileKotlinClass = aClass
|
||||
modificationStamp = file.modificationStamp
|
||||
|
||||
return aClass
|
||||
}
|
||||
}
|
||||
|
||||
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 getKotlinBinaryClass(file: VirtualFile, fileContent: ByteArray? = null): KotlinJvmBinaryClass? {
|
||||
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.virtualFileKotlinClass
|
||||
}
|
||||
|
||||
val aClass = ApplicationManager.getApplication().runReadAction(Computable {
|
||||
@Suppress("DEPRECATION")
|
||||
VirtualFileKotlinClass.create(file, fileContent)
|
||||
})
|
||||
|
||||
return requestCache.cache(file, aClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.resolve.jvm.modules
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
//import com.intellij.psi.PsiJavaModule
|
||||
import com.intellij.psi.PsiModifier
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.utils.compact
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
||||
//import org.jetbrains.org.objectweb.asm.ModuleVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
//import org.jetbrains.org.objectweb.asm.Opcodes.ACC_TRANSITIVE
|
||||
import java.io.IOException
|
||||
|
||||
class JavaModuleInfo(
|
||||
val moduleName: String,
|
||||
val requires: List<Requires>,
|
||||
val exports: List<Exports>
|
||||
) {
|
||||
data class Requires(val moduleName: String, val isTransitive: Boolean)
|
||||
|
||||
data class Exports(val packageFqName: FqName, val toModules: List<String>)
|
||||
|
||||
override fun toString(): String =
|
||||
"Module $moduleName (${requires.size} requires, ${exports.size} exports)"
|
||||
|
||||
companion object {
|
||||
/*fun create(psiJavaModule: PsiJavaModule): JavaModuleInfo {
|
||||
return JavaModuleInfo(
|
||||
psiJavaModule.name,
|
||||
psiJavaModule.requires.mapNotNull { statement ->
|
||||
statement.moduleName?.let { moduleName ->
|
||||
JavaModuleInfo.Requires(moduleName, statement.hasModifierProperty(PsiModifier.TRANSITIVE))
|
||||
}
|
||||
},
|
||||
psiJavaModule.exports.mapNotNull { statement ->
|
||||
statement.packageName?.let { packageName ->
|
||||
JavaModuleInfo.Exports(FqName(packageName), statement.moduleNames)
|
||||
}
|
||||
}
|
||||
)
|
||||
}*/
|
||||
|
||||
/*fun read(file: VirtualFile): JavaModuleInfo? {
|
||||
val contents = try { file.contentsToByteArray() } catch (e: IOException) { return null }
|
||||
|
||||
var moduleName: String? = null
|
||||
val requires = arrayListOf<Requires>()
|
||||
val exports = arrayListOf<Exports>()
|
||||
|
||||
ClassReader(contents).accept(object : ClassVisitor(Opcodes.ASM6) {
|
||||
override fun visitModule(name: String, access: Int, version: String?): ModuleVisitor {
|
||||
moduleName = name
|
||||
|
||||
return object : ModuleVisitor(Opcodes.ASM6) {
|
||||
override fun visitRequire(module: String, access: Int, version: String?) {
|
||||
requires.add(Requires(module, (access and ACC_TRANSITIVE) != 0))
|
||||
}
|
||||
|
||||
override fun visitExport(packageFqName: String, access: Int, modules: Array<String>?) {
|
||||
// For some reason, '/' is the delimiter in packageFqName here
|
||||
exports.add(Exports(FqName(packageFqName.replace('/', '.')), modules?.toList().orEmpty()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ClassReader.SKIP_DEBUG or ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES)
|
||||
|
||||
return if (moduleName != null)
|
||||
JavaModuleInfo(moduleName!!, requires.compact(), exports.compact())
|
||||
else null
|
||||
}*/
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user