| /* |
| * Copyright 2020 Google LLC |
| * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.google.devtools.ksp.symbol.impl.java |
| |
| import com.google.devtools.ksp.ExceptionMessage |
| import com.google.devtools.ksp.processing.impl.ResolverImpl |
| import com.google.devtools.ksp.symbol.KSAnnotation |
| import com.google.devtools.ksp.symbol.KSNode |
| import com.google.devtools.ksp.symbol.KSReferenceElement |
| import com.google.devtools.ksp.symbol.KSType |
| import com.google.devtools.ksp.symbol.KSTypeReference |
| import com.google.devtools.ksp.symbol.KSVisitor |
| import com.google.devtools.ksp.symbol.Location |
| import com.google.devtools.ksp.symbol.Modifier |
| import com.google.devtools.ksp.symbol.NonExistLocation |
| import com.google.devtools.ksp.symbol.Origin |
| import com.google.devtools.ksp.symbol.impl.KSObjectCache |
| import com.google.devtools.ksp.symbol.impl.binary.KSClassDeclarationDescriptorImpl |
| import com.google.devtools.ksp.symbol.impl.binary.KSClassifierReferenceDescriptorImpl |
| import com.google.devtools.ksp.symbol.impl.kotlin.KSErrorType |
| import com.google.devtools.ksp.symbol.impl.kotlin.KSTypeImpl |
| import com.google.devtools.ksp.symbol.impl.memoized |
| import com.google.devtools.ksp.symbol.impl.toLocation |
| import com.intellij.psi.PsiArrayType |
| import com.intellij.psi.PsiClassType |
| import com.intellij.psi.PsiPrimitiveType |
| import com.intellij.psi.PsiType |
| import com.intellij.psi.PsiWildcardType |
| import com.intellij.psi.impl.source.PsiClassReferenceType |
| import org.jetbrains.kotlin.descriptors.NotFoundClasses |
| import org.jetbrains.kotlin.types.KotlinType |
| import org.jetbrains.kotlin.types.Variance |
| import org.jetbrains.kotlin.types.typeUtil.makeNullable |
| |
| class KSTypeReferenceJavaImpl private constructor(val psi: PsiType, override val parent: KSNode?) : KSTypeReference { |
| companion object : KSObjectCache<Pair<PsiType, KSNode?>, KSTypeReferenceJavaImpl>() { |
| fun getCached(psi: PsiType, parent: KSNode?) = cache |
| .getOrPut(Pair(psi, parent)) { KSTypeReferenceJavaImpl(psi, parent) } |
| } |
| |
| override val origin = Origin.JAVA |
| |
| override val location: Location by lazy { |
| (psi as? PsiClassReferenceType)?.reference?.toLocation() ?: NonExistLocation |
| } |
| |
| override val annotations: Sequence<KSAnnotation> by lazy { |
| psi.annotations.asSequence().map { KSAnnotationJavaImpl.getCached(it) }.memoized() |
| } |
| |
| override val modifiers: Set<Modifier> = emptySet() |
| |
| override val element: KSReferenceElement by lazy { |
| fun PsiPrimitiveType.toKotlinType(): KotlinType { |
| return when (this.name) { |
| "int" -> ResolverImpl.instance.module.builtIns.intType |
| "short" -> ResolverImpl.instance.module.builtIns.shortType |
| "byte" -> ResolverImpl.instance.module.builtIns.byteType |
| "long" -> ResolverImpl.instance.module.builtIns.longType |
| "float" -> ResolverImpl.instance.module.builtIns.floatType |
| "double" -> ResolverImpl.instance.module.builtIns.doubleType |
| "char" -> ResolverImpl.instance.module.builtIns.charType |
| "boolean" -> ResolverImpl.instance.module.builtIns.booleanType |
| "void" -> ResolverImpl.instance.module.builtIns.unitType |
| else -> throw IllegalStateException("Unexpected primitive type ${this.name}, $ExceptionMessage") |
| } |
| } |
| |
| val type = if (psi is PsiWildcardType) { |
| psi.bound |
| } else { |
| psi |
| } |
| when (type) { |
| is PsiClassType -> KSClassifierReferenceJavaImpl.getCached(type, this) |
| is PsiWildcardType -> KSClassifierReferenceJavaImpl.getCached(type.extendsBound as PsiClassType, this) |
| is PsiPrimitiveType -> KSClassifierReferenceDescriptorImpl.getCached(type.toKotlinType(), origin, this) |
| is PsiArrayType -> { |
| val componentType = ResolverImpl.instance.resolveJavaType(type.componentType, this) |
| if (type.componentType !is PsiPrimitiveType) { |
| KSClassifierReferenceDescriptorImpl.getCached( |
| ResolverImpl.instance.module.builtIns.getArrayType(Variance.INVARIANT, componentType), |
| origin, |
| this |
| ) |
| } else { |
| KSClassifierReferenceDescriptorImpl.getCached( |
| ResolverImpl.instance.module.builtIns |
| .getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(componentType)!!, |
| origin, this |
| ) |
| } |
| } |
| null -> |
| KSClassifierReferenceDescriptorImpl.getCached( |
| (ResolverImpl.instance.builtIns.anyType as KSTypeImpl).kotlinType.makeNullable(), origin, this |
| ) |
| else -> throw IllegalStateException("Unexpected psi type for ${type.javaClass}, $ExceptionMessage") |
| } |
| } |
| |
| override fun resolve(): KSType { |
| val resolvedType = ResolverImpl.instance.resolveUserType(this) |
| return if ((resolvedType.declaration as? KSClassDeclarationDescriptorImpl) |
| ?.descriptor is NotFoundClasses.MockClassDescriptor |
| ) { |
| KSErrorType |
| } else resolvedType |
| } |
| |
| override fun <D, R> accept(visitor: KSVisitor<D, R>, data: D): R { |
| return visitor.visitTypeReference(this, data) |
| } |
| |
| override fun toString(): String { |
| return element.toString() |
| } |
| } |