Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.java.lazy.descriptors
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.components.ExternalSignatureResolver
import org.jetbrains.kotlin.load.java.components.TypeUsage
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.child
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeAttributes
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
import org.jetbrains.kotlin.load.java.structure.JavaField
import org.jetbrains.kotlin.load.java.structure.JavaMethod
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
import org.jetbrains.kotlin.load.java.typeEnhacement.enhanceSignatures
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.PLATFORM_TYPES
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude.NonExtensions
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.resolve.scopes.JetScopeImpl
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.toReadOnlyList
import java.util.*
public abstract class LazyJavaScope(
protected val c: LazyJavaResolverContext,
private val containingDeclaration: DeclarationDescriptor
) : JetScopeImpl() {
// this lazy value is not used at all in LazyPackageFragmentScopeForJavaPackage because we do not use caching there
// but is placed in the base class to not duplicate code
private val allDescriptors = c.storageManager.createRecursionTolerantLazyValue>(
{ computeDescriptors(DescriptorKindFilter.ALL, JetScope.ALL_NAME_FILTER, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS) },
// This is to avoid the following recursive case:
// when computing getAllPackageNames() we ask the JavaPsiFacade for all subpackages of foo
// it, in turn, asks JavaElementFinder for subpackages of Kotlin package foo, which calls getAllPackageNames() recursively
// when on recursive call we return an empty collection, recursion collapses gracefully
listOf()
)
override fun getContainingDeclaration() = containingDeclaration
protected val memberIndex: NotNullLazyValue = c.storageManager.createLazyValue { computeMemberIndex() }
protected abstract fun computeMemberIndex(): MemberIndex
// Fake overrides, SAM constructors/adapters, values()/valueOf(), etc.
protected abstract fun computeNonDeclaredFunctions(result: MutableCollection, name: Name)
protected abstract fun getDispatchReceiverParameter(): ReceiverParameterDescriptor?
private val functions = c.storageManager.createMemoizedFunction> {
name ->
val result = LinkedHashSet()
for (method in memberIndex().findMethodsByName(name)) {
val descriptor = resolveMethodToFunctionDescriptor(method, true)
result.add(descriptor)
if (method.isStatic) {
result.addIfNotNull(c.components.samConversionResolver.resolveSamAdapter(descriptor))
}
}
computeNonDeclaredFunctions(result, name)
enhanceSignatures(result).toReadOnlyList()
}
protected data class MethodSignatureData(
val effectiveSignature: ExternalSignatureResolver.AlternativeMethodSignature,
val errors: List
)
protected abstract fun resolveMethodSignature(
method: JavaMethod,
methodTypeParameters: List,
returnType: JetType,
valueParameters: ResolvedValueParameters): MethodSignatureData
fun resolveMethodToFunctionDescriptor(method: JavaMethod, record: Boolean = true): JavaMethodDescriptor {
val annotations = c.resolveAnnotations(method)
val functionDescriptorImpl = JavaMethodDescriptor.createJavaMethod(
containingDeclaration, annotations, method.getName(), c.components.sourceElementFactory.source(method)
)
val c = c.child(functionDescriptorImpl, method)
val methodTypeParameters = method.getTypeParameters().map { p -> c.typeParameterResolver.resolveTypeParameter(p)!! }
val valueParameters = resolveValueParameters(c, functionDescriptorImpl, method.getValueParameters())
val returnType = computeMethodReturnType(method, annotations, c)
val (effectiveSignature, signatureErrors) = resolveMethodSignature(method, methodTypeParameters, returnType, valueParameters)
functionDescriptorImpl.initialize(
effectiveSignature.getReceiverType(),
getDispatchReceiverParameter(),
effectiveSignature.getTypeParameters(),
effectiveSignature.getValueParameters(),
effectiveSignature.getReturnType(),
Modality.convertFromFlags(method.isAbstract(), !method.isFinal()),
method.getVisibility(),
false
)
functionDescriptorImpl.setParameterNamesStatus(effectiveSignature.hasStableParameterNames(), valueParameters.hasSynthesizedNames)
if (record) {
c.components.javaResolverCache.recordMethod(method, functionDescriptorImpl)
}
if (signatureErrors.isNotEmpty()) {
c.components.externalSignatureResolver.reportSignatureErrors(functionDescriptorImpl, signatureErrors)
}
return functionDescriptorImpl
}
protected fun computeMethodReturnType(method: JavaMethod, annotations: Annotations, c: LazyJavaResolverContext): JetType {
val annotationMethod = method.getContainingClass().isAnnotationType()
val returnTypeAttrs = LazyJavaTypeAttributes(
TypeUsage.MEMBER_SIGNATURE_COVARIANT, annotations,
allowFlexible = !annotationMethod,
isForAnnotationParameter = annotationMethod
)
return c.typeResolver.transformJavaType(method.getReturnType(), returnTypeAttrs).let {
// Annotation arguments are never null in Java
if (annotationMethod) TypeUtils.makeNotNullable(it) else it
}
}
protected class ResolvedValueParameters(val descriptors: List, val hasSynthesizedNames: Boolean)
protected fun resolveValueParameters(
c: LazyJavaResolverContext,
function: FunctionDescriptor,
jValueParameters: List
): ResolvedValueParameters {
var synthesizedNames = false
val descriptors = jValueParameters.withIndex().map { pair ->
val (index, javaParameter) = pair
val annotations = c.resolveAnnotations(javaParameter)
val typeUsage = LazyJavaTypeAttributes(TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT, annotations)
val (outType, varargElementType) =
if (javaParameter.isVararg()) {
val paramType = javaParameter.getType() as? JavaArrayType
?: throw AssertionError("Vararg parameter should be an array: $javaParameter")
val outType = c.typeResolver.transformArrayType(paramType, typeUsage, true)
outType to c.module.builtIns.getArrayElementType(outType)
}
else {
c.typeResolver.transformJavaType(javaParameter.getType(), typeUsage) to null
}
val name = if (function.getName().asString() == "equals" &&
jValueParameters.size() == 1 &&
c.module.builtIns.getNullableAnyType() == outType) {
// This is a hack to prevent numerous warnings on Kotlin classes that inherit Java classes: if you override "equals" in such
// class without this hack, you'll be warned that in the superclass the name is "p0" (regardless of the fact that it's
// "other" in Any)
// TODO: fix Java parameter name loading logic somehow (don't always load "p0", "p1", etc.)
Name.identifier("other")
}
else {
// TODO: parameter names may be drawn from attached sources, which is slow; it's better to make them lazy
val javaName = javaParameter.getName()
if (javaName == null) synthesizedNames = true
javaName ?: Name.identifier("p$index")
}
ValueParameterDescriptorImpl(
function,
null,
index,
annotations,
name,
outType,
false,
varargElementType,
c.components.sourceElementFactory.source(javaParameter)
)
}.toList()
return ResolvedValueParameters(descriptors, synthesizedNames)
}
override fun getFunctions(name: Name, location: LookupLocation) = functions(name)
protected open fun getFunctionNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection
= memberIndex().getMethodNames(nameFilter)
protected abstract fun computeNonDeclaredProperties(name: Name, result: MutableCollection)
protected abstract fun getPropertyNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection
private val properties = c.storageManager.createMemoizedFunction {
name: Name ->
val properties = ArrayList()
val field = memberIndex().findFieldByName(name)
if (field != null && !field.isEnumEntry()) {
properties.add(resolveProperty(field))
}
computeNonDeclaredProperties(name, properties)
if (DescriptorUtils.isAnnotationClass(containingDeclaration))
properties.toReadOnlyList()
else
enhanceSignatures(properties).toReadOnlyList()
}
private fun resolveProperty(field: JavaField): PropertyDescriptor {
val isVar = !field.isFinal()
val propertyDescriptor = createPropertyDescriptor(field)
propertyDescriptor.initialize(null, null)
val propertyType = getPropertyType(field, propertyDescriptor.getAnnotations())
val effectiveSignature = c.components.externalSignatureResolver.resolveAlternativeFieldSignature(field, propertyType, isVar)
val signatureErrors = effectiveSignature.getErrors()
if (!signatureErrors.isEmpty()) {
c.components.externalSignatureResolver.reportSignatureErrors(propertyDescriptor, signatureErrors)
}
propertyDescriptor.setType(effectiveSignature.getReturnType(), listOf(), getDispatchReceiverParameter(), null : JetType?)
if (DescriptorUtils.shouldRecordInitializerForProperty(propertyDescriptor, propertyDescriptor.getType())) {
propertyDescriptor.setCompileTimeInitializer(
c.storageManager.createNullableLazyValue {
c.components.javaPropertyInitializerEvaluator.getInitializerConstant(field, propertyDescriptor)
})
}
c.components.javaResolverCache.recordField(field, propertyDescriptor);
return propertyDescriptor
}
private fun createPropertyDescriptor(field: JavaField): PropertyDescriptorImpl {
val isVar = !field.isFinal()
val visibility = field.getVisibility()
val annotations = c.resolveAnnotations(field)
val propertyName = field.getName()
return JavaPropertyDescriptor(containingDeclaration, annotations, visibility, isVar, propertyName,
c.components.sourceElementFactory.source(field), /* original = */ null, /*isConst= */ field.isFinalStatic)
}
private val JavaField.isFinalStatic: Boolean
get() = isFinal && isStatic
private fun getPropertyType(field: JavaField, annotations: Annotations): JetType {
// Fields do not have their own generic parameters
val finalStatic = field.isFinalStatic
// simple static constants should not have flexible types:
val allowFlexible = PLATFORM_TYPES && !(finalStatic && c.components.javaPropertyInitializerEvaluator.isNotNullCompileTimeConstant(field))
val propertyType = c.typeResolver.transformJavaType(
field.getType(),
LazyJavaTypeAttributes(TypeUsage.MEMBER_SIGNATURE_INVARIANT, annotations, allowFlexible)
)
if ((!allowFlexible || !PLATFORM_TYPES) && finalStatic) {
return TypeUtils.makeNotNullable(propertyType)
}
return propertyType
}
override fun getProperties(name: Name, location: LookupLocation): Collection = properties(name)
override fun getOwnDeclaredDescriptors() = getDescriptors()
override fun getDescriptors(kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean) = allDescriptors()
protected fun computeDescriptors(
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean,
location: LookupLocation
): List {
val result = LinkedHashSet()
if (kindFilter.acceptsKinds(DescriptorKindFilter.CLASSIFIERS_MASK)) {
for (name in getClassNames(kindFilter, nameFilter)) {
if (nameFilter(name)) {
// Null signifies that a class found in Java is not present in Kotlin (e.g. package class)
result.addIfNotNull(getClassifier(name, location))
}
}
}
if (kindFilter.acceptsKinds(DescriptorKindFilter.FUNCTIONS_MASK) && !kindFilter.excludes.contains(NonExtensions)) {
for (name in getFunctionNames(kindFilter, nameFilter)) {
if (nameFilter(name)) {
result.addAll(getFunctions(name, location))
}
}
}
if (kindFilter.acceptsKinds(DescriptorKindFilter.VARIABLES_MASK) && !kindFilter.excludes.contains(NonExtensions)) {
for (name in getPropertyNames(kindFilter, nameFilter)) {
if (nameFilter(name)) {
result.addAll(getProperties(name, location))
}
}
}
addExtraDescriptors(result, kindFilter, nameFilter)
return result.toReadOnlyList()
}
protected open fun addExtraDescriptors(result: MutableSet,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean) {
// Do nothing
}
protected abstract fun getClassNames(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection
override fun toString() = "Lazy scope for ${getContainingDeclaration()}"
override fun printScopeStructure(p: Printer) {
p.println(javaClass.getSimpleName(), " {")
p.pushIndent()
p.println("containingDeclaration: ${getContainingDeclaration()}")
p.popIndent()
p.println("}")
}
}