Remove obsolete kapt2 implementation
This commit is contained in:
Generated
-2
@@ -14,7 +14,6 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/android-tests/android-tests.iml" filepath="$PROJECT_DIR$/compiler/android-tests/android-tests.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/annotation-based-compiler-plugins-ide-support/annotation-based-compiler-plugins-ide-support.iml" filepath="$PROJECT_DIR$/plugins/annotation-based-compiler-plugins-ide-support/annotation-based-compiler-plugins-ide-support.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/annotation-collector/annotation-collector.iml" filepath="$PROJECT_DIR$/plugins/annotation-collector/annotation-collector.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/annotation-processing/annotation-processing.iml" filepath="$PROJECT_DIR$/plugins/annotation-processing/annotation-processing.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/ant/ant.iml" filepath="$PROJECT_DIR$/ant/ant.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/backend/backend.iml" filepath="$PROJECT_DIR$/compiler/backend/backend.iml" group="compiler/java" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/backend-common/backend-common.iml" filepath="$PROJECT_DIR$/compiler/backend-common/backend-common.iml" group="compiler" />
|
||||
@@ -64,7 +63,6 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/ir/ir.psi2ir/ir.psi2ir.iml" filepath="$PROJECT_DIR$/compiler/ir/ir.psi2ir/ir.psi2ir.iml" group="compiler/ir" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/ir/ir.tree/ir.tree.iml" filepath="$PROJECT_DIR$/compiler/ir/ir.tree/ir.tree.iml" group="compiler/ir" />
|
||||
<module fileurl="file://$PROJECT_DIR$/j2k/j2k.iml" filepath="$PROJECT_DIR$/j2k/j2k.iml" group="j2k" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/java-model-wrappers/java-model-wrappers.iml" filepath="$PROJECT_DIR$/plugins/java-model-wrappers/java-model-wrappers.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/javac-wrapper/javac-wrapper.iml" filepath="$PROJECT_DIR$/compiler/javac-wrapper/javac-wrapper.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps-plugin/jps-plugin.iml" filepath="$PROJECT_DIR$/jps-plugin/jps-plugin.iml" group="ide/jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps-plugin/jps-tests/jps-tests.iml" filepath="$PROJECT_DIR$/jps-plugin/jps-tests/jps-tests.iml" group="ide/jps" />
|
||||
|
||||
@@ -30,9 +30,6 @@ import org.jetbrains.kotlin.android.intention.AbstractAndroidResourceIntentionTe
|
||||
import org.jetbrains.kotlin.android.lint.AbstractKotlinLintTest
|
||||
import org.jetbrains.kotlin.android.quickfix.AbstractAndroidLintQuickfixTest
|
||||
import org.jetbrains.kotlin.android.quickfix.AbstractAndroidQuickFixMultiFileTest
|
||||
import org.jetbrains.kotlin.annotation.AbstractAnnotationProcessorBoxTest
|
||||
import org.jetbrains.kotlin.annotation.processing.test.sourceRetention.AbstractBytecodeListingTestForSourceRetention
|
||||
import org.jetbrains.kotlin.annotation.processing.test.wrappers.AbstractAnnotationProcessingTest
|
||||
import org.jetbrains.kotlin.asJava.AbstractCompilerLightClassTest
|
||||
import org.jetbrains.kotlin.cfg.AbstractControlFlowTest
|
||||
import org.jetbrains.kotlin.cfg.AbstractDataFlowTest
|
||||
@@ -160,6 +157,7 @@ import org.jetbrains.kotlin.kdoc.AbstractKDocLexerTest
|
||||
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidBoxTest
|
||||
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidBytecodeShapeTest
|
||||
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidSyntheticPropertyDescriptorTest
|
||||
import org.jetbrains.kotlin.annotation.AbstractAnnotationProcessorBoxTest
|
||||
import org.jetbrains.kotlin.modules.xml.AbstractModuleXmlParserTest
|
||||
import org.jetbrains.kotlin.multiplatform.AbstractMultiPlatformIntegrationTest
|
||||
import org.jetbrains.kotlin.noarg.AbstractBlackBoxCodegenTestForNoArg
|
||||
@@ -1258,16 +1256,6 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("plugins/plugins-tests/tests", "plugins/annotation-processing/testData") {
|
||||
testClass<AbstractAnnotationProcessingTest> {
|
||||
model("wrappers", recursive = true, extension = "kt")
|
||||
}
|
||||
|
||||
testClass<AbstractBytecodeListingTestForSourceRetention> {
|
||||
model("sourceRetention", extension = "kt")
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("plugins/kapt3/test", "plugins/kapt3/testData") {
|
||||
testClass<AbstractClassFileToSourceStubConverterTest> {
|
||||
model("converter")
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="java-model-wrappers" />
|
||||
<orderEntry type="module" module-name="frontend" />
|
||||
<orderEntry type="module" module-name="plugin-api" />
|
||||
<orderEntry type="module" module-name="frontend.java" />
|
||||
<orderEntry type="module" module-name="light-classes" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="module" module-name="cli" />
|
||||
<orderEntry type="module" module-name="backend" />
|
||||
</component>
|
||||
</module>
|
||||
-1
@@ -1 +0,0 @@
|
||||
org.jetbrains.kotlin.annotation.processing.AnnotationProcessingCommandLineProcessor
|
||||
-1
@@ -1 +0,0 @@
|
||||
org.jetbrains.kotlin.annotation.processing.AnnotationProcessingComponentRegistrar
|
||||
-361
@@ -1,361 +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.annotation
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiJavaFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.impl.PsiModificationTrackerImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.annotation.processing.RoundAnnotations
|
||||
import org.jetbrains.kotlin.annotation.processing.diagnostic.ErrorsAnnotationProcessing
|
||||
import org.jetbrains.kotlin.annotation.processing.impl.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.*
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
|
||||
import org.jetbrains.kotlin.java.model.elements.JeTypeElement
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
import java.net.URLClassLoader
|
||||
import java.util.*
|
||||
import javax.annotation.processing.Processor
|
||||
import javax.tools.Diagnostic
|
||||
|
||||
class ClasspathBasedAnnotationProcessingExtension(
|
||||
val annotationProcessingClasspath: List<File>,
|
||||
override val options: Map<String, String>,
|
||||
generatedSourcesOutputDir: File,
|
||||
classesOutputDir: File,
|
||||
javaSourceRoots: List<File>,
|
||||
verboseOutput: Boolean,
|
||||
incrementalDataFile: File?,
|
||||
messageCollector: MessageCollector?
|
||||
) : AbstractAnnotationProcessingExtension(generatedSourcesOutputDir,
|
||||
classesOutputDir, javaSourceRoots, verboseOutput,
|
||||
incrementalDataFile, messageCollector) {
|
||||
override fun loadAnnotationProcessors(): List<Processor> {
|
||||
val classLoader = URLClassLoader(annotationProcessingClasspath.map { it.toURI().toURL() }.toTypedArray())
|
||||
return ServiceLoader.load(Processor::class.java, classLoader).toList()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractAnnotationProcessingExtension(
|
||||
val generatedSourcesOutputDir: File,
|
||||
val classesOutputDir: File,
|
||||
val javaSourceRoots: List<File>,
|
||||
val verboseOutput: Boolean,
|
||||
val incrementalDataFile: File? = null,
|
||||
messageCollector: MessageCollector? = null
|
||||
) : AnalysisHandlerExtension {
|
||||
private companion object {
|
||||
val LINE_SEPARATOR = System.getProperty("line.separator") ?: "\n"
|
||||
}
|
||||
|
||||
private var annotationProcessingComplete = false
|
||||
private val messager = run {
|
||||
val collector = messageCollector ?: PrintingMessageCollector(System.err, MessageRenderer.WITHOUT_PATHS, verboseOutput)
|
||||
KotlinMessager(collector)
|
||||
}
|
||||
|
||||
private inline fun log(message: () -> String) {
|
||||
if (verboseOutput) {
|
||||
messager.printMessage(Diagnostic.Kind.OTHER, "Kapt: " + message())
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.count(noun: String) = if (this == 1) "$this $noun" else "$this ${noun}s"
|
||||
|
||||
private inline fun <T, R> T.runIf(condition: Boolean, block: T.() -> R) {
|
||||
if (condition) block()
|
||||
}
|
||||
|
||||
override fun analysisCompleted(
|
||||
project: Project,
|
||||
module: ModuleDescriptor,
|
||||
bindingTrace: BindingTrace,
|
||||
files: Collection<KtFile>
|
||||
): AnalysisResult? {
|
||||
if (annotationProcessingComplete) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Clean the generated source directory even if we don't run any annotation processors
|
||||
generatedSourcesOutputDir.deleteRecursively()
|
||||
generatedSourcesOutputDir.mkdirs()
|
||||
|
||||
val processors = loadAnnotationProcessors()
|
||||
if (processors.isEmpty()) {
|
||||
log { "No annotation processors detected, exiting" }
|
||||
return null
|
||||
}
|
||||
|
||||
val appendJavaSourceRootsHandler = project.getUserData(APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY)
|
||||
if (appendJavaSourceRootsHandler == null) {
|
||||
log { "Java source root handler is not set, exiting" }
|
||||
return null
|
||||
}
|
||||
|
||||
val startTime = System.currentTimeMillis()
|
||||
|
||||
val psiManager = PsiManager.getInstance(project)
|
||||
val javaPsiFacade = JavaPsiFacade.getInstance(project)
|
||||
val projectScope = GlobalSearchScope.projectScope(project)
|
||||
|
||||
val options = this.options
|
||||
log { "Options: $options" }
|
||||
|
||||
val filer = KotlinFiler(generatedSourcesOutputDir, classesOutputDir)
|
||||
val types = KotlinTypes(javaPsiFacade, PsiManager.getInstance(project), projectScope)
|
||||
val elements = KotlinElements(javaPsiFacade, projectScope)
|
||||
|
||||
val processingEnvironment = KotlinProcessingEnvironment(
|
||||
elements, types, messager, options, filer, processors,
|
||||
project, psiManager, javaPsiFacade, projectScope, bindingTrace.bindingContext, appendJavaSourceRootsHandler)
|
||||
|
||||
var processingResult: ProcessingResult
|
||||
try {
|
||||
processingResult = processingEnvironment.doAnnotationProcessing(files)
|
||||
processingEnvironment.dispose()
|
||||
}
|
||||
catch (thr: Throwable) {
|
||||
messager.printMessage(
|
||||
Diagnostic.Kind.ERROR,
|
||||
"An exception occurred during annotation processing. Stacktrace: \n" + thr.getStackTraceAsString())
|
||||
|
||||
processingResult = ProcessingResult(errorCount = 1, warningCount = 0, wasAnythingGenerated = false)
|
||||
}
|
||||
|
||||
annotationProcessingComplete = true
|
||||
log {
|
||||
"Annotation processing complete in ${System.currentTimeMillis() - startTime} ms, " +
|
||||
processingResult.errorCount.count("error") + ", " +
|
||||
processingResult.warningCount.count("warning")
|
||||
}
|
||||
|
||||
if (processingResult.errorCount != 0) {
|
||||
val reportFile = files.firstOrNull()
|
||||
if (reportFile != null) {
|
||||
bindingTrace.report(ErrorsAnnotationProcessing.ANNOTATION_PROCESSING_ERROR.on(reportFile))
|
||||
}
|
||||
|
||||
// Do not restart Kotlin file analysis
|
||||
return null
|
||||
}
|
||||
|
||||
if (!processingResult.wasAnythingGenerated) {
|
||||
// Nothing was generated, do not need to restart analysis
|
||||
return null
|
||||
}
|
||||
|
||||
return AnalysisResult.RetryWithAdditionalJavaRoots(
|
||||
bindingTrace.bindingContext,
|
||||
module,
|
||||
listOf(generatedSourcesOutputDir),
|
||||
addToEnvironment = false)
|
||||
}
|
||||
|
||||
private fun Throwable.getStackTraceAsString(): String {
|
||||
val out = StringWriter(1024)
|
||||
val printWriter = PrintWriter(out)
|
||||
try {
|
||||
printStackTrace(printWriter)
|
||||
return out.toString().replace("\r", "")
|
||||
}
|
||||
finally {
|
||||
printWriter.close()
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinProcessingEnvironment.createTypeMapper(): KotlinTypeMapper {
|
||||
return KotlinTypeMapper(bindingContext(), ClassBuilderMode.full(false), NoResolveFileClassesProvider,
|
||||
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false, false)
|
||||
}
|
||||
|
||||
private fun KotlinProcessingEnvironment.doAnnotationProcessing(files: Collection<KtFile>): ProcessingResult {
|
||||
run initializeProcessors@ {
|
||||
processors().forEach { it.init(this) }
|
||||
log { "Initialized processors: " + processors().joinToString { it::class.java.name } }
|
||||
}
|
||||
|
||||
val firstRoundAnnotations = RoundAnnotations(
|
||||
bindingContext(),
|
||||
createTypeMapper())
|
||||
|
||||
run analyzeFilesForFirstRound@ {
|
||||
log { "Analysing Kotlin files: " + files.map { it.virtualFile.path } }
|
||||
firstRoundAnnotations.analyzeFiles(files)
|
||||
|
||||
log { "Analysing Java source roots: $javaSourceRoots" }
|
||||
for (javaSourceRoot in javaSourceRoots) {
|
||||
javaSourceRoot.walk().filter { it.isFile && it.extension == "java" }.forEach {
|
||||
val vFile = StandardFileSystems.local().findFileByPath(it.absolutePath)
|
||||
if (vFile != null) {
|
||||
val javaFile = psiManager().findFile(vFile) as? PsiJavaFile
|
||||
if (javaFile != null) {
|
||||
firstRoundAnnotations.analyzeFile(javaFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runIf(incrementalDataFile != null) processIncrementalData@ {
|
||||
val incrementalDataFile = incrementalDataFile!!
|
||||
|
||||
|
||||
runIf(incrementalDataFile.exists()) analyzeFilesFromPreviousIncrementalData@ {
|
||||
val incrementalData = try {
|
||||
incrementalDataFile.readText()
|
||||
} catch (e: IOException) {
|
||||
log { "An exception occurred while processing incremental data file: $incrementalDataFile" }
|
||||
null
|
||||
}
|
||||
|
||||
if (incrementalData != null) {
|
||||
val analyzedClasses = mutableListOf<String>()
|
||||
|
||||
for (line in incrementalData.lines()) {
|
||||
if (line.length < 3 || !line.startsWith("i ")) continue
|
||||
val fqName = line.drop(2)
|
||||
val psiClass = javaPsiFacade().findClass(fqName, projectScope()) ?: continue
|
||||
if (firstRoundAnnotations.analyzeDeclaration(psiClass)) {
|
||||
analyzedClasses += fqName
|
||||
}
|
||||
}
|
||||
|
||||
log { "Analysing files from incremental data: $analyzedClasses" }
|
||||
}
|
||||
}
|
||||
|
||||
run saveNewIncrementalData@ {
|
||||
val analyzedClasses = firstRoundAnnotations.analyzedClasses
|
||||
log { "Saving incremental data: ${analyzedClasses.size} class names" }
|
||||
try {
|
||||
incrementalDataFile.parentFile.mkdirs()
|
||||
incrementalDataFile.writeText(analyzedClasses.joinToString(LINE_SEPARATOR) { "i $it" })
|
||||
}
|
||||
catch (e: IOException) {
|
||||
log { "Unable to write $incrementalDataFile" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val finalRoundNumber = run annotationProcessing@ {
|
||||
val firstRoundEnvironment = KotlinRoundEnvironment(firstRoundAnnotations, false, 1)
|
||||
process(firstRoundEnvironment) // Dispose for firstRoundEnvironment is called inside process
|
||||
} + 1
|
||||
|
||||
log { "Starting round $finalRoundNumber (final)" }
|
||||
val finalRoundEnvironment = KotlinRoundEnvironment(firstRoundAnnotations.copy(), true, finalRoundNumber)
|
||||
for (processor in processors()) {
|
||||
processor.process(emptySet(), finalRoundEnvironment)
|
||||
}
|
||||
finalRoundEnvironment.dispose()
|
||||
|
||||
return ProcessingResult(messager.errorCount, messager.warningCount, filer.wasAnythingGenerated)
|
||||
}
|
||||
|
||||
private tailrec fun KotlinProcessingEnvironment.process(roundEnvironment: KotlinRoundEnvironment): Int {
|
||||
val newFiles = doRound(roundEnvironment)
|
||||
val newJavaFiles = newFiles.filter { it.extension.toLowerCase() == "java" }
|
||||
if (newJavaFiles.isEmpty() || messager.errorCount != 0) {
|
||||
return roundEnvironment.roundNumber
|
||||
}
|
||||
|
||||
// Add new Java source roots after the first round
|
||||
if (roundEnvironment.roundNumber == 1) {
|
||||
appendJavaSourceRootsHandler()(listOf(generatedSourcesOutputDir))
|
||||
}
|
||||
|
||||
// Update the platform caches
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
(psiManager().modificationTracker as? PsiModificationTrackerImpl)?.incCounter()
|
||||
}
|
||||
|
||||
// Find generated files
|
||||
val localFileSystem = StandardFileSystems.local()
|
||||
val psiFiles = newJavaFiles
|
||||
.map { localFileSystem.findFileByPath(it.absolutePath)?.let { psiManager().findFile(it) } }
|
||||
.filterIsInstance<PsiJavaFile>()
|
||||
|
||||
if (psiFiles.isEmpty()) {
|
||||
log { "Something is strange, files were generated but not found by PsiManager" }
|
||||
return roundEnvironment.roundNumber
|
||||
}
|
||||
|
||||
// Start the next round
|
||||
val nextRoundAnnotations = roundEnvironment.roundAnnotations().copy().apply { analyzeFiles(psiFiles) }
|
||||
val nextRoundEnvironment = KotlinRoundEnvironment(nextRoundAnnotations, false, roundEnvironment.roundNumber + 1)
|
||||
roundEnvironment.dispose()
|
||||
return process(nextRoundEnvironment)
|
||||
}
|
||||
|
||||
private fun KotlinProcessingEnvironment.doRound(roundEnvironment: KotlinRoundEnvironment): List<File> {
|
||||
log { "Starting round ${roundEnvironment.roundNumber}" }
|
||||
|
||||
val newFiles = mutableListOf<File>()
|
||||
filer.onFileCreatedHandler = { newFiles += it }
|
||||
|
||||
for (processor in processors()) {
|
||||
val supportedAnnotationNames = processor.supportedAnnotationTypes
|
||||
val acceptsAnyAnnotation = supportedAnnotationNames.contains("*")
|
||||
|
||||
val applicableAnnotationNames = when (acceptsAnyAnnotation) {
|
||||
true -> roundEnvironment.roundAnnotations().annotationsMap.keys
|
||||
false -> processor.supportedAnnotationTypes.filter { it in roundEnvironment.roundAnnotations().annotationsMap }
|
||||
}
|
||||
|
||||
if (applicableAnnotationNames.isEmpty()) {
|
||||
log { "Skipping processor " + processor::class.java.name + ": no relevant annotations" }
|
||||
continue
|
||||
}
|
||||
|
||||
val applicableAnnotations = applicableAnnotationNames
|
||||
.map { javaPsiFacade().findClass(it, projectScope())?.let(::JeTypeElement) }
|
||||
.filterNotNullTo(hashSetOf())
|
||||
|
||||
log {
|
||||
val annotationNames = applicableAnnotations.joinToString { it.qualifiedName.toString() }
|
||||
"Processing with " + processor::class.java.name + " (annotations: " + annotationNames + ")"
|
||||
}
|
||||
|
||||
processor.process(applicableAnnotations, roundEnvironment)
|
||||
}
|
||||
|
||||
log { "Round ${roundEnvironment.roundNumber} finished, ${newFiles.size.count("file")} generated (${newFiles.joinToString()})" }
|
||||
return newFiles
|
||||
}
|
||||
|
||||
protected abstract fun loadAnnotationProcessors(): List<Processor>
|
||||
protected abstract val options: Map<String, String>
|
||||
}
|
||||
|
||||
private class ProcessingResult(val errorCount: Int, val warningCount: Int, val wasAnythingGenerated: Boolean)
|
||||
-150
@@ -1,150 +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.annotation.processing
|
||||
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import org.jetbrains.kotlin.annotation.ClasspathBasedAnnotationProcessingExtension
|
||||
import org.jetbrains.kotlin.annotation.processing.diagnostic.DefaultErrorMessagesAnnotationProcessing
|
||||
import org.jetbrains.kotlin.cli.jvm.config.IS_KAPT2_ENABLED_KEY
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRoot
|
||||
import org.jetbrains.kotlin.compiler.plugin.CliOption
|
||||
import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
|
||||
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
|
||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||
import org.jetbrains.kotlin.java.model.internal.JeElementRegistry
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
||||
import java.io.File
|
||||
|
||||
import org.jetbrains.kotlin.annotation.processing.AnnotationProcessingConfigurationKeys.ANNOTATION_PROCESSOR_CLASSPATH
|
||||
import org.jetbrains.kotlin.annotation.processing.AnnotationProcessingConfigurationKeys.APT_OPTIONS
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
|
||||
object AnnotationProcessingConfigurationKeys {
|
||||
val GENERATED_OUTPUT_DIR: CompilerConfigurationKey<String> =
|
||||
CompilerConfigurationKey.create<String>("generated files output directory")
|
||||
|
||||
val CLASS_FILES_OUTPUT_DIR: CompilerConfigurationKey<String> =
|
||||
CompilerConfigurationKey.create<String>("class files output directory")
|
||||
|
||||
val ANNOTATION_PROCESSOR_CLASSPATH: CompilerConfigurationKey<List<String>> =
|
||||
CompilerConfigurationKey.create<List<String>>("annotation processor classpath")
|
||||
|
||||
val APT_OPTIONS: CompilerConfigurationKey<List<String>> =
|
||||
CompilerConfigurationKey.create<List<String>>("annotation processing options")
|
||||
|
||||
val INCREMENTAL_DATA_FILE: CompilerConfigurationKey<String> =
|
||||
CompilerConfigurationKey.create<String>("data file for incremental compilation support")
|
||||
|
||||
val VERBOSE_MODE: CompilerConfigurationKey<String> =
|
||||
CompilerConfigurationKey.create<String>("verbose mode")
|
||||
}
|
||||
|
||||
class AnnotationProcessingCommandLineProcessor : CommandLineProcessor {
|
||||
companion object {
|
||||
val ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID: String = "org.jetbrains.kotlin.kapt2"
|
||||
|
||||
val GENERATED_OUTPUT_DIR_OPTION: CliOption =
|
||||
CliOption("generated", "<path>", "Output path for the generated files", required = false)
|
||||
|
||||
val CLASS_FILES_OUTPUT_DIR_OPTION: CliOption =
|
||||
CliOption("classes", "<path>", "Output path for the class files", required = false)
|
||||
|
||||
val ANNOTATION_PROCESSOR_CLASSPATH_OPTION: CliOption =
|
||||
CliOption("apclasspath", "<classpath>", "Annotation processor classpath",
|
||||
required = false, allowMultipleOccurrences = true)
|
||||
|
||||
val APT_OPTIONS_OPTION: CliOption =
|
||||
CliOption("apoption", "<key>:<value>", "Annotation processor option",
|
||||
required = false, allowMultipleOccurrences = true)
|
||||
|
||||
val INCREMENTAL_DATA_FILE_OPTION: CliOption =
|
||||
CliOption("incrementalData", "<path>", "Location of the incremental data file", required = false)
|
||||
|
||||
val VERBOSE_MODE_OPTION: CliOption =
|
||||
CliOption("verbose", "true | false", "Enable verbose output", required = false)
|
||||
}
|
||||
|
||||
override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID
|
||||
|
||||
override val pluginOptions: Collection<CliOption> =
|
||||
listOf(GENERATED_OUTPUT_DIR_OPTION, ANNOTATION_PROCESSOR_CLASSPATH_OPTION, APT_OPTIONS_OPTION,
|
||||
CLASS_FILES_OUTPUT_DIR_OPTION, INCREMENTAL_DATA_FILE_OPTION, VERBOSE_MODE_OPTION)
|
||||
|
||||
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
|
||||
when (option) {
|
||||
ANNOTATION_PROCESSOR_CLASSPATH_OPTION -> configuration.appendList(ANNOTATION_PROCESSOR_CLASSPATH, value)
|
||||
APT_OPTIONS_OPTION -> configuration.appendList(APT_OPTIONS, value)
|
||||
GENERATED_OUTPUT_DIR_OPTION -> configuration.put(AnnotationProcessingConfigurationKeys.GENERATED_OUTPUT_DIR, value)
|
||||
CLASS_FILES_OUTPUT_DIR_OPTION -> configuration.put(AnnotationProcessingConfigurationKeys.CLASS_FILES_OUTPUT_DIR, value)
|
||||
INCREMENTAL_DATA_FILE_OPTION -> configuration.put(AnnotationProcessingConfigurationKeys.INCREMENTAL_DATA_FILE, value)
|
||||
VERBOSE_MODE_OPTION -> configuration.put(AnnotationProcessingConfigurationKeys.VERBOSE_MODE, value)
|
||||
else -> throw CliOptionProcessingException("Unknown option: ${option.name}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AnnotationProcessingComponentRegistrar : ComponentRegistrar {
|
||||
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
|
||||
val generatedOutputDir = configuration.get(AnnotationProcessingConfigurationKeys.GENERATED_OUTPUT_DIR) ?: return
|
||||
val apClasspath = configuration.get(ANNOTATION_PROCESSOR_CLASSPATH)?.map(::File) ?: return
|
||||
|
||||
val apOptions = (configuration.get(APT_OPTIONS) ?: listOf())
|
||||
.map { it.split(':') }
|
||||
.filter { it.size == 2 }
|
||||
.map { it[0] to it[1] }
|
||||
.toMap()
|
||||
|
||||
val incrementalDataFile = configuration.get(AnnotationProcessingConfigurationKeys.INCREMENTAL_DATA_FILE)?.let(::File)
|
||||
|
||||
val generatedOutputDirFile = File(generatedOutputDir)
|
||||
generatedOutputDirFile.mkdirs()
|
||||
|
||||
val contentRoots = configuration[JVMConfigurationKeys.CONTENT_ROOTS] ?: emptyList()
|
||||
|
||||
val compileClasspath = contentRoots.filterIsInstance<JvmContentRoot>().map { it.file }
|
||||
val classpath = apClasspath + compileClasspath
|
||||
|
||||
val javaRoots = contentRoots.filterIsInstance<JavaSourceRoot>().map { it.file }
|
||||
|
||||
val classesOutputDir = File(configuration.get(AnnotationProcessingConfigurationKeys.CLASS_FILES_OUTPUT_DIR)
|
||||
?: configuration[JVMConfigurationKeys.MODULES]!!.first().getOutputDirectory())
|
||||
|
||||
val verboseOutput = configuration.get(AnnotationProcessingConfigurationKeys.VERBOSE_MODE) == "true"
|
||||
|
||||
Extensions.getRootArea().getExtensionPoint(DefaultErrorMessages.Extension.EP_NAME)
|
||||
.registerExtension(DefaultErrorMessagesAnnotationProcessing())
|
||||
|
||||
// Annotations with the "SOURCE" retention will be written to class files
|
||||
project.putUserData(IS_KAPT2_ENABLED_KEY, true)
|
||||
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
|
||||
val annotationProcessingExtension = ClasspathBasedAnnotationProcessingExtension(
|
||||
classpath, apOptions, generatedOutputDirFile, classesOutputDir, javaRoots, verboseOutput,
|
||||
incrementalDataFile, messageCollector)
|
||||
|
||||
project.registerService(JeElementRegistry::class.java, JeElementRegistry())
|
||||
|
||||
AnalysisHandlerExtension.registerExtension(project, annotationProcessingExtension)
|
||||
}
|
||||
}
|
||||
-126
@@ -1,126 +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.annotation.processing
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.asJava.findFacadeClass
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.java.model.internal.getAnnotationsWithInherited
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
internal class RoundAnnotations(
|
||||
val bindingContext: BindingContext,
|
||||
val typeMapper: KotlinTypeMapper
|
||||
) {
|
||||
private companion object {
|
||||
private val BLACKLISTED_ANNOTATATIONS = listOf(
|
||||
"java.lang.Deprecated", "kotlin.Deprecated", // Deprecated annotations
|
||||
"java.lang.annotation.", // Java annotations
|
||||
"org.jetbrains.annotations.", // Nullable/NotNull, ReadOnly, Mutable
|
||||
"kotlin.jvm.", "kotlin.Metadata" // Kotlin annotations from runtime
|
||||
)
|
||||
}
|
||||
|
||||
private val mutableAnnotationsMap = mutableMapOf<String, MutableList<PsiModifierListOwner>>()
|
||||
private val mutableAnalyzedClasses = mutableSetOf<String>()
|
||||
|
||||
val annotationsMap: Map<String, List<PsiModifierListOwner>>
|
||||
get() = mutableAnnotationsMap
|
||||
|
||||
val analyzedClasses: Set<String>
|
||||
get() = mutableAnalyzedClasses
|
||||
|
||||
fun copy() = RoundAnnotations(bindingContext, typeMapper)
|
||||
|
||||
fun analyzeFiles(files: Collection<KtFile>) = files.forEach { analyzeFile(it) }
|
||||
|
||||
@JvmName("analyzePsiJavaFiles")
|
||||
fun analyzeFiles(files: Collection<PsiJavaFile>) = files.forEach { analyzeFile(it) }
|
||||
|
||||
fun analyzeFile(file: KtFile) {
|
||||
val lightClass = file.findFacadeClass()
|
||||
|
||||
if (lightClass != null) {
|
||||
analyzeDeclaration(lightClass)
|
||||
}
|
||||
|
||||
for (declaration in file.declarations) {
|
||||
if (declaration !is KtClassOrObject) continue
|
||||
val clazz = declaration.toLightClass() ?: continue
|
||||
analyzeDeclaration(clazz)
|
||||
}
|
||||
}
|
||||
|
||||
fun analyzeFile(file: PsiJavaFile) {
|
||||
file.classes.forEach { analyzeDeclaration(it) }
|
||||
}
|
||||
|
||||
fun PsiElement.getTopLevelClassParent(): PsiClass? = when (this) {
|
||||
is PsiClass -> containingClass?.let { it.getTopLevelClassParent() } ?: this
|
||||
else -> PsiTreeUtil.getParentOfType(this, PsiClass::class.java, true)?.getTopLevelClassParent()
|
||||
}
|
||||
|
||||
private val PsiAnnotation.hasSourceRetention: Boolean
|
||||
get() {
|
||||
val annotationDeclaration = nameReferenceElement?.resolve() as? PsiClass ?: return false
|
||||
val metaAnnotations = annotationDeclaration.modifierList?.annotations ?: return false
|
||||
return metaAnnotations.any { anno ->
|
||||
val declaration = anno.nameReferenceElement?.resolve() as? PsiClass ?: return@any false
|
||||
if (declaration.qualifiedName != "java.lang.annotation.Retention") return@any false
|
||||
val value = (anno.findAttributeValue("value") as? PsiReferenceExpression)?.resolve() ?: return@any false
|
||||
value is PsiEnumConstant && value.name == "SOURCE"
|
||||
}
|
||||
}
|
||||
|
||||
fun analyzeDeclaration(declaration: PsiElement): Boolean {
|
||||
if (declaration !is PsiModifierListOwner) return false
|
||||
|
||||
// Do not analyze classes twice (for incremental compilation data)
|
||||
if (declaration is PsiClass && declaration.qualifiedName in analyzedClasses) return false
|
||||
|
||||
for (annotation in declaration.getAnnotationsWithInherited()) {
|
||||
val fqName = annotation.qualifiedName ?: continue
|
||||
|
||||
if (BLACKLISTED_ANNOTATATIONS.any { fqName.startsWith(it) }) continue
|
||||
mutableAnnotationsMap.getOrPut(fqName, { mutableListOf() }).add(declaration)
|
||||
|
||||
// Add only top-level classes
|
||||
val topLevelClassQualifiedName = declaration.getTopLevelClassParent()?.qualifiedName
|
||||
if (topLevelClassQualifiedName != null) {
|
||||
mutableAnalyzedClasses += topLevelClassQualifiedName
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration is PsiClass) {
|
||||
declaration.methods.forEach { analyzeDeclaration(it) }
|
||||
declaration.fields.forEach { analyzeDeclaration(it) }
|
||||
declaration.innerClasses.forEach { analyzeDeclaration(it) }
|
||||
}
|
||||
|
||||
if (declaration is PsiMethod) {
|
||||
for (parameter in declaration.parameterList.parameters) {
|
||||
analyzeDeclaration(parameter)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +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.annotation.processing.diagnostic
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
||||
|
||||
class DefaultErrorMessagesAnnotationProcessing : DefaultErrorMessages.Extension {
|
||||
|
||||
private companion object {
|
||||
val MAP = DiagnosticFactoryToRendererMap("AnnotationProcessing")
|
||||
|
||||
init {
|
||||
MAP.put(ErrorsAnnotationProcessing.ANNOTATION_PROCESSING_ERROR,
|
||||
"Some error(s) occurred while processing annotations. Please see the error messages above.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMap() = MAP
|
||||
}
|
||||
-35
@@ -1,35 +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.annotation.processing.diagnostic;
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.psi.KtElement;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.Severity.ERROR;
|
||||
|
||||
public interface ErrorsAnnotationProcessing {
|
||||
DiagnosticFactory0<KtElement> ANNOTATION_PROCESSING_ERROR = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
Object _initializer = new Object() {
|
||||
{
|
||||
Errors.Initializer.initializeFactoryNames(ErrorsAnnotationProcessing.class);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
-225
@@ -1,225 +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.annotation.processing.impl
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiSuperMethodUtil
|
||||
import com.intellij.psi.util.TypeConversionUtil
|
||||
import org.jetbrains.kotlin.java.model.JeAnnotationOwner
|
||||
import org.jetbrains.kotlin.java.model.JeElement
|
||||
import org.jetbrains.kotlin.java.model.JeName
|
||||
import org.jetbrains.kotlin.java.model.elements.JeAnnotationMirror
|
||||
import org.jetbrains.kotlin.java.model.elements.JeMethodExecutableElement
|
||||
import org.jetbrains.kotlin.java.model.elements.JePackageElement
|
||||
import org.jetbrains.kotlin.java.model.elements.JeTypeElement
|
||||
import org.jetbrains.kotlin.java.model.internal.getTypeWithTypeParameters
|
||||
import org.jetbrains.kotlin.java.model.util.disposeAll
|
||||
import org.jetbrains.kotlin.java.model.util.toDisposable
|
||||
import java.io.PrintWriter
|
||||
import java.io.Writer
|
||||
import javax.lang.model.element.*
|
||||
import javax.lang.model.util.Elements
|
||||
|
||||
class KotlinElements(
|
||||
javaPsiFacade: JavaPsiFacade,
|
||||
scope: GlobalSearchScope
|
||||
) : Elements, Disposable {
|
||||
internal val javaPsiFacade = javaPsiFacade.toDisposable()
|
||||
internal val scope = scope.toDisposable()
|
||||
|
||||
override fun dispose() = disposeAll(javaPsiFacade, scope)
|
||||
|
||||
override fun hides(hider: Element, hidden: Element): Boolean {
|
||||
val hiderMethod = (hider as? JeMethodExecutableElement)?.psi ?: return false
|
||||
val hiddenMethod = (hidden as? JeMethodExecutableElement)?.psi ?: return false
|
||||
|
||||
val hiderMethodClass = hiderMethod.containingClass ?: return false
|
||||
val hiddenMethodClass = hiddenMethod.containingClass ?: return false
|
||||
|
||||
if (hiddenMethodClass.getTypeWithTypeParameters() !in hiderMethodClass.superTypes) return false
|
||||
|
||||
return isSubSignature(hiderMethod, hiddenMethod)
|
||||
}
|
||||
|
||||
override fun overrides(overrider: ExecutableElement, overridden: ExecutableElement, type: TypeElement): Boolean {
|
||||
overrider as? JeMethodExecutableElement ?: return false
|
||||
overridden as? JeMethodExecutableElement ?: return false
|
||||
type as? JeTypeElement ?: return false
|
||||
|
||||
if (overrider.psi == overridden.psi) return false
|
||||
|
||||
// if 'type' is a subtype of overrider's containing class
|
||||
if (type.psi.isSubclassOf(overridden.psi.containingClass) && type.psi.isSubclassOf(overrider.psi.containingClass)) {
|
||||
return isSubSignature(overrider.psi, overridden.psi)
|
||||
}
|
||||
|
||||
return PsiSuperMethodUtil.isSuperMethod(overrider.psi, overridden.psi)
|
||||
}
|
||||
|
||||
override fun getName(cs: CharSequence?) = JeName(cs?.toString())
|
||||
|
||||
override fun getElementValuesWithDefaults(a: AnnotationMirror): Map<out ExecutableElement, AnnotationValue> {
|
||||
a as? JeAnnotationMirror ?: return emptyMap()
|
||||
return a.getAllElementValues()
|
||||
}
|
||||
|
||||
override fun getBinaryName(type: TypeElement) = JeName((type as JeTypeElement).psi.qualifiedName)
|
||||
|
||||
//TODO
|
||||
override fun getDocComment(e: Element?) = null
|
||||
|
||||
override fun isDeprecated(e: Element?): Boolean {
|
||||
val deprecated = ((e as? JeElement)?.psi as? PsiDocCommentOwner)?.isDeprecated ?: false
|
||||
if (deprecated) return true
|
||||
return (e as? JeAnnotationOwner)?.psi?.modifierList?.findAnnotation("java.lang.Deprecated") != null
|
||||
}
|
||||
|
||||
override fun getAllMembers(type: TypeElement) = (type as? JeTypeElement)?.getAllMembers() ?: emptyList()
|
||||
|
||||
override fun printElements(w: Writer, vararg elements: Element) {
|
||||
val printWriter = PrintWriter(w)
|
||||
for (element in elements) {
|
||||
printWriter.println(element.simpleName.toString() + " (" + element::class.java.name + ")")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPackageElement(name: CharSequence): PackageElement? {
|
||||
val psiPackage = javaPsiFacade().findPackage(name.toString()) ?: return null
|
||||
return JePackageElement(psiPackage)
|
||||
}
|
||||
|
||||
override fun getTypeElement(name: CharSequence): TypeElement? {
|
||||
val psiClass = javaPsiFacade().findClass(name.toString(), scope()) ?: return null
|
||||
return JeTypeElement(psiClass)
|
||||
}
|
||||
|
||||
override fun getConstantExpression(value: Any?) = Constants.format(value)
|
||||
|
||||
override tailrec fun getPackageOf(element: Element): PackageElement? {
|
||||
if (element is PackageElement) return element
|
||||
val parent = element.enclosingElement ?: return null
|
||||
return getPackageOf(parent)
|
||||
}
|
||||
|
||||
override fun getAllAnnotationMirrors(e: Element): List<AnnotationMirror> {
|
||||
val annotations = (e as? JeElement)?.annotationMirrors?.toMutableList() ?: mutableListOf()
|
||||
|
||||
if (e is JeTypeElement) {
|
||||
var parent = e.psi.superClass
|
||||
while (parent != null) {
|
||||
val parentAnnotations = parent.modifierList?.annotations
|
||||
if (parentAnnotations == null) {
|
||||
parent = parent.superClass
|
||||
continue
|
||||
}
|
||||
|
||||
for (parentAnnotation in parentAnnotations) {
|
||||
val annotationClass = parentAnnotation.nameReferenceElement?.resolve() as? PsiClass ?: continue
|
||||
annotationClass.modifierList?.findAnnotation("java.lang.annotation.Inherited") ?: continue
|
||||
annotations += JeAnnotationMirror(parentAnnotation)
|
||||
}
|
||||
|
||||
parent = parent.superClass
|
||||
}
|
||||
}
|
||||
|
||||
return annotations
|
||||
}
|
||||
|
||||
override fun isFunctionalInterface(type: TypeElement): Boolean {
|
||||
val jeTypeElement = type as? JeTypeElement ?: return false
|
||||
if (!jeTypeElement.psi.isInterface) return false
|
||||
if (jeTypeElement.psi.allMethods.count { it.hasModifierProperty(PsiModifier.ABSTRACT) } != 1) return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private fun PsiClass.isSubclassOf(other: PsiClass?): Boolean {
|
||||
if (other == null) return false
|
||||
return TypeConversionUtil.isAssignable(other.getTypeWithTypeParameters(), this.getTypeWithTypeParameters(), false)
|
||||
}
|
||||
|
||||
private fun isSubSignature(childMethod: PsiMethod, superMethod: PsiMethod): Boolean {
|
||||
if (childMethod.name != superMethod.name) return false
|
||||
if (childMethod.parameterList.parametersCount != superMethod.parameterList.parametersCount) return false
|
||||
|
||||
if (childMethod.returnType != superMethod.returnType) return false
|
||||
for (i in 0..childMethod.parameterList.parametersCount - 1) {
|
||||
if (childMethod.parameterList.parameters[i].type != superMethod.parameterList.parameters[i].type) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
object Constants {
|
||||
fun format(value: Any?): String {
|
||||
return when (value) {
|
||||
is Byte -> formatByte((value as Byte?)!!)
|
||||
is Short -> formatShort((value as Short?)!!)
|
||||
is Long -> formatLong((value as Long?)!!)
|
||||
is Float -> formatFloat((value as Float?)!!)
|
||||
is Double -> formatDouble((value as Double?)!!)
|
||||
is Char -> formatChar(value)
|
||||
is String -> formatString(value)
|
||||
is Int, is Boolean -> value.toString()
|
||||
else -> throw IllegalArgumentException(
|
||||
"Argument is not a primitive type or a string; it " +
|
||||
(if (value == null) "is a null value." else "has class " + value::class.java.name) + ".")
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatByte(b: Byte) = String.format("(byte)0x%02x", b)
|
||||
private fun formatShort(s: Short) = String.format("(short)%d", s)
|
||||
private fun formatLong(lng: Long) = "${lng}L"
|
||||
private fun formatChar(c: Char) = '\'' + quote(c) + '\''
|
||||
private fun formatString(s: String) = '"' + quote(s) + '"'
|
||||
|
||||
private fun formatFloat(f: Float): String = when {
|
||||
java.lang.Float.isNaN(f) -> "0.0f/0.0f"
|
||||
java.lang.Float.isInfinite(f) -> if (f < 0) "-1.0f/0.0f" else "1.0f/0.0f"
|
||||
else -> "${f}f"
|
||||
}
|
||||
|
||||
private fun formatDouble(d: Double): String = when {
|
||||
java.lang.Double.isNaN(d) -> "0.0/0.0"
|
||||
java.lang.Double.isInfinite(d) -> if (d < 0) "-1.0/0.0" else "1.0/0.0"
|
||||
else -> d.toString()
|
||||
}
|
||||
|
||||
fun quote(ch: Char): String = when (ch) {
|
||||
'\b' -> "\\b"
|
||||
'\n' -> "\\n"
|
||||
'\r' -> "\\r"
|
||||
'\t' -> "\\t"
|
||||
'\'' -> "\\'"
|
||||
'\"' -> "\\\""
|
||||
'\\' -> "\\\\"
|
||||
else -> if (isPrintableAscii(ch)) ch.toString() else String.format("\\u%04x", ch.toInt())
|
||||
}
|
||||
|
||||
fun quote(s: String): String {
|
||||
val buf = StringBuilder()
|
||||
for (i in 0..s.length - 1) {
|
||||
buf.append(quote(s[i]))
|
||||
}
|
||||
return buf.toString()
|
||||
}
|
||||
|
||||
private fun isPrintableAscii(ch: Char) = ch >= ' ' && ch <= '~'
|
||||
}
|
||||
-102
@@ -1,102 +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.annotation.processing.impl
|
||||
|
||||
import java.io.File
|
||||
import javax.annotation.processing.Filer
|
||||
import javax.lang.model.element.Element
|
||||
import javax.tools.FileObject
|
||||
import javax.tools.JavaFileManager
|
||||
import javax.tools.JavaFileObject
|
||||
import javax.tools.StandardLocation
|
||||
|
||||
class KotlinFiler(
|
||||
val generatedSourceDir: File,
|
||||
val classesOutputDir: File,
|
||||
internal var onFileCreatedHandler: (File) -> Unit = {}
|
||||
) : Filer {
|
||||
private companion object {
|
||||
val PACKAGE_INFO_SUFFIX = ".packageInfo"
|
||||
}
|
||||
|
||||
internal var wasAnythingGenerated: Boolean = false
|
||||
private set
|
||||
|
||||
private fun getGeneratedFile(nameCharSequence: CharSequence, extension: String, baseDir: File = generatedSourceDir): Pair<File, String> {
|
||||
val name = nameCharSequence.toString()
|
||||
val isPackageInfo = name.endsWith(PACKAGE_INFO_SUFFIX)
|
||||
val fqName = if (isPackageInfo) name.substring(0, PACKAGE_INFO_SUFFIX.length) else name
|
||||
|
||||
val packageName = fqName.substringBeforeLast('.', "")
|
||||
|
||||
val packageDir = if (packageName.isNotEmpty()) {
|
||||
File(baseDir, packageName.replace('.', '/')).apply { mkdirs() }
|
||||
}
|
||||
else {
|
||||
baseDir
|
||||
}
|
||||
|
||||
val fileName = fqName.substringAfterLast('.') + (if (isPackageInfo) PACKAGE_INFO_SUFFIX else extension)
|
||||
val file = File(packageDir, fileName)
|
||||
return Pair(file, file.toRelativeString(baseDir))
|
||||
}
|
||||
|
||||
private fun File.notifyCreated() = apply {
|
||||
wasAnythingGenerated = true
|
||||
onFileCreatedHandler(this)
|
||||
}
|
||||
|
||||
override fun createSourceFile(name: CharSequence, vararg originatingElements: Element?): JavaFileObject {
|
||||
val (file, fileName) = getGeneratedFile(name, ".java")
|
||||
return KotlinJavaFileObject(file.notifyCreated(), fileName)
|
||||
}
|
||||
|
||||
override fun getResource(location: JavaFileManager.Location, pkg: CharSequence, relativeName: CharSequence): FileObject? {
|
||||
val (file, fileName) = getResourceFile(location, pkg, relativeName)
|
||||
return KotlinFileObject(file, fileName)
|
||||
}
|
||||
|
||||
override fun createResource(
|
||||
location: JavaFileManager.Location,
|
||||
pkg: CharSequence,
|
||||
relativeName: CharSequence,
|
||||
vararg originatingElements: Element?
|
||||
): FileObject? {
|
||||
val (resourceFile, fileName) = getResourceFile(location, pkg, relativeName)
|
||||
resourceFile.parentFile.mkdirs()
|
||||
return KotlinFileObject(resourceFile.notifyCreated(), fileName)
|
||||
}
|
||||
|
||||
private fun getResourceFile(location: JavaFileManager.Location, pkg: CharSequence, relativeName: CharSequence): Pair<File, String> {
|
||||
val baseDir = when (location) {
|
||||
StandardLocation.CLASS_OUTPUT -> classesOutputDir
|
||||
StandardLocation.SOURCE_OUTPUT -> generatedSourceDir
|
||||
else -> throw IllegalArgumentException("Location is not supported: $location (${location.name})")
|
||||
}
|
||||
|
||||
val targetDir = File(baseDir, pkg.toString().replace('.', '/'))
|
||||
targetDir.mkdirs()
|
||||
|
||||
val resourceFile = File(targetDir, relativeName.toString())
|
||||
return Pair(resourceFile, resourceFile.toRelativeString(baseDir))
|
||||
}
|
||||
|
||||
override fun createClassFile(name: CharSequence, vararg originatingElements: Element?): JavaFileObject {
|
||||
val (file, fileName) = getGeneratedFile(name, ".class")
|
||||
return KotlinJavaFileObject(file.notifyCreated(), fileName)
|
||||
}
|
||||
}
|
||||
-61
@@ -1,61 +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.annotation.processing.impl
|
||||
|
||||
import java.io.File
|
||||
import javax.tools.FileObject
|
||||
import javax.tools.JavaFileObject
|
||||
|
||||
class KotlinJavaFileObject(file: File, fileName: String) : KotlinAbstractFileObject(file, fileName), JavaFileObject {
|
||||
//TODO
|
||||
override fun isNameCompatible(simpleName: String, kind: JavaFileObject.Kind) = true
|
||||
|
||||
override fun getKind() = when (file.extension) {
|
||||
"class" -> JavaFileObject.Kind.CLASS
|
||||
"java" -> JavaFileObject.Kind.SOURCE
|
||||
"html" -> JavaFileObject.Kind.HTML
|
||||
else -> JavaFileObject.Kind.OTHER
|
||||
}
|
||||
|
||||
//TODO
|
||||
override fun getAccessLevel() = null
|
||||
|
||||
//TODO
|
||||
override fun getNestingKind() = null
|
||||
}
|
||||
|
||||
class KotlinFileObject(file: File, fileName: String) : KotlinAbstractFileObject(file, fileName)
|
||||
|
||||
abstract class KotlinAbstractFileObject(val file: File, val fileName: String) : FileObject {
|
||||
override fun openOutputStream() = file.outputStream()
|
||||
|
||||
override fun getName() = fileName
|
||||
|
||||
override fun openWriter() = file.writer()
|
||||
|
||||
override fun openInputStream() = file.inputStream()
|
||||
|
||||
override fun getCharContent(ignoreEncodingErrors: Boolean) = file.readText()
|
||||
|
||||
override fun getLastModified() = file.lastModified()
|
||||
|
||||
override fun toUri() = file.toURI()
|
||||
|
||||
override fun openReader(ignoreEncodingErrors: Boolean) = file.reader()
|
||||
|
||||
override fun delete() = file.delete()
|
||||
}
|
||||
-61
@@ -1,61 +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.annotation.processing.impl
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import javax.annotation.processing.Messager
|
||||
import javax.lang.model.element.AnnotationMirror
|
||||
import javax.lang.model.element.AnnotationValue
|
||||
import javax.lang.model.element.Element
|
||||
import javax.tools.Diagnostic
|
||||
import javax.tools.Diagnostic.Kind
|
||||
|
||||
class KotlinMessager(private val messageCollector: MessageCollector) : Messager {
|
||||
var errorCount: Int = 0
|
||||
private set
|
||||
|
||||
var warningCount: Int = 0
|
||||
private set
|
||||
|
||||
override fun printMessage(kind: Diagnostic.Kind, msg: CharSequence) = printMessage(kind, msg, null)
|
||||
|
||||
override fun printMessage(kind: Diagnostic.Kind, msg: CharSequence, e: Element?) = printMessage(kind, msg, e, null)
|
||||
|
||||
override fun printMessage(kind: Diagnostic.Kind, msg: CharSequence, e: Element?, a: AnnotationMirror?) {
|
||||
printMessage(kind, msg, e, a, null)
|
||||
}
|
||||
|
||||
override fun printMessage(kind: Diagnostic.Kind, msg: CharSequence, e: Element?, a: AnnotationMirror?, v: AnnotationValue?) {
|
||||
val severity = when (kind) {
|
||||
Kind.ERROR -> {
|
||||
errorCount++
|
||||
CompilerMessageSeverity.ERROR
|
||||
}
|
||||
Kind.WARNING -> {
|
||||
warningCount++
|
||||
CompilerMessageSeverity.WARNING
|
||||
}
|
||||
Kind.MANDATORY_WARNING -> {
|
||||
warningCount++
|
||||
CompilerMessageSeverity.STRONG_WARNING
|
||||
}
|
||||
else -> CompilerMessageSeverity.LOGGING
|
||||
}
|
||||
messageCollector.report(severity, msg.toString())
|
||||
}
|
||||
}
|
||||
-83
@@ -1,83 +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.annotation.processing.impl
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.java.model.internal.JeElementRegistry
|
||||
import org.jetbrains.kotlin.java.model.util.disposeAll
|
||||
import org.jetbrains.kotlin.java.model.util.toDisposable
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import javax.annotation.processing.ProcessingEnvironment
|
||||
import javax.annotation.processing.Processor
|
||||
import javax.lang.model.SourceVersion
|
||||
|
||||
class KotlinProcessingEnvironment(
|
||||
elements: KotlinElements,
|
||||
types: KotlinTypes,
|
||||
messager: KotlinMessager,
|
||||
options: Map<String, String>,
|
||||
filer: KotlinFiler,
|
||||
|
||||
processors: List<Processor>,
|
||||
|
||||
project: Project,
|
||||
psiManager: PsiManager,
|
||||
javaPsiFacade: JavaPsiFacade,
|
||||
projectScope: GlobalSearchScope,
|
||||
bindingContext: BindingContext,
|
||||
appendJavaSourceRootsHandler: (List<File>) -> Unit
|
||||
) : ProcessingEnvironment, Disposable {
|
||||
private val elements = elements.toDisposable()
|
||||
private val types = types.toDisposable()
|
||||
private val messager = messager.toDisposable()
|
||||
private val filer = filer.toDisposable()
|
||||
internal val processors = processors.toDisposable()
|
||||
|
||||
internal val project = project.toDisposable()
|
||||
internal val psiManager = psiManager.toDisposable()
|
||||
internal val javaPsiFacade = javaPsiFacade.toDisposable()
|
||||
internal val projectScope = projectScope.toDisposable()
|
||||
internal val bindingContext = bindingContext.toDisposable()
|
||||
|
||||
private val registry = ServiceManager.getService(project, JeElementRegistry::class.java).toDisposable()
|
||||
internal val appendJavaSourceRootsHandler = appendJavaSourceRootsHandler.toDisposable()
|
||||
private val options = Collections.unmodifiableMap(options).toDisposable()
|
||||
|
||||
override fun dispose() {
|
||||
types().dispose()
|
||||
elements().dispose()
|
||||
registry().dispose()
|
||||
disposeAll(elements, types, messager, filer, processors,
|
||||
project, psiManager, javaPsiFacade, projectScope, bindingContext,
|
||||
appendJavaSourceRootsHandler, options)
|
||||
}
|
||||
|
||||
override fun getElementUtils() = elements()
|
||||
override fun getTypeUtils() = types()
|
||||
override fun getMessager() = messager()
|
||||
override fun getLocale() = Locale.getDefault()
|
||||
override fun getSourceVersion() = SourceVersion.RELEASE_8
|
||||
override fun getOptions() = options()
|
||||
override fun getFiler() = filer()
|
||||
}
|
||||
-56
@@ -1,56 +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.annotation.processing.impl
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.annotation.processing.RoundAnnotations
|
||||
import org.jetbrains.kotlin.java.model.toJeElement
|
||||
import org.jetbrains.kotlin.java.model.util.disposeAll
|
||||
import org.jetbrains.kotlin.java.model.util.toDisposable
|
||||
import javax.annotation.processing.RoundEnvironment
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.TypeElement
|
||||
|
||||
internal class KotlinRoundEnvironment(
|
||||
roundAnnotations: RoundAnnotations,
|
||||
private val isProcessingOver: Boolean,
|
||||
internal val roundNumber: Int
|
||||
) : RoundEnvironment, Disposable {
|
||||
val roundAnnotations = roundAnnotations.toDisposable()
|
||||
|
||||
override fun dispose() = disposeAll(roundAnnotations)
|
||||
|
||||
private var isError = false
|
||||
|
||||
override fun getRootElements() = emptySet<Element>()
|
||||
|
||||
override fun processingOver() = isProcessingOver
|
||||
|
||||
private fun getElementsAnnotatedWith(fqName: String): Set<Element> {
|
||||
val declarations = roundAnnotations().annotationsMap[fqName] ?: return emptySet()
|
||||
return hashSetOf<Element>().apply {
|
||||
for (declaration in declarations) {
|
||||
declaration.toJeElement()?.let { add(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getElementsAnnotatedWith(a: TypeElement) = getElementsAnnotatedWith(a.qualifiedName.toString())
|
||||
override fun getElementsAnnotatedWith(a: Class<out Annotation>) = getElementsAnnotatedWith(a.canonicalName)
|
||||
|
||||
override fun errorRaised() = isError
|
||||
}
|
||||
-315
@@ -1,315 +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.annotation.processing.impl
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.MethodSignatureUtil
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import com.intellij.psi.util.TypeConversionUtil
|
||||
import org.jetbrains.kotlin.java.model.JeElement
|
||||
import org.jetbrains.kotlin.java.model.elements.*
|
||||
import org.jetbrains.kotlin.java.model.types.*
|
||||
import org.jetbrains.kotlin.java.model.util.disposeAll
|
||||
import org.jetbrains.kotlin.java.model.util.toDisposable
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.TypeElement
|
||||
import javax.lang.model.type.*
|
||||
import javax.lang.model.util.Types
|
||||
|
||||
class KotlinTypes(
|
||||
javaPsiFacade: JavaPsiFacade,
|
||||
psiManager: PsiManager,
|
||||
scope: GlobalSearchScope
|
||||
) : Types, Disposable {
|
||||
val javaPsiFacade = javaPsiFacade.toDisposable()
|
||||
val psiManager = psiManager.toDisposable()
|
||||
val scope = scope.toDisposable()
|
||||
|
||||
override fun dispose() = disposeAll(javaPsiFacade, psiManager, scope)
|
||||
|
||||
override fun contains(containing: TypeMirror, contained: TypeMirror): Boolean {
|
||||
assertKindNot(containing, TypeKind.PACKAGE, TypeKind.EXECUTABLE)
|
||||
assertKindNot(contained, TypeKind.PACKAGE, TypeKind.EXECUTABLE)
|
||||
|
||||
assertJeType(containing); containing as JePsiType
|
||||
assertJeType(contained); contained as JePsiType
|
||||
|
||||
fun L(type: PsiType): PsiType = when {
|
||||
type is PsiWildcardType && type.isSuper -> type.superBound
|
||||
else -> type
|
||||
}
|
||||
|
||||
fun U(type: PsiType): PsiType = when {
|
||||
type is PsiWildcardType && type.isExtends -> type.extendsBound
|
||||
else -> type
|
||||
}
|
||||
|
||||
return when (containing) {
|
||||
is JeArrayType, is JePrimitiveType -> containing == contained
|
||||
else -> {
|
||||
!GenericsUtil.checkNotInBounds(L(contained.psiType), L(containing.psiType), false)
|
||||
&& !GenericsUtil.checkNotInBounds(U(contained.psiType), U(containing.psiType), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getArrayType(componentType: TypeMirror): ArrayType {
|
||||
if (componentType is ExecutableType || componentType is NoType) error(componentType)
|
||||
assertJeType(componentType); componentType as JePsiType
|
||||
|
||||
return JeArrayType(PsiArrayType(componentType.psiType), psiManager(), isRaw = false)
|
||||
}
|
||||
|
||||
override fun isAssignable(t1: TypeMirror, t2: TypeMirror): Boolean {
|
||||
assertKindNot(t1, TypeKind.PACKAGE, TypeKind.EXECUTABLE, TypeKind.NONE)
|
||||
assertKindNot(t2, TypeKind.PACKAGE, TypeKind.EXECUTABLE, TypeKind.NONE)
|
||||
|
||||
t1 as? JePsiType ?: return false
|
||||
t2 as? JePsiType ?: return false
|
||||
return t2.psiType.isAssignableFrom(t1.psiType)
|
||||
}
|
||||
|
||||
override fun getNullType() = JeNullType
|
||||
|
||||
override fun getWildcardType(extendsBound: TypeMirror?, superBound: TypeMirror?): JeWildcardType {
|
||||
if (extendsBound != null && superBound != null) {
|
||||
throw IllegalArgumentException("Both extendsBound and superBound should not be specified.")
|
||||
}
|
||||
|
||||
if (extendsBound != null && extendsBound !is JePsiType) illegalArg("extendsBound should have PsiType")
|
||||
if (superBound != null && superBound !is JePsiType) illegalArg("superBound should have PsiType")
|
||||
|
||||
return JeWildcardType(when {
|
||||
extendsBound != null -> PsiWildcardType.createExtends(psiManager(), (extendsBound as JePsiType).psiType)
|
||||
superBound != null -> PsiWildcardType.createSuper(psiManager(), (superBound as JePsiType).psiType)
|
||||
else -> PsiWildcardType.createUnbounded(psiManager())
|
||||
}, isRaw = false)
|
||||
}
|
||||
|
||||
override fun unboxedType(t: TypeMirror): PrimitiveType? {
|
||||
fun error(): Nothing = throw IllegalArgumentException("This type could not be unboxed: $t")
|
||||
t as? JePsiType ?: error()
|
||||
val unboxedType = PsiPrimitiveType.getUnboxedType(t.psiType) ?: error()
|
||||
return unboxedType.toJePrimitiveType()
|
||||
}
|
||||
|
||||
override fun getPrimitiveType(kind: TypeKind) = kind.toJePrimitiveType()
|
||||
|
||||
override fun erasure(t: TypeMirror): TypeMirror {
|
||||
if (t.kind == TypeKind.PACKAGE) throw IllegalArgumentException("Invalid type: $t")
|
||||
return when (t) {
|
||||
is JeTypeVariableType -> TypeConversionUtil.typeParameterErasure(t.parameter).toJeType(t.psiManager, isRaw = true)
|
||||
is JePsiType -> TypeConversionUtil.erasure(t.psiType).toJeType(psiManager(), isRaw = true)
|
||||
is JeMethodExecutableTypeMirror -> {
|
||||
val oldSignature = t.signature
|
||||
val parameterTypes = oldSignature?.parameterTypes?.toList() ?: t.psi.parameterList.parameters.map { it.type }
|
||||
val newSignature = MethodSignatureUtil.createMethodSignature(
|
||||
oldSignature?.name ?: t.psi.name,
|
||||
parameterTypes.map { TypeConversionUtil.erasure(it) }.toTypedArray(),
|
||||
emptyArray(),
|
||||
PsiSubstitutor.EMPTY,
|
||||
oldSignature?.isConstructor ?: t.psi.isConstructor)
|
||||
JeMethodExecutableTypeMirror(
|
||||
t.psi, newSignature,
|
||||
TypeConversionUtil.erasure(t.returnType ?: t.psi.returnType), isRaw = true)
|
||||
}
|
||||
else -> t
|
||||
}
|
||||
}
|
||||
|
||||
override fun directSupertypes(t: TypeMirror): List<TypeMirror> {
|
||||
if (t is NoType || t is ExecutableType) throw IllegalArgumentException("Invalid type: $t")
|
||||
|
||||
val psiType = (t as? JePsiType)?.psiType as? PsiClassType ?: return emptyList()
|
||||
return psiType.superTypes.map { it.toJeType(psiManager()) }
|
||||
}
|
||||
|
||||
override fun boxedClass(p: PrimitiveType): TypeElement? {
|
||||
p as? JePrimitiveType ?: throw IllegalArgumentException("Unknown type: $p")
|
||||
val boxedTypeName = p.psiType.boxedTypeName
|
||||
val boxedClass = javaPsiFacade().findClass(boxedTypeName, scope())
|
||||
?: throw IllegalStateException("Can't find boxed class $boxedTypeName")
|
||||
return JeTypeElement(boxedClass)
|
||||
}
|
||||
|
||||
override fun asElement(t: TypeMirror): Element? {
|
||||
if (t is JeDeclaredType) {
|
||||
return t.asElement()
|
||||
} else if (t is JeTypeVariableType) {
|
||||
return t.asElement()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
override fun isSubtype(t1: TypeMirror, t2: TypeMirror): Boolean {
|
||||
val psiType1 = (t1 as? JePsiType)?.psiType ?: return false
|
||||
val psiType2 = (t2 as? JePsiType)?.psiType ?: return false
|
||||
|
||||
return TypeConversionUtil.isAssignable(psiType2, psiType1, false)
|
||||
}
|
||||
|
||||
override fun isSameType(t1: TypeMirror, t2: TypeMirror) = t1 == t2
|
||||
|
||||
override fun getNoType(kind: TypeKind) = when (kind) {
|
||||
TypeKind.VOID -> JeVoidType
|
||||
TypeKind.NONE -> JeNoneType
|
||||
else -> illegalArg("Must be kind of VOID or NONE, got ${kind.name}")
|
||||
}
|
||||
|
||||
override fun getDeclaredType(typeElem: TypeElement, vararg typeArgMirrors: TypeMirror): DeclaredType {
|
||||
val psiClass = (typeElem as JeTypeElement).psi
|
||||
if (!psiClass.hasTypeParameters() && typeArgMirrors.size > 0) {
|
||||
throw IllegalArgumentException("$typeElem has not type parameters")
|
||||
}
|
||||
|
||||
// Raw type
|
||||
if (psiClass.hasTypeParameters() && typeArgMirrors.isEmpty()) {
|
||||
return JeDeclaredType(PsiTypesUtil.getClassType(psiClass).rawType(), psiClass)
|
||||
}
|
||||
|
||||
val typeParameters = psiClass.typeParameters
|
||||
if (typeArgMirrors.size != typeParameters.size) {
|
||||
throw IllegalArgumentException("$typeElem type parameters count: " +
|
||||
"${typeParameters.size}, received ${typeArgMirrors.size} args")
|
||||
}
|
||||
|
||||
val typeArgs = typeArgMirrors.mapIndexed {
|
||||
i, t -> (t as? JePsiType)?.psiType ?: throw IllegalArgumentException("Invalid type argument #$i: $t")
|
||||
}
|
||||
|
||||
val psiType = createImmediateClassType(psiClass, typeArgs) ?:
|
||||
throw IllegalStateException("Can't create declared type ($psiClass, $typeArgs)")
|
||||
return JeDeclaredType(psiType, psiClass)
|
||||
}
|
||||
|
||||
override fun getDeclaredType(
|
||||
containing: DeclaredType?,
|
||||
typeElem: TypeElement,
|
||||
vararg typeArgMirrors: TypeMirror
|
||||
): DeclaredType? {
|
||||
if (containing == null) {
|
||||
return getDeclaredType(typeElem, *typeArgMirrors)
|
||||
}
|
||||
|
||||
val psiClass = (typeElem as JeTypeElement).psi
|
||||
if (psiClass.containingClass == null) {
|
||||
throw IllegalArgumentException("$typeElem is a top-level class element")
|
||||
}
|
||||
|
||||
val containingType = (containing as? JePsiType)?.psiType as? PsiClassType
|
||||
?: throw IllegalArgumentException("Illegal containing type: $containing")
|
||||
val containingClass = containingType.resolve()
|
||||
?: throw IllegalArgumentException("Class type can't be resolved: $containing")
|
||||
|
||||
if (psiClass.containingClass != containingClass) {
|
||||
throw IllegalArgumentException("$containing is not an enclosing element for $typeElem")
|
||||
}
|
||||
|
||||
val typeArgs = typeArgMirrors.mapIndexed {
|
||||
i, t -> (t as? JePsiType)?.psiType ?: throw IllegalArgumentException("Invalid type argument #$i: $t")
|
||||
}
|
||||
|
||||
val psiType = createImmediateClassType(psiClass, typeArgs) ?:
|
||||
throw IllegalStateException("Can't create declared type ($psiClass, $typeArgs)")
|
||||
return JeDeclaredType(psiType, psiClass, containing)
|
||||
}
|
||||
|
||||
private fun Array<out PsiType>.findSuperType(superTypeClass: PsiClass): PsiClassType? {
|
||||
for (supertype in this) {
|
||||
if (supertype is PsiClassType && supertype.resolve() == superTypeClass) return supertype
|
||||
supertype.superTypes.findSuperType(superTypeClass)?.let { return it }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun asMemberOf(containing: DeclaredType, element: Element): TypeMirror {
|
||||
if (containing !is JeDeclaredType || element is JeClassInitializerExecutableElement) return element.asType()
|
||||
val containingType = containing.psiType
|
||||
|
||||
val member = (element as JeElement).psi as? PsiMember ?: return element.asType()
|
||||
|
||||
val memberOwnerClass = when (member) {
|
||||
is PsiTypeParameter -> member.owner as? PsiClass
|
||||
else -> member.containingClass
|
||||
} ?: return element.asType()
|
||||
|
||||
val relevantSuperType = if (memberOwnerClass == containingType.resolve()) {
|
||||
containingType
|
||||
} else {
|
||||
containingType.superTypes.findSuperType(memberOwnerClass) ?: return element.asType()
|
||||
}
|
||||
|
||||
val resolveResult = relevantSuperType.resolveGenerics()
|
||||
if (!resolveResult.isValidResult) return element.asType()
|
||||
val substitutor = resolveResult.substitutor
|
||||
|
||||
return when (element) {
|
||||
is JeMethodExecutableElement -> {
|
||||
val method = element.psi
|
||||
val signature = method.getSignature(substitutor)
|
||||
val returnType = substitutor.substitute(element.psi.returnType)
|
||||
JeMethodExecutableTypeMirror(method, signature, returnType)
|
||||
}
|
||||
is JeVariableElement -> substitutor.substitute(element.psi.type).toJeType(psiManager())
|
||||
is JeTypeParameterElement -> substitutor.substitute(element.psi)?.toJeType(psiManager()) ?: element.asType()
|
||||
else -> throw IllegalArgumentException("Invalid element type: ${element::class.java.name} ($element)")
|
||||
}
|
||||
}
|
||||
|
||||
override fun isSubsignature(t1: ExecutableType, t2: ExecutableType): Boolean {
|
||||
val m1 = (t1 as JeClassInitializerExecutableTypeMirror).psi
|
||||
val m2 = (t2 as JeClassInitializerExecutableTypeMirror).psi
|
||||
|
||||
// No parameters
|
||||
if (m1 is PsiClassInitializer && m2 is PsiClassInitializer) return true
|
||||
|
||||
if (m1 !is PsiMethod || m2 !is PsiMethod) return false
|
||||
|
||||
if (m1.parameterList.parametersCount != m2.parameterList.parametersCount) return false
|
||||
|
||||
for (i in 0..(m1.parameterList.parametersCount - 1)) {
|
||||
val p1 = m1.parameterList.parameters[i].type
|
||||
val p2 = m2.parameterList.parameters[i].type
|
||||
|
||||
if (p1 != p2 && TypeConversionUtil.erasure(p1) != TypeConversionUtil.erasure(p2)) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun capture(t: TypeMirror): TypeMirror? {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
|
||||
private fun illegalArg(text: String? = null): Nothing {
|
||||
val message = if (text != null) ": $text" else ""
|
||||
throw IllegalArgumentException("Illegal argument" + message)
|
||||
}
|
||||
|
||||
private fun assertKindNot(typeMirror: TypeMirror, vararg kinds: TypeKind): Unit {
|
||||
if (typeMirror.kind in kinds) illegalArg("type must not be kind of " + kinds.joinToString { it.name } + ", got ${typeMirror.kind.name}")
|
||||
}
|
||||
|
||||
private fun assertJeType(type: TypeMirror) {
|
||||
if (type !is JeTypeMirror) {
|
||||
illegalArg("Must be a subclass of JePsiType, got ${type::class.java.name}")
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
class MyClass {
|
||||
var myProperty: String = "A"
|
||||
|
||||
fun myFunction() = object : java.lang.Runnable {
|
||||
override fun run() {}
|
||||
}
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
annotation class Anno(val name: String = "Mary", val age: Int = 20)
|
||||
|
||||
@Anno("Tom", 10)
|
||||
class A
|
||||
|
||||
@Anno(name = "Tom")
|
||||
class B
|
||||
|
||||
@Anno(age = 10)
|
||||
class C
|
||||
|
||||
@Anno
|
||||
class D
|
||||
@@ -1,8 +0,0 @@
|
||||
package test
|
||||
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
class MyClass
|
||||
|
||||
interface MyInterface
|
||||
@@ -1,10 +0,0 @@
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
@Deprecated("")
|
||||
class Depr
|
||||
|
||||
class NoDepr
|
||||
|
||||
@java.lang.Deprecated
|
||||
class JavaDepr
|
||||
@@ -1,25 +0,0 @@
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
class A {
|
||||
interface AA {
|
||||
fun onClick(o: Any)
|
||||
}
|
||||
}
|
||||
|
||||
enum class B { RED }
|
||||
|
||||
interface C {
|
||||
fun onClick()
|
||||
}
|
||||
|
||||
interface D {
|
||||
fun onClick()
|
||||
fun onDoubleClick()
|
||||
}
|
||||
|
||||
interface E : C
|
||||
|
||||
interface F : C {
|
||||
fun onDoubleClick()
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
open class Parent {
|
||||
open fun a() {}
|
||||
}
|
||||
|
||||
open class Child : Parent() {
|
||||
override fun a() {}
|
||||
fun a(name: String) {}
|
||||
open fun b() = "A"
|
||||
}
|
||||
|
||||
class ChildOfChild : Child() {
|
||||
override fun a() {}
|
||||
override fun b() = "B"
|
||||
fun a(name: CharSequence) {}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
interface Intf {
|
||||
fun a()
|
||||
}
|
||||
|
||||
open class A {
|
||||
open fun a() {}
|
||||
}
|
||||
|
||||
class B : A(), Intf {
|
||||
override fun a() {}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
open class Base<T> {
|
||||
@JvmField
|
||||
val f: T = null!!
|
||||
|
||||
fun m(t: T): T = null!!
|
||||
}
|
||||
|
||||
class Impl<T> : Base<T>() {
|
||||
fun implM(t: T): T = null!!
|
||||
}
|
||||
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
class Test {
|
||||
val f = Impl<String>()
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
interface Intf<T>
|
||||
|
||||
open class Base<T> : Intf<T> {
|
||||
fun factory() = Base<CharSequence>()
|
||||
}
|
||||
|
||||
class Impl : Base<String>()
|
||||
@@ -1,12 +0,0 @@
|
||||
// Some user annotation is required because annoations from kotlin.jvm are filtered out in kapt
|
||||
annotation class Anno
|
||||
|
||||
@JvmSuppressWildcards
|
||||
@Anno
|
||||
class Test
|
||||
|
||||
@JvmSuppressWildcards(suppress = true)
|
||||
class TestTrue
|
||||
|
||||
@JvmSuppressWildcards(suppress = false)
|
||||
class TestFalse
|
||||
@@ -1 +0,0 @@
|
||||
class Test
|
||||
@@ -1,3 +0,0 @@
|
||||
class Test
|
||||
|
||||
annotation class Anno
|
||||
@@ -1,7 +0,0 @@
|
||||
package org.jetbrains.kotlin.annotation.processing.test.processor
|
||||
|
||||
enum class RGBColors { RED, GREEN, BLUE }
|
||||
annotation class ColorsAnnotation(val colors: Array<RGBColors>)
|
||||
|
||||
@ColorsAnnotation(colors = arrayOf(RGBColors.BLUE, RGBColors.RED))
|
||||
class Test
|
||||
@@ -1,23 +0,0 @@
|
||||
abstract class Base<A> {
|
||||
fun baseF(): A = null!!
|
||||
}
|
||||
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
class Test<T> : Base<Int>() {
|
||||
fun a(): String = ""
|
||||
fun b(i: String, b: CharSequence) {}
|
||||
fun c(): Int = 5
|
||||
fun d(): T = null!!
|
||||
fun <D : Any> e(item: D): D = item
|
||||
fun f(items: List<Map<String, Int>>, i: Int) {}
|
||||
fun <D : String> g(item: D) {}
|
||||
fun h(): Array<List<String>> = null!!
|
||||
fun <T> i(): T where T : CharSequence, T : Appendable = null!!
|
||||
}
|
||||
|
||||
class Test2<in A : List<String>, out B : List<String>> {
|
||||
fun a(items: A) {}
|
||||
fun b(): B = null!!
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
class Test {
|
||||
fun a(): Int = 5
|
||||
fun b(): Unit {}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
class Test
|
||||
|
||||
@Anno
|
||||
interface Intf
|
||||
|
||||
class Test2 {
|
||||
@Anno
|
||||
fun test2Fun() {}
|
||||
}
|
||||
|
||||
class Test3 {
|
||||
@Anno
|
||||
class Test3Nested
|
||||
|
||||
@Anno
|
||||
inner class Test3Inner
|
||||
}
|
||||
|
||||
class Test4
|
||||
|
||||
class Test5 {
|
||||
fun test5Fun() {}
|
||||
}
|
||||
|
||||
annotation class Surprise
|
||||
|
||||
@Surprise
|
||||
class Test6
|
||||
|
||||
class Test7 {
|
||||
@Surprise
|
||||
fun test7Fun(): String = "ABC"
|
||||
}
|
||||
|
||||
class Test8 {
|
||||
@Anno
|
||||
fun test8Fun1() {}
|
||||
|
||||
@Anno
|
||||
fun test8Fun2() {}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
@java.lang.annotation.Inherited
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
open class Base
|
||||
|
||||
class Impl : Base()
|
||||
|
||||
@Anno
|
||||
interface Intf
|
||||
|
||||
class IntfImpl : Intf
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
@Repeatable
|
||||
@java.lang.annotation.Inherited
|
||||
annotation class Anno(val name: String)
|
||||
|
||||
@Anno("Mary")
|
||||
open class Base
|
||||
|
||||
@Anno("Tom")
|
||||
class Impl : Base()
|
||||
@@ -1,25 +0,0 @@
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
class AnnoAnnotated
|
||||
|
||||
class Test {
|
||||
@kotlin.jvm.Transient
|
||||
val f: String = ""
|
||||
|
||||
// explicitly
|
||||
@org.jetbrains.annotations.NotNull
|
||||
fun a() {}
|
||||
|
||||
@kotlin.jvm.Synchronized
|
||||
fun b() {}
|
||||
|
||||
@kotlin.jvm.JvmOverloads
|
||||
fun c(a: Int = 3, b: String = "") {}
|
||||
|
||||
@java.lang.Deprecated
|
||||
fun d() {}
|
||||
|
||||
@kotlin.Deprecated("")
|
||||
fun e() {}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
annotation class Anno
|
||||
|
||||
interface Intf
|
||||
|
||||
@Anno
|
||||
class Test {
|
||||
fun a(map: Map<Int, Intf>) {}
|
||||
fun b(map: MutableMap<Int, Intf>) {}
|
||||
|
||||
fun c(map: Map<Int, Test>) {}
|
||||
fun d(map: MutableMap<Int, Test>) {}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
annotation class Anno(val a: Anno2, val b: Array<Anno2>, val c: String, val d: KClass<*>, val e: Array<KClass<*>>)
|
||||
annotation class Anno2(val name: String)
|
||||
|
||||
@Anno(a = Anno2("Tim"), b = arrayOf(Anno2("Kate"), Anno2("Mary")), c = "ABC", d = Anno2::class, e = arrayOf(Anno::class))
|
||||
class Test
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
@Name("Mary")
|
||||
@Age(18)
|
||||
class Mary
|
||||
|
||||
@Name("Kate")
|
||||
@Age(22)
|
||||
class Kate
|
||||
|
||||
annotation class Name(val name: String)
|
||||
annotation class Age(val age: Int)
|
||||
@@ -1,10 +0,0 @@
|
||||
annotation class Anno(val name: String)
|
||||
|
||||
@Anno("MyClassAnno")
|
||||
class MyClass {
|
||||
@Anno("myFuncAnno")
|
||||
fun myFunc(): String = "Mary"
|
||||
|
||||
@field:Anno("myFieldAnno")
|
||||
val myField: String = "Tom"
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class Source1
|
||||
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class Source2
|
||||
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class Source3
|
||||
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class Source4
|
||||
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class Binary
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class Runtime
|
||||
|
||||
@Source1
|
||||
class Test
|
||||
|
||||
class Test2 {
|
||||
@Source2
|
||||
fun t() {}
|
||||
}
|
||||
|
||||
class Test3 {
|
||||
@field:Source3
|
||||
val p: String = "A"
|
||||
}
|
||||
|
||||
class Test4 {
|
||||
fun t(@Source4 a: String) {}
|
||||
}
|
||||
|
||||
class Test5 {
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class Source5
|
||||
|
||||
@Source5
|
||||
fun t() {}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
@Anno
|
||||
class MyClass
|
||||
|
||||
annotation class Anno
|
||||
@@ -1,5 +0,0 @@
|
||||
@Anno2
|
||||
class MyClass
|
||||
|
||||
annotation class Anno
|
||||
annotation class Anno2
|
||||
@@ -1,2 +0,0 @@
|
||||
@Suppress("Tom", "Mary")
|
||||
class Test
|
||||
@@ -1,8 +0,0 @@
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
class A : B<Int>(), C<Int>
|
||||
|
||||
open class B<T>
|
||||
|
||||
interface C<T> {}
|
||||
@@ -1,17 +0,0 @@
|
||||
interface I<T>
|
||||
|
||||
abstract class A<T> : I<T>
|
||||
|
||||
annotation class Anno
|
||||
|
||||
@Anno
|
||||
class B : A<String>()
|
||||
|
||||
class C<T : CharSequence> : A<T>()
|
||||
|
||||
interface I2<X>
|
||||
open class B2<X>
|
||||
class A2<T : CharSequence> : B2<T>(), I2<T>
|
||||
|
||||
interface I3<T>
|
||||
class A3<T> : I3<List<T>>
|
||||
@@ -1,15 +0,0 @@
|
||||
// Same as withoutSource.kt
|
||||
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class SourceAnno
|
||||
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class BinaryAnno
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class RuntimeAnno
|
||||
|
||||
@SourceAnno
|
||||
@BinaryAnno
|
||||
@RuntimeAnno
|
||||
class Test
|
||||
@@ -1,22 +0,0 @@
|
||||
@kotlin.annotation.Retention
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class BinaryAnno
|
||||
|
||||
@kotlin.annotation.Retention
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class RuntimeAnno
|
||||
|
||||
@kotlin.annotation.Retention
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class SourceAnno
|
||||
|
||||
@RuntimeAnno
|
||||
@kotlin.Metadata
|
||||
@SourceAnno
|
||||
@BinaryAnno
|
||||
public final class Test {
|
||||
public method <init>(): void
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Same as withSource.kt
|
||||
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class SourceAnno
|
||||
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class BinaryAnno
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class RuntimeAnno
|
||||
|
||||
@SourceAnno
|
||||
@BinaryAnno
|
||||
@RuntimeAnno
|
||||
class Test
|
||||
@@ -1,21 +0,0 @@
|
||||
@kotlin.annotation.Retention
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class BinaryAnno
|
||||
|
||||
@kotlin.annotation.Retention
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class RuntimeAnno
|
||||
|
||||
@kotlin.annotation.Retention
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class SourceAnno
|
||||
|
||||
@RuntimeAnno
|
||||
@kotlin.Metadata
|
||||
@BinaryAnno
|
||||
public final class Test {
|
||||
public method <init>(): void
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
annotation class Inject
|
||||
|
||||
class Test {
|
||||
@Inject
|
||||
fun myFunc(): String = "Mary"
|
||||
|
||||
@field:Inject
|
||||
val myField: String = "Tom"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
annotation class Inject
|
||||
annotation class Inject2
|
||||
|
||||
@Inject2
|
||||
class Test {
|
||||
@Inject
|
||||
@Inject2
|
||||
fun myFunc(): String = "Mary"
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
annotation class Inject2
|
||||
|
||||
@Inject2
|
||||
class Test
|
||||
@@ -1,8 +0,0 @@
|
||||
annotation class Inject
|
||||
annotation class Inject2
|
||||
|
||||
@Inject
|
||||
class Test {
|
||||
@Inject
|
||||
fun myFunc(): String = "Mary"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
class Test
|
||||
@@ -1,17 +0,0 @@
|
||||
// FQNAME: EnumClass
|
||||
|
||||
// FILE: EnumClass.java
|
||||
enum EnumClass {
|
||||
RED, GREEN, BLUE;
|
||||
|
||||
void someMethod() {
|
||||
System.out.println("Hello, world!")
|
||||
}
|
||||
|
||||
String getStringRepresentation() {
|
||||
return this.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: Anno.kt
|
||||
annotation class Anno
|
||||
@@ -1,11 +0,0 @@
|
||||
final enum EnumClass {
|
||||
public static final EnumClass RED
|
||||
|
||||
public static final EnumClass GREEN
|
||||
|
||||
public static final EnumClass BLUE
|
||||
|
||||
void someMethod()
|
||||
|
||||
java.lang.String getStringRepresentation()
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
// FQNAME: MetaAnnotation
|
||||
|
||||
// FILE: MetaAnnotation.java
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Deprecated
|
||||
@Target({ ElementType.CONSTRUCTOR, ElementType.FIELD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MetaAnnotation {
|
||||
String strValue();
|
||||
}
|
||||
|
||||
// FILE: Anno.kt
|
||||
annotation class Anno
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
@java.lang.Deprecated
|
||||
@java.lang.annotation.Target(value = { CONSTRUCTOR, FIELD })
|
||||
@java.lang.annotation.Retention(value = RUNTIME)
|
||||
public abstract @interface MetaAnnotation {
|
||||
public abstract java.lang.String strValue()
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// FQNAME: Simple
|
||||
|
||||
// FILE: Simple.java
|
||||
@interface Anno {
|
||||
String[] numbers();
|
||||
}
|
||||
|
||||
@interface AnnoValue {
|
||||
String[] value();
|
||||
}
|
||||
|
||||
@KotlinAnnotation(a = "A", b = 5)
|
||||
@Anno(numbers = { "five", "six" })
|
||||
@AnnoValue({ "five", "six" })
|
||||
public abstract class Simple {
|
||||
@Anno(numbers = "seven")
|
||||
@AnnoValue("seven")
|
||||
final String field = "A";
|
||||
|
||||
abstract void voidMethod();
|
||||
|
||||
static {
|
||||
System.out.println("A");
|
||||
}
|
||||
|
||||
{
|
||||
System.out.println("b");
|
||||
}
|
||||
|
||||
protected String strMethod(int param) {
|
||||
return "A";
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: KotlinAnnotation.kt
|
||||
annotation class KotlinAnnotation(val a: String, val b: Int)
|
||||
@@ -1,18 +0,0 @@
|
||||
@KotlinAnnotation(a = "A", b = 5)
|
||||
@Anno(numbers = { "five", "six" })
|
||||
@AnnoValue(value = { "five", "six" })
|
||||
public abstract class Simple {
|
||||
static {}
|
||||
|
||||
{}
|
||||
|
||||
@Anno(numbers = { "seven" })
|
||||
@AnnoValue(value = { "seven" })
|
||||
final java.lang.String field
|
||||
|
||||
abstract void voidMethod()
|
||||
|
||||
protected java.lang.String strMethod(int param)
|
||||
|
||||
public void <init>()
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// FQNAME: WithNested
|
||||
|
||||
// FILE: WithNested.java
|
||||
class WithNested {
|
||||
void myClassFun() {}
|
||||
|
||||
static class NestedClass {
|
||||
void nestedClassFun() {}
|
||||
}
|
||||
|
||||
class InnerClass {
|
||||
void innerClassFun() {}
|
||||
|
||||
class InnerInnerClass {
|
||||
void innerInnerClassFun() {}
|
||||
}
|
||||
}
|
||||
|
||||
interface NestedInterface {
|
||||
void nestedInterfaceFun() {}
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: Anno.kt
|
||||
annotation class Anno
|
||||
@@ -1,27 +0,0 @@
|
||||
class WithNested {
|
||||
void myClassFun()
|
||||
|
||||
static class NestedClass {
|
||||
void nestedClassFun()
|
||||
|
||||
void <init>()
|
||||
}
|
||||
|
||||
class InnerClass {
|
||||
void innerClassFun()
|
||||
|
||||
class InnerInnerClass {
|
||||
void innerInnerClassFun()
|
||||
|
||||
void <init>(WithNested.InnerClass $instance)
|
||||
}
|
||||
|
||||
void <init>(WithNested $instance)
|
||||
}
|
||||
|
||||
static abstract interface NestedInterface {
|
||||
public abstract void nestedInterfaceFun()
|
||||
}
|
||||
|
||||
void <init>()
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
// FQNAME: test.Main
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@MainAnno("A", 5)
|
||||
class Main {
|
||||
@field:XAnno(color = Color.GREEN)
|
||||
val x: String = ""
|
||||
|
||||
@get:YAnno(arrayOf<String>("Mary", "Tom"), intArrayOf(1, 3, 5), arrayOf<Color>(Color.GREEN, Color.RED))
|
||||
val y: String = ""
|
||||
|
||||
@set:ZAnno(String::class, arrayOf(String::class, Long::class, Main::class))
|
||||
var z: String = ""
|
||||
|
||||
// Property annotations are lost here (we don't create Elements (javac API) for the synthetic propertyName$annotations() methods)
|
||||
@MainAnno("B", 6)
|
||||
val zz: String = ""
|
||||
}
|
||||
|
||||
enum class Color {
|
||||
RED, GREEN, BLUE
|
||||
}
|
||||
|
||||
annotation class MainAnno(val a: String, val b: Int)
|
||||
|
||||
annotation class XAnno(val color: Color)
|
||||
|
||||
annotation class YAnno(val names: Array<String>, val ints: IntArray, val colors: Array<Color>)
|
||||
|
||||
annotation class ZAnno(val clazz: KClass<*>, val classes: Array<KClass<*>>)
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
@test.MainAnno(a = "A", b = 5)
|
||||
public final class Main {
|
||||
@test.XAnno(color = GREEN)
|
||||
@org.jetbrains.annotations.NotNull
|
||||
private final java.lang.String x
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
private final java.lang.String y
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
private java.lang.String z
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
private final java.lang.String zz
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final java.lang.String getX()
|
||||
|
||||
@test.YAnno(names = { "Mary", "Tom" }, ints = { 1, 3, 5 }, colors = { GREEN, RED })
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final java.lang.String getY()
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final java.lang.String getZ()
|
||||
|
||||
@test.ZAnno(clazz = java.lang.String.class, classes = { java.lang.String.class, long.class, test.Main.class })
|
||||
public final void setZ(java.lang.String p)
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final java.lang.String getZz()
|
||||
|
||||
public void <init>()
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// FQNAME: EnumClass
|
||||
|
||||
enum class EnumClass {
|
||||
RED, GREEN, BLUE;
|
||||
|
||||
fun someFun() {
|
||||
System.out.println("Hello, world!")
|
||||
}
|
||||
|
||||
fun stringRepresentation() = this.toString()
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
public enum EnumClass {
|
||||
public static final EnumClass RED
|
||||
|
||||
public static final EnumClass GREEN
|
||||
|
||||
public static final EnumClass BLUE
|
||||
|
||||
public final void someFun()
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final java.lang.String stringRepresentation()
|
||||
|
||||
protected void <init>()
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
// FQNAME: Test
|
||||
|
||||
class Test {
|
||||
@kotlin.jvm.Transient
|
||||
val f: String = ""
|
||||
|
||||
// explicitly
|
||||
@org.jetbrains.annotations.NotNull
|
||||
fun a() {}
|
||||
|
||||
@kotlin.jvm.Synchronized
|
||||
fun b() {}
|
||||
|
||||
@kotlin.jvm.JvmOverloads
|
||||
fun c(a: Int = 3, b: String = "") {}
|
||||
|
||||
@java.lang.Deprecated
|
||||
fun d() {}
|
||||
|
||||
@kotlin.Deprecated("")
|
||||
fun e() {}
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
public final class Test {
|
||||
@kotlin.jvm.Transient
|
||||
@org.jetbrains.annotations.NotNull
|
||||
private final transient java.lang.String f
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final java.lang.String getF()
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final void a()
|
||||
|
||||
@kotlin.jvm.Synchronized
|
||||
public final synchronized void b()
|
||||
|
||||
@kotlin.jvm.JvmOverloads
|
||||
public final void c(int a, java.lang.String b)
|
||||
|
||||
@kotlin.jvm.JvmOverloads
|
||||
public final void c(int a)
|
||||
|
||||
@kotlin.jvm.JvmOverloads
|
||||
public final void c()
|
||||
|
||||
@java.lang.Deprecated
|
||||
public final void d()
|
||||
|
||||
@kotlin.Deprecated(message = "")
|
||||
public final void e()
|
||||
|
||||
public void <init>()
|
||||
}
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
// FQNAME: Anno
|
||||
|
||||
@Repeatable
|
||||
@Deprecated("")
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.EXPRESSION)
|
||||
annotation class Anno
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
@kotlin.annotation.Repeatable
|
||||
@kotlin.Deprecated(message = "")
|
||||
@kotlin.annotation.Retention(value = RUNTIME)
|
||||
@kotlin.annotation.Target(allowedTargets = { CLASS, CONSTRUCTOR, EXPRESSION })
|
||||
@java.lang.annotation.Retention(value = RUNTIME)
|
||||
@java.lang.annotation.Target(value = { TYPE, CONSTRUCTOR })
|
||||
public abstract @interface Anno {
|
||||
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
// FQNAME: MyClass
|
||||
|
||||
class MyClass {
|
||||
companion object {
|
||||
val CONST = 2
|
||||
}
|
||||
|
||||
fun myClassFun() {}
|
||||
|
||||
class NestedClass {
|
||||
companion object A {
|
||||
val CONSTA = 3
|
||||
}
|
||||
|
||||
fun nestedClassFun() {}
|
||||
|
||||
class NestedNestedClass {
|
||||
fun nestedNestedClassFun() {}
|
||||
}
|
||||
}
|
||||
|
||||
inner class InnerClass {
|
||||
fun innerClassFun() {}
|
||||
}
|
||||
|
||||
interface InnerInterface {
|
||||
fun innerInterfaceFun()
|
||||
fun innerInterfaceFunWithImpl() = 5
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
public final class MyClass {
|
||||
private static final int CONST
|
||||
|
||||
public static final MyClass.Companion Companion
|
||||
|
||||
public final void myClassFun()
|
||||
|
||||
public void <init>()
|
||||
|
||||
public static final class Companion {
|
||||
public final int getCONST()
|
||||
|
||||
private void <init>()
|
||||
}
|
||||
|
||||
public static final class NestedClass {
|
||||
private static final int CONSTA
|
||||
|
||||
public static final MyClass.NestedClass.A A
|
||||
|
||||
public final void nestedClassFun()
|
||||
|
||||
public void <init>()
|
||||
|
||||
public static final class A {
|
||||
public final int getCONSTA()
|
||||
|
||||
private void <init>()
|
||||
}
|
||||
|
||||
public static final class NestedNestedClass {
|
||||
public final void nestedNestedClassFun()
|
||||
|
||||
public void <init>()
|
||||
}
|
||||
}
|
||||
|
||||
public final class InnerClass {
|
||||
public final void innerClassFun()
|
||||
|
||||
public void <init>()
|
||||
}
|
||||
|
||||
public static abstract interface InnerInterface {
|
||||
public abstract void innerInterfaceFun()
|
||||
|
||||
public default int innerInterfaceFunWithImpl()
|
||||
|
||||
public static final class DefaultImpls {
|
||||
public static int innerInterfaceFunWithImpl(MyClass.InnerInterface $this)
|
||||
|
||||
public void <init>()
|
||||
}
|
||||
}
|
||||
}
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
// FQNAME: MyClass
|
||||
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@Repeatable
|
||||
annotation class Anno(val name: String)
|
||||
|
||||
@Anno("Mary")
|
||||
@Anno("Tom")
|
||||
class MyClass
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
@Anno(name = "Mary")
|
||||
@Anno(name = "Tom")
|
||||
public final class MyClass {
|
||||
public void <init>()
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// FQNAME: test.Simple
|
||||
|
||||
package test
|
||||
|
||||
abstract class Simple(private val prop: String) {
|
||||
protected val anotherProp: Int = 5
|
||||
|
||||
abstract fun strFun(x: Long): String
|
||||
fun voidFun() {}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
public abstract class Simple {
|
||||
private final int anotherProp
|
||||
|
||||
private final java.lang.String prop
|
||||
|
||||
protected final int getAnotherProp()
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public abstract java.lang.String strFun(long x)
|
||||
|
||||
public final void voidFun()
|
||||
|
||||
public void <init>(java.lang.String prop)
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="light-classes" />
|
||||
<orderEntry type="module" module-name="frontend" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -1,82 +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.java.model
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import org.jetbrains.kotlin.java.model.elements.JeAnnotationMirror
|
||||
import org.jetbrains.kotlin.java.model.internal.KotlinAnnotationProxyMaker
|
||||
import org.jetbrains.kotlin.java.model.internal.getAnnotationsWithInherited
|
||||
import javax.lang.model.element.AnnotationMirror
|
||||
import javax.lang.model.element.Element
|
||||
import java.lang.reflect.Array as RArray
|
||||
|
||||
interface JeAnnotationOwner : JeElement {
|
||||
override val psi: PsiModifierListOwner
|
||||
|
||||
override fun getAnnotationMirrors() = psi.getAnnotationsWithInherited().map(::JeAnnotationMirror)
|
||||
|
||||
override fun <A : Annotation> getAnnotation(annotationClass: Class<A>): A? {
|
||||
return getAnnotationsByType(annotationClass, onlyFirst = true).firstOrNull()
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <A : Annotation> getAnnotationsByType(annotationClass: Class<A>): Array<A> {
|
||||
val annotations = getAnnotationsByType(annotationClass, onlyFirst = false)
|
||||
|
||||
return (RArray.newInstance(annotationClass, annotations.size) as Array<A>).apply {
|
||||
annotations.forEachIndexed { i, annotation -> RArray.set(this, i, annotation) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun <A : Annotation> getAnnotationsByType(annotationClass: Class<A>, onlyFirst: Boolean): List<A> {
|
||||
if (!annotationClass.isAnnotation) {
|
||||
throw IllegalArgumentException("Not an annotation class: " + annotationClass)
|
||||
}
|
||||
|
||||
val annotationFqName = annotationClass.canonicalName
|
||||
|
||||
val allAnnotations = psi.getAnnotationsWithInherited().filter { it.qualifiedName == annotationFqName }
|
||||
if (allAnnotations.isEmpty()) return emptyList()
|
||||
|
||||
val annotations = if (onlyFirst) listOf(allAnnotations.first()) else allAnnotations
|
||||
|
||||
val annotationDeclarations = annotations.map { it to it.nameReferenceElement?.resolve() as? PsiClass }.filter { it.second != null }
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val annotationProxies = annotationDeclarations.map {
|
||||
val (annotation, annotationDeclaration) = it
|
||||
KotlinAnnotationProxyMaker(annotation, annotationDeclaration!!, annotationClass).generate() as? A
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return annotationProxies as List<A>
|
||||
}
|
||||
}
|
||||
|
||||
interface JeNoAnnotations : Element {
|
||||
override fun getAnnotationMirrors() = emptyList<AnnotationMirror>()
|
||||
|
||||
override fun <A : Annotation> getAnnotation(annotationClass: Class<A>?): Nothing? {
|
||||
return null
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <A : Annotation?> getAnnotationsByType(annotationType: Class<A>): Array<A> {
|
||||
return RArray.newInstance(annotationType, 0) as Array<A>
|
||||
}
|
||||
}
|
||||
@@ -1,31 +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.java.model
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.java.model.elements.*
|
||||
|
||||
// to extension function?
|
||||
fun PsiElement?.toJeElement(): JeElement? = when (this) {
|
||||
null -> null
|
||||
is PsiPackage -> JePackageElement(this)
|
||||
is PsiClass -> JeTypeElement(this)
|
||||
is PsiVariable -> JeVariableElement(this)
|
||||
is PsiMethod -> JeMethodExecutableElement(this)
|
||||
is PsiClassInitializer -> JeClassInitializerExecutableElement(this)
|
||||
else -> null
|
||||
}
|
||||
@@ -1,52 +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.java.model
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.java.model.internal.JeElementRegistry
|
||||
import org.jetbrains.kotlin.java.model.util.toDisposable
|
||||
import javax.lang.model.element.Element
|
||||
|
||||
interface JePsiElementOwner {
|
||||
val psi: PsiElement
|
||||
}
|
||||
|
||||
interface JeElement : Element, JePsiElementOwner
|
||||
|
||||
abstract class JeDisposablePsiElementOwner<out T : PsiElement>(element: T) : JePsiElementOwner, Disposable {
|
||||
private val disposablePsi = element.toDisposable()
|
||||
|
||||
init {
|
||||
@Suppress("LeakingThis")
|
||||
ServiceManager.getService(element.project, JeElementRegistry::class.java).register(this)
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
disposablePsi.dispose()
|
||||
}
|
||||
|
||||
override val psi: T
|
||||
get() = disposablePsi()
|
||||
|
||||
val psiManager: PsiManager
|
||||
get() = disposablePsi().manager
|
||||
}
|
||||
|
||||
abstract class JeAbstractElement<out T : PsiElement>(element: T) : JeDisposablePsiElementOwner<T>(element), JeElement, Disposable
|
||||
-26
@@ -1,26 +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.java.model
|
||||
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import org.jetbrains.kotlin.java.model.internal.getJavaModifiers
|
||||
import javax.lang.model.element.Element
|
||||
|
||||
interface JeModifierListOwner : Element {
|
||||
val psi: PsiModifierListOwner
|
||||
override fun getModifiers() = psi.getJavaModifiers()
|
||||
}
|
||||
@@ -1,33 +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.java.model
|
||||
|
||||
import javax.lang.model.element.Name
|
||||
|
||||
fun JeName(name: String?) = name?.let(::JeName) ?: JeName.EMPTY
|
||||
|
||||
class JeName(val name: String) : Name, CharSequence by name {
|
||||
override fun contentEquals(cs: CharSequence?) = cs?.toString() == name
|
||||
|
||||
override fun toString() = name
|
||||
|
||||
companion object {
|
||||
val EMPTY = JeName("")
|
||||
val INIT = JeName("<init>")
|
||||
val CLINIT = JeName("<clinit>")
|
||||
}
|
||||
}
|
||||
-120
@@ -1,120 +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.java.model.elements
|
||||
|
||||
import org.jetbrains.kotlin.java.model.JeElement
|
||||
import org.jetbrains.kotlin.java.model.types.*
|
||||
import javax.lang.model.element.AnnotationMirror
|
||||
import javax.lang.model.element.AnnotationValue
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class DefaultJeElementRenderer : JeElementRenderer {
|
||||
override fun render(element: JeElement): String {
|
||||
return when (element) {
|
||||
is JePackageElement -> buildString {
|
||||
appendln("package ${element.qualifiedName}").appendln()
|
||||
element.enclosedElements.forEach { appendln(render(it).withMargin()).appendln() }
|
||||
}
|
||||
is JeTypeElement -> buildString {
|
||||
val classType = when (element.kind) {
|
||||
ElementKind.ANNOTATION_TYPE -> "@interface"
|
||||
ElementKind.INTERFACE -> "interface"
|
||||
ElementKind.ENUM -> "enum"
|
||||
ElementKind.CLASS -> "class"
|
||||
else -> throw IllegalStateException("Invalid class type: ${element.kind}")
|
||||
}
|
||||
appendln(renderModifiers(element) + classType + ' ' + element.simpleName + " {")
|
||||
appendln(element.enclosedElements.joinToString(LINE_SEPARATOR.repeat(2)) { render(it).withMargin() })
|
||||
append("}")
|
||||
}
|
||||
is JeVariableElement -> renderModifiers(element) + renderType(element.asType()) + " " + element.simpleName
|
||||
is JeMethodExecutableElement -> buildString {
|
||||
append(renderModifiers(element) + renderType(element.returnType, noneAsVoid = true) + " " + element.simpleName)
|
||||
append(element.parameters.joinToString(prefix = "(", postfix = ")") { renderType(it.asType()) + " " + it.simpleName })
|
||||
}
|
||||
is JeClassInitializerExecutableElement -> renderModifiers(element) + "{}"
|
||||
else -> throw IllegalArgumentException("Unsupported element: $element")
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderType(type: TypeMirror, noneAsVoid: Boolean = false): String {
|
||||
return when (type) {
|
||||
is JeNullType -> "null"
|
||||
is JeVoidType -> "void"
|
||||
is JeErrorType -> "<ERROR>"
|
||||
is JeNoneType -> if (noneAsVoid) "void" else throw IllegalArgumentException("Unexpected 'none' type")
|
||||
is JePsiType -> type.psiType.getCanonicalText(false)
|
||||
else -> throw IllegalArgumentException("Unsupported type: $type")
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderModifiers(element: Element): String {
|
||||
val renderedAnnotations = renderAnnotations(element)
|
||||
val modifiers = element.modifiers
|
||||
|
||||
return if (modifiers.isEmpty())
|
||||
renderedAnnotations
|
||||
else
|
||||
renderedAnnotations + modifiers.joinToString(" ", postfix = " ") { it.name.toLowerCase() }
|
||||
}
|
||||
|
||||
private fun renderAnnotations(element: Element): String {
|
||||
val annotations = element.annotationMirrors
|
||||
if (annotations.isEmpty()) return ""
|
||||
return annotations.joinToString(LINE_SEPARATOR, postfix = LINE_SEPARATOR) { renderAnnotation(it) }
|
||||
}
|
||||
|
||||
private fun renderAnnotation(anno: AnnotationMirror): String {
|
||||
val name = "@" + renderType(anno.annotationType)
|
||||
val args = anno.elementValues
|
||||
if (args.isEmpty()) return name
|
||||
|
||||
return name + args
|
||||
.map { it.key.simpleName.toString() + " = " + renderAnnotationValue(it.value) }
|
||||
.joinToString(prefix = "(", postfix = ")")
|
||||
}
|
||||
|
||||
private fun renderAnnotationValue(av: AnnotationValue): String {
|
||||
return when (av) {
|
||||
is JeAnnotationAnnotationValue -> renderAnnotation(av.value)
|
||||
is JeArrayAnnotationValue -> av.value.joinToString(prefix = "{ ", postfix = " }") { renderAnnotationValue(it) }
|
||||
is JeSingletonArrayAnnotationValue -> av.value.joinToString(prefix = "{ ", postfix = " }") { renderAnnotationValue(it) }
|
||||
is JeEnumValueAnnotationValue -> av.value.simpleName.toString()
|
||||
is JeErrorAnnotationValue -> "<ERROR>"
|
||||
is JeExpressionAnnotationValue, is JeLiteralAnnotationValue -> av.value?.let { renderConstantValue(it) } ?: "null"
|
||||
is JeTypeAnnotationValue -> renderType(av.value) + ".class"
|
||||
else -> throw IllegalArgumentException("Unsupported annotation value: $av")
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderConstantValue(value: Any?): String {
|
||||
return when (value) {
|
||||
null -> "null"
|
||||
is String -> "\"" + value.replace("\"", "\\\"") + "\""
|
||||
else -> value.toString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.withMargin() = lines().joinToString(LINE_SEPARATOR) { MARGIN + it }
|
||||
|
||||
private companion object {
|
||||
val MARGIN = " "
|
||||
val LINE_SEPARATOR: String = System.getProperty("line.separator")
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +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.java.model.elements
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.java.model.JeDisposablePsiElementOwner
|
||||
import org.jetbrains.kotlin.java.model.internal.getTypeWithTypeParameters
|
||||
import org.jetbrains.kotlin.java.model.types.JeDeclaredErrorType
|
||||
import org.jetbrains.kotlin.java.model.types.JeDeclaredType
|
||||
import javax.lang.model.element.AnnotationMirror
|
||||
import javax.lang.model.element.AnnotationValue
|
||||
import javax.lang.model.element.ExecutableElement
|
||||
import javax.lang.model.type.DeclaredType
|
||||
|
||||
class JeAnnotationMirror(psi: PsiAnnotation) : JeDisposablePsiElementOwner<PsiAnnotation>(psi), AnnotationMirror {
|
||||
override fun getAnnotationType(): DeclaredType? {
|
||||
val psiClass = resolveAnnotationClass() ?: return JeDeclaredErrorType
|
||||
return JeDeclaredType(psiClass.getTypeWithTypeParameters(), psiClass)
|
||||
}
|
||||
|
||||
override fun getElementValues(): Map<out ExecutableElement, AnnotationValue> = getElementValues(false)
|
||||
|
||||
fun getAllElementValues(): Map<out ExecutableElement, AnnotationValue> = getElementValues(true)
|
||||
|
||||
private fun getElementValues(withDefaults: Boolean): Map<out ExecutableElement, AnnotationValue> {
|
||||
val annotationClass = resolveAnnotationClass() ?: return emptyMap()
|
||||
|
||||
return mutableMapOf<ExecutableElement, AnnotationValue>().apply {
|
||||
for (method in annotationClass.methods) {
|
||||
method as? PsiAnnotationMethod ?: continue
|
||||
val returnType = method.returnType ?: continue
|
||||
|
||||
val attributeValue = psi.findDeclaredAttributeValue(method.name)
|
||||
?: (if (withDefaults) method.defaultValue else null)
|
||||
?: continue
|
||||
|
||||
val annotationValue = when {
|
||||
returnType is PsiArrayType && attributeValue !is PsiArrayInitializerMemberValue ->
|
||||
JeSingletonArrayAnnotationValue(attributeValue)
|
||||
else -> JeAnnotationValue(attributeValue)
|
||||
}
|
||||
|
||||
put(JeMethodExecutableElement(method), annotationValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveAnnotationClass() = psi.nameReferenceElement?.resolve() as? PsiClass
|
||||
}
|
||||
-106
@@ -1,106 +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.java.model.elements
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.java.model.JeDisposablePsiElementOwner
|
||||
import org.jetbrains.kotlin.java.model.internal.calcConstantValue
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import java.util.*
|
||||
import javax.lang.model.element.AnnotationValue
|
||||
import javax.lang.model.element.AnnotationValueVisitor
|
||||
|
||||
fun JeAnnotationValue(psi: PsiAnnotationMemberValue): AnnotationValue {
|
||||
val original = psi.originalElement
|
||||
val annotationValue = when (original) {
|
||||
is PsiLiteral -> JeLiteralAnnotationValue(original)
|
||||
is PsiAnnotation -> JeAnnotationAnnotationValue(original)
|
||||
is PsiArrayInitializerMemberValue -> JeArrayAnnotationValue(original)
|
||||
is PsiClassObjectAccessExpression -> JeTypeAnnotationValue(original)
|
||||
is PsiReferenceExpression -> {
|
||||
val element = original.resolve()
|
||||
if (element is PsiEnumConstant) {
|
||||
JeEnumValueAnnotationValue(element)
|
||||
}
|
||||
else if (element is PsiField && element.hasInitializer()) {
|
||||
JeAnnotationValue(element.initializer ?: error("Field should have an initializer"))
|
||||
}
|
||||
else {
|
||||
JeErrorAnnotationValue(psi)
|
||||
}
|
||||
}
|
||||
is PsiExpression -> JeExpressionAnnotationValue(original)
|
||||
else -> throw AssertionError("Unsupported annotation element value: $psi (original = $original)")
|
||||
}
|
||||
return annotationValue
|
||||
}
|
||||
|
||||
class JeAnnotationAnnotationValue(psi: PsiAnnotation) : JeDisposablePsiElementOwner<PsiAnnotation>(psi), AnnotationValue {
|
||||
override fun getValue() = JeAnnotationMirror(psi)
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitAnnotation(value, p)
|
||||
}
|
||||
|
||||
class JeEnumValueAnnotationValue(psi: PsiEnumConstant) : JeDisposablePsiElementOwner<PsiEnumConstant>(psi), AnnotationValue {
|
||||
override fun getValue() = JeVariableElement(psi)
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitEnumConstant(value, p)
|
||||
}
|
||||
|
||||
class JeTypeAnnotationValue(psi: PsiClassObjectAccessExpression) : JeDisposablePsiElementOwner<PsiClassObjectAccessExpression>(psi), AnnotationValue {
|
||||
override fun getValue() = psi.operand.type.toJeType(psi.manager)
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitType(value, p)
|
||||
}
|
||||
|
||||
abstract class JePrimitiveAnnotationValue<out T : PsiElement>(psi: T) : JeDisposablePsiElementOwner<T>(psi), AnnotationValue {
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P): R {
|
||||
val value = this.value
|
||||
return when (value) {
|
||||
is String -> v.visitString(value, p)
|
||||
is Int -> v.visitInt(value, p)
|
||||
is Boolean -> v.visitBoolean(value, p)
|
||||
is Char -> v.visitChar(value, p)
|
||||
is Byte -> v.visitByte(value, p)
|
||||
is Short -> v.visitShort(value, p)
|
||||
is Long -> v.visitLong(value, p)
|
||||
is Float -> v.visitFloat(value, p)
|
||||
is Double -> v.visitDouble(value, p)
|
||||
else -> throw AssertionError("Bad annotation element value: $value")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JeLiteralAnnotationValue(psi: PsiLiteral) : JePrimitiveAnnotationValue<PsiLiteral>(psi) {
|
||||
override fun getValue() = psi.value
|
||||
}
|
||||
|
||||
class JeExpressionAnnotationValue(psi: PsiExpression) : JePrimitiveAnnotationValue<PsiExpression>(psi) {
|
||||
override fun getValue() = psi.calcConstantValue()
|
||||
}
|
||||
|
||||
class JeArrayAnnotationValue(psi: PsiArrayInitializerMemberValue) : JeDisposablePsiElementOwner<PsiArrayInitializerMemberValue>(psi), AnnotationValue {
|
||||
override fun getValue() = psi.initializers.map(::JeAnnotationValue)
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitArray(value, p)
|
||||
}
|
||||
|
||||
class JeSingletonArrayAnnotationValue(psi: PsiAnnotationMemberValue) : JeDisposablePsiElementOwner<PsiAnnotationMemberValue>(psi), AnnotationValue {
|
||||
override fun getValue(): List<AnnotationValue> = Collections.singletonList(JeAnnotationValue(psi))
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitArray(value, p)
|
||||
}
|
||||
|
||||
class JeErrorAnnotationValue(psi: PsiElement) : JeDisposablePsiElementOwner<PsiElement>(psi), AnnotationValue {
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitString(psi.text, p)
|
||||
override fun getValue() = null
|
||||
}
|
||||
-71
@@ -1,71 +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.java.model.elements
|
||||
|
||||
import com.intellij.psi.PsiClassInitializer
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.internal.isStatic
|
||||
import org.jetbrains.kotlin.java.model.types.JeClassInitializerExecutableTypeMirror
|
||||
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
||||
import javax.lang.model.element.*
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class JeClassInitializerExecutableElement(
|
||||
psi: PsiClassInitializer
|
||||
) : JeAbstractElement<PsiClassInitializer>(psi), ExecutableElement, JeNoAnnotations, JeModifierListOwner {
|
||||
val isStaticInitializer = psi.isStatic
|
||||
|
||||
override fun getEnclosingElement() = psi.containingClass?.let(::JeTypeElement)
|
||||
|
||||
override fun getSimpleName() = if (isStaticInitializer) JeName.CLINIT else JeName.EMPTY
|
||||
|
||||
override fun getThrownTypes() = emptyList<TypeMirror>()
|
||||
|
||||
override fun getTypeParameters() = emptyList<TypeParameterElement>()
|
||||
|
||||
override fun getParameters() = emptyList<VariableElement>()
|
||||
|
||||
override fun getDefaultValue() = null
|
||||
|
||||
override fun getReturnType() = JeNoneType
|
||||
|
||||
override fun getReceiverType() = JeNoneType
|
||||
|
||||
override fun isVarArgs() = false
|
||||
|
||||
override fun isDefault() = false
|
||||
|
||||
override fun getKind() = if (isStaticInitializer) ElementKind.STATIC_INIT else ElementKind.INSTANCE_INIT
|
||||
|
||||
override fun asType() = JeClassInitializerExecutableTypeMirror(psi)
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitExecutable(this, p)
|
||||
|
||||
override fun getEnclosedElements() = emptyList<Element>()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || other::class.java != this::class.java) return false
|
||||
|
||||
return psi == (other as JeClassInitializerExecutableElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.containingClass?.qualifiedName
|
||||
?.let { it + if (isStaticInitializer) ".<clinit>" else ".<instinit>" } ?: "<unnamed>"
|
||||
}
|
||||
-23
@@ -1,23 +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.java.model.elements
|
||||
|
||||
import org.jetbrains.kotlin.java.model.JeElement
|
||||
|
||||
interface JeElementRenderer {
|
||||
fun render(element: JeElement): String
|
||||
}
|
||||
-97
@@ -1,97 +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.java.model.elements
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.internal.getTypeWithTypeParameters
|
||||
import org.jetbrains.kotlin.java.model.internal.isStatic
|
||||
import org.jetbrains.kotlin.java.model.types.JeMethodExecutableTypeMirror
|
||||
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.*
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class JeMethodExecutableElement(psi: PsiMethod) : JeAbstractElement<PsiMethod>(psi), ExecutableElement, JeModifierListOwner, JeAnnotationOwner {
|
||||
override fun getEnclosingElement() = psi.containingClass?.let(::JeTypeElement)
|
||||
|
||||
override fun getSimpleName(): JeName {
|
||||
if (psi.isConstructor) return JeName.INIT
|
||||
return JeName(psi.name)
|
||||
}
|
||||
|
||||
override fun getThrownTypes() = psi.throwsList.referencedTypes.map { it.toJeType(psi.manager) }
|
||||
|
||||
override fun getTypeParameters() = psi.typeParameters.map { JeTypeParameterElement(it, this) }
|
||||
|
||||
override fun getParameters() = psi.parameterList.parameters.map(::JeVariableElement)
|
||||
|
||||
override fun getDefaultValue(): AnnotationValue? {
|
||||
val annotationMethod = psi as? PsiAnnotationMethod ?: return null
|
||||
val defaultValue = annotationMethod.defaultValue ?: return null
|
||||
return JeAnnotationValue(defaultValue)
|
||||
}
|
||||
|
||||
override fun getReturnType() = psi.returnType?.let { it.toJeType(psi.manager) } ?: JeNoneType
|
||||
|
||||
override fun getReceiverType() = psi.getReceiverTypeMirror()
|
||||
|
||||
override fun isVarArgs() = psi.isVarArgs
|
||||
|
||||
override fun isDefault() = psi.hasModifierProperty(PsiModifier.DEFAULT)
|
||||
|
||||
override fun getKind() = when {
|
||||
psi.isConstructor -> ElementKind.CONSTRUCTOR
|
||||
else -> ElementKind.METHOD
|
||||
}
|
||||
|
||||
override fun asType() = JeMethodExecutableTypeMirror(psi)
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitExecutable(this, p)
|
||||
|
||||
override fun getEnclosedElements() = emptyList<Element>()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || other::class.java != this::class.java) return false
|
||||
|
||||
return psi == (other as JeMethodExecutableElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.name
|
||||
}
|
||||
|
||||
fun PsiMethod.getReceiverTypeMirror(): TypeMirror {
|
||||
if (isStatic) return JeNoneType
|
||||
|
||||
if (isConstructor) {
|
||||
val containingClass = containingClass
|
||||
if (containingClass != null && !containingClass.isStatic) {
|
||||
containingClass.containingClass?.let {
|
||||
return it.getTypeWithTypeParameters().toJeType(manager)
|
||||
}
|
||||
}
|
||||
|
||||
return JeNoneType
|
||||
}
|
||||
|
||||
val containingClass = containingClass ?: return JeNoneType
|
||||
return containingClass.getTypeWithTypeParameters().toJeType(manager)
|
||||
|
||||
}
|
||||
-53
@@ -1,53 +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.java.model.elements
|
||||
|
||||
import com.intellij.psi.PsiPackage
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.types.JePackageTypeMirror
|
||||
import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.element.ElementVisitor
|
||||
import javax.lang.model.element.PackageElement
|
||||
|
||||
class JePackageElement(psi: PsiPackage) : JeAbstractElement<PsiPackage>(psi), PackageElement, JeModifierListOwner, JeNoAnnotations {
|
||||
override fun getEnclosingElement() = null
|
||||
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
|
||||
override fun getKind() = ElementKind.PACKAGE
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitPackage(this, p)
|
||||
|
||||
override fun isUnnamed() = psi.name.isNullOrEmpty()
|
||||
|
||||
override fun getQualifiedName() = JeName(psi.qualifiedName)
|
||||
|
||||
override fun getEnclosedElements() = psi.classes.map(::JeTypeElement)
|
||||
|
||||
override fun asType() = JePackageTypeMirror
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || other::class.java != this::class.java) return false
|
||||
|
||||
return psi == (other as JePackageElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.qualifiedName
|
||||
}
|
||||
-142
@@ -1,142 +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.java.model.elements
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType
|
||||
import com.intellij.psi.util.ClassUtil
|
||||
import org.jetbrains.kotlin.asJava.elements.LightParameter
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.internal.DefaultConstructorPsiMethod
|
||||
import org.jetbrains.kotlin.java.model.internal.getTypeWithTypeParameters
|
||||
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.*
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class JeTypeElement(psi: PsiClass) : JeAbstractElement<PsiClass>(psi), TypeElement, JeAnnotationOwner, JeModifierListOwner {
|
||||
override fun getEnclosingElement(): Element? {
|
||||
psi.containingClass?.let { return JeTypeElement(it) }
|
||||
val javaFile = psi.containingFile as? PsiJavaFile ?: return null
|
||||
return JavaPsiFacade.getInstance(psi.project).findPackage(javaFile.packageName)?.let(::JePackageElement)
|
||||
}
|
||||
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
|
||||
override fun getQualifiedName() = JeName(psi.qualifiedName)
|
||||
|
||||
private fun getSuperType(superTypes: Array<PsiClassType>, superClass: PsiClass): PsiClassType {
|
||||
return superTypes.firstOrNull { it is PsiClassReferenceType && it.resolve() == superClass }
|
||||
?: superClass.getTypeWithTypeParameters()
|
||||
}
|
||||
|
||||
override fun getSuperclass(): TypeMirror {
|
||||
val superClass = psi.superClass ?: return JeNoneType
|
||||
val psiType = getSuperType(psi.superTypes, superClass)
|
||||
return psiType.toJeType(psi.manager)
|
||||
}
|
||||
|
||||
override fun getInterfaces(): List<TypeMirror> {
|
||||
val superTypes = psi.superTypes
|
||||
val interfaces = mutableListOf<TypeMirror>()
|
||||
|
||||
for (intf in psi.interfaces) {
|
||||
val psiType = getSuperType(superTypes, intf)
|
||||
interfaces += psiType.toJeType(psi.manager)
|
||||
}
|
||||
|
||||
return interfaces
|
||||
}
|
||||
|
||||
override fun getTypeParameters() = psi.typeParameters.map { JeTypeParameterElement(it, this) }
|
||||
|
||||
override fun getNestingKind() = when {
|
||||
ClassUtil.isTopLevelClass(psi) -> NestingKind.TOP_LEVEL
|
||||
psi.parent is PsiClass -> NestingKind.MEMBER
|
||||
psi is PsiAnonymousClass -> NestingKind.ANONYMOUS
|
||||
else -> NestingKind.LOCAL
|
||||
}
|
||||
|
||||
override fun getEnclosedElements(): List<JeElement> {
|
||||
val declarations = mutableListOf<JeElement>()
|
||||
psi.initializers.forEach { declarations += JeClassInitializerExecutableElement(it) }
|
||||
psi.fields.forEach { declarations += JeVariableElement(it) }
|
||||
psi.methods.forEach { declarations += JeMethodExecutableElement(it) }
|
||||
psi.innerClasses.forEach { declarations += JeTypeElement(it) }
|
||||
|
||||
// Add default constructor if possible
|
||||
if (!psi.isInterface && !psi.isAnnotationType && psi.constructors.isEmpty()) {
|
||||
val superClass = psi.superClass
|
||||
val canHaveDefaultConstructor = superClass == null || run {
|
||||
val constructors = superClass.constructors
|
||||
constructors.isEmpty() || constructors.any {
|
||||
(it.hasModifierProperty(PsiModifier.PUBLIC) || it.hasModifierProperty(PsiModifier.PROTECTED) || run {
|
||||
it.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && psi.packageName == superClass.packageName
|
||||
}) && it.parameterList.parametersCount == 0
|
||||
}
|
||||
}
|
||||
|
||||
if (canHaveDefaultConstructor) {
|
||||
declarations += JeMethodExecutableElement(DefaultConstructorPsiMethod(psi, psi.language).apply {
|
||||
val containingClass = psi.containingClass
|
||||
if (containingClass != null && !psi.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
addParameter(LightParameter("\$instance", containingClass.getTypeWithTypeParameters(), this, psi.language))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return declarations
|
||||
}
|
||||
|
||||
private val PsiClass.packageName: String
|
||||
get() = (containingFile as? PsiJavaFile)?.packageName ?: ""
|
||||
|
||||
fun getAllMembers(): List<Element> {
|
||||
val declarations = mutableListOf<Element>()
|
||||
psi.allFields.forEach { declarations += JeVariableElement(it) }
|
||||
psi.allMethods.forEach {
|
||||
if (it.isConstructor && it.containingClass != this@JeTypeElement.psi) return@forEach
|
||||
declarations += JeMethodExecutableElement(it)
|
||||
}
|
||||
psi.allInnerClasses.forEach { declarations += JeTypeElement(it) }
|
||||
psi.initializers.forEach { declarations += JeClassInitializerExecutableElement(it) }
|
||||
return declarations
|
||||
}
|
||||
|
||||
override fun getKind() = when {
|
||||
psi.isEnum -> ElementKind.ENUM
|
||||
psi.isAnnotationType -> ElementKind.ANNOTATION_TYPE
|
||||
psi.isInterface -> ElementKind.INTERFACE
|
||||
else -> ElementKind.CLASS
|
||||
}
|
||||
|
||||
override fun asType() = psi.getTypeWithTypeParameters().toJeType(psi.manager)
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitType(this, p)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || other::class.java != this::class.java) return false
|
||||
|
||||
return psi == (other as JeTypeElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.qualifiedName ?: "<anonymous> extends " + psi.superClass?.qualifiedName ?: "<unnamed>"
|
||||
}
|
||||
-58
@@ -1,58 +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.java.model.elements
|
||||
|
||||
import com.intellij.psi.PsiTypeParameter
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.internal.getTypeWithTypeParameters
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.element.ElementVisitor
|
||||
import javax.lang.model.element.TypeParameterElement
|
||||
|
||||
class JeTypeParameterElement(
|
||||
psi: PsiTypeParameter,
|
||||
val parent: JeElement?
|
||||
) : JeAbstractElement<PsiTypeParameter>(psi), TypeParameterElement, JeAnnotationOwner, JeModifierListOwner {
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
|
||||
override fun getEnclosingElement() = parent
|
||||
|
||||
override fun getKind() = ElementKind.TYPE_PARAMETER
|
||||
|
||||
override fun asType() = psi.getTypeWithTypeParameters().toJeType(psi.manager)
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitTypeParameter(this, p)
|
||||
|
||||
override fun getEnclosedElements() = emptyList<Element>()
|
||||
|
||||
override fun getBounds() = psi.superTypes.map { it.toJeType(psi.manager) }
|
||||
|
||||
override fun getGenericElement() = parent
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || other::class.java != this::class.java) return false
|
||||
|
||||
return psi == (other as JeTypeParameterElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.name ?: "T"
|
||||
}
|
||||
-67
@@ -1,67 +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.java.model.elements
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.internal.calcConstantValue
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.element.ElementVisitor
|
||||
import javax.lang.model.element.VariableElement
|
||||
|
||||
class JeVariableElement(psi: PsiVariable) : JeAbstractElement<PsiVariable>(psi), VariableElement, JeModifierListOwner, JeAnnotationOwner {
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
|
||||
override fun getEnclosingElement(): JeElement? {
|
||||
val psi = psi
|
||||
|
||||
if (psi is PsiParameter) {
|
||||
(psi.declarationScope as? PsiMethod)?.let { return JeMethodExecutableElement(it) }
|
||||
}
|
||||
|
||||
val containingClass = (psi as? PsiMember)?.containingClass ?: PsiTreeUtil.getParentOfType(psi, PsiClass::class.java)
|
||||
return containingClass?.let(::JeTypeElement)
|
||||
}
|
||||
|
||||
override fun getConstantValue() = psi.initializer?.calcConstantValue()
|
||||
|
||||
override fun getKind() = when (psi) {
|
||||
is PsiField -> ElementKind.FIELD
|
||||
is PsiParameter -> ElementKind.PARAMETER
|
||||
else -> ElementKind.LOCAL_VARIABLE
|
||||
}
|
||||
|
||||
override fun asType() = psi.type.toJeType(psi.manager)
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitVariable(this, p)
|
||||
|
||||
override fun getEnclosedElements() = emptyList<Element>()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || other::class.java != this::class.java) return false
|
||||
|
||||
return psi == (other as JeVariableElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.name ?: "<unnamed variable>"
|
||||
}
|
||||
-54
@@ -1,54 +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.java.model.internal;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiType;
|
||||
import sun.reflect.annotation.EnumConstantNotPresentExceptionProxy;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class AnnotationUtil {
|
||||
public static final Map<PsiType, Class<?>> ARRAY_TYPES_MAP;
|
||||
|
||||
static {
|
||||
Map<PsiType, Class<?>> classes = new HashMap<PsiType, Class<?>>();
|
||||
|
||||
classes.put(PsiType.BYTE, byte.class);
|
||||
classes.put(PsiType.SHORT, short.class);
|
||||
classes.put(PsiType.INT, int.class);
|
||||
classes.put(PsiType.CHAR, char.class);
|
||||
classes.put(PsiType.BOOLEAN, boolean.class);
|
||||
classes.put(PsiType.LONG, long.class);
|
||||
classes.put(PsiType.FLOAT, float.class);
|
||||
classes.put(PsiType.DOUBLE, double.class);
|
||||
|
||||
ARRAY_TYPES_MAP = Collections.unmodifiableMap(classes);
|
||||
}
|
||||
|
||||
public static Object createEnumValue(Class<?> enumClass, String name) {
|
||||
try {
|
||||
return Enum.valueOf((Class)enumClass, name);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
//noinspection unchecked
|
||||
return new EnumConstantNotPresentExceptionProxy((Class<Enum<?>>) enumClass, name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
-38
@@ -1,38 +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.java.model.internal
|
||||
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiModifier.*
|
||||
import com.intellij.psi.impl.light.LightMethodBuilder
|
||||
|
||||
internal class DefaultConstructorPsiMethod(
|
||||
clazz: PsiClass,
|
||||
language: Language
|
||||
) : LightMethodBuilder(clazz, language) {
|
||||
init {
|
||||
val modifier = when {
|
||||
clazz.hasModifierProperty(PUBLIC) -> PUBLIC
|
||||
clazz.hasModifierProperty(PRIVATE) -> PRIVATE
|
||||
clazz.hasModifierProperty(PROTECTED) -> PROTECTED
|
||||
else -> PACKAGE_LOCAL
|
||||
}
|
||||
setModifiers(modifier)
|
||||
isConstructor = true
|
||||
}
|
||||
}
|
||||
-42
@@ -1,42 +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.java.model.internal
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
|
||||
/*
|
||||
Some annotation processors (I'm looking at you, Data Binding)
|
||||
have a habit to cache Element or TypeMirror instances into static fields.
|
||||
Because almost every JeElement or JeTypeMirror is dependent on some PsiElement, and PsiElements are dependent on PsiProject,
|
||||
the entire project will not be gc'ed normally.
|
||||
JeElementRegistry allows us to remove all Psi*-references from our wrapper Element and TypeMirror instances.
|
||||
|
||||
So this class basically remembers all instances created by kapt, and disposes all of them as the Annotation Processing is complete.
|
||||
*/
|
||||
class JeElementRegistry : Disposable {
|
||||
private val list = mutableListOf<Disposable>()
|
||||
|
||||
fun register(obj: Disposable) {
|
||||
list += obj
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
val list = this.list
|
||||
list.forEach { it.dispose() }
|
||||
this.list.clear()
|
||||
}
|
||||
}
|
||||
-211
@@ -1,211 +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.java.model.internal
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import sun.reflect.annotation.AnnotationParser
|
||||
import sun.reflect.annotation.ExceptionProxy
|
||||
import java.io.ObjectInputStream
|
||||
import java.lang.reflect.Array
|
||||
import java.lang.reflect.Method
|
||||
import java.util.*
|
||||
import javax.lang.model.type.MirroredTypeException
|
||||
import javax.lang.model.type.MirroredTypesException
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class KotlinAnnotationProxyMaker(val annotation: PsiAnnotation, val annotationClass: PsiClass, val annotationType: Class<out Annotation>) {
|
||||
fun generate(): Annotation {
|
||||
return AnnotationParser.annotationForMap(annotationType, getAllValuesForParser(getAllPsiValues()))
|
||||
}
|
||||
|
||||
private data class AnnotationParameterData(
|
||||
val method: PsiAnnotationMethod,
|
||||
val value: PsiAnnotationMemberValue,
|
||||
val jMethod: Method)
|
||||
|
||||
private fun getAllPsiValues(): List<AnnotationParameterData> {
|
||||
val values = mutableListOf<AnnotationParameterData>()
|
||||
for (method in annotationClass.methods) {
|
||||
if (method !is PsiAnnotationMethod) continue
|
||||
if (method.returnType == null) continue
|
||||
|
||||
val jMethod = try { annotationType.getMethod(method.name) } catch (e : NoSuchMethodException) { continue }
|
||||
|
||||
val value = annotation.findAttributeValue(method.name) ?: method.defaultValue ?: continue
|
||||
values += AnnotationParameterData(method, value, jMethod)
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
private fun getAllValuesForParser(values: List<AnnotationParameterData>): Map<String, Any?> {
|
||||
val parserValues = mutableMapOf<String, Any?>()
|
||||
val evaluator = JavaPsiFacade.getInstance(annotation.project).constantEvaluationHelper
|
||||
for ((method, value, jMethod) in values) {
|
||||
val jReturnType = jMethod.returnType ?: unexpectedType("no return type for ${jMethod.name}")
|
||||
parserValues.put(method.name, getConstantValue(value, method.returnType!!, jReturnType, evaluator))
|
||||
}
|
||||
return parserValues
|
||||
}
|
||||
}
|
||||
|
||||
private val JAVA_LANG_STRING = "java.lang.String"
|
||||
|
||||
private fun getConstantValue(
|
||||
psiValue: PsiAnnotationMemberValue,
|
||||
returnType: PsiType,
|
||||
jReturnType: Class<*>,
|
||||
evaluator: PsiConstantEvaluationHelper
|
||||
): Any? {
|
||||
val manager = psiValue.manager
|
||||
|
||||
when {
|
||||
returnType == PsiType.NULL || returnType == PsiType.VOID -> unexpectedType("void")
|
||||
returnType.fqName == JAVA_LANG_STRING -> return (psiValue as? PsiExpression)?.calcConstantValue(evaluator)
|
||||
jReturnType.isAnnotation -> {
|
||||
if (psiValue !is PsiAnnotation) error("psiValue is not a PsiAnnotation")
|
||||
val annotationClass = PsiTypesUtil.getPsiClass(returnType) ?: error("Can't resolve type $returnType")
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val annotation = KotlinAnnotationProxyMaker(psiValue, annotationClass, jReturnType as Class<out Annotation>)
|
||||
return jReturnType.cast(annotation.generate())
|
||||
}
|
||||
jReturnType.isArray -> {
|
||||
val jComponentType = jReturnType.componentType ?: unexpectedType("no component type for $jReturnType")
|
||||
if (returnType !is PsiArrayType) unexpectedType(returnType)
|
||||
|
||||
val arrayValues = when (psiValue) {
|
||||
is PsiArrayInitializerMemberValue -> psiValue.initializers.toList()
|
||||
else -> listOf(psiValue)
|
||||
}
|
||||
|
||||
if (jComponentType.isPrimitive
|
||||
|| jComponentType.isAnnotation
|
||||
|| jComponentType.isEnum
|
||||
|| jComponentType.canonicalName == JAVA_LANG_STRING
|
||||
) {
|
||||
val arr = Array.newInstance(jComponentType, arrayValues.size)
|
||||
arrayValues.forEachIndexed { i, componentPsiValue ->
|
||||
val componentValue = getConstantValue(componentPsiValue, returnType.componentType, jComponentType, evaluator)
|
||||
try { Array.set(arr, i, componentValue) } catch (e: IllegalArgumentException) { return null }
|
||||
}
|
||||
return arr
|
||||
} else {
|
||||
val typeMirrors = arrayValues.map { getObjectType(it).toJeType(manager) }
|
||||
return MirroredTypesExceptionProxy(Collections.unmodifiableList(typeMirrors))
|
||||
}
|
||||
}
|
||||
jReturnType.isEnum -> {
|
||||
val enumConstant = (psiValue.originalElement as? PsiReference)?.resolve() as? PsiEnumConstant
|
||||
?: error("$psiValue can not be resolved to enum constant")
|
||||
return AnnotationUtil.createEnumValue(jReturnType, enumConstant.name)
|
||||
}
|
||||
else -> return if (returnType is PsiClassType) {
|
||||
val type = getObjectType(psiValue).toJeType(manager)
|
||||
MirroredTypeExceptionProxy(type)
|
||||
} else {
|
||||
castPrimitiveValue(returnType, (psiValue as? PsiExpression)?.calcConstantValue(evaluator))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val PsiType.fqName: String?
|
||||
get() = (this as? PsiClassType)?.resolve()?.qualifiedName
|
||||
|
||||
private fun getObjectType(value: PsiAnnotationMemberValue): PsiType {
|
||||
when (value) {
|
||||
is PsiClassObjectAccessExpression -> return value.operand.type
|
||||
is PsiReference -> {
|
||||
val resolvedElement = value.resolve()
|
||||
if (resolvedElement is PsiField && resolvedElement.isStatic && resolvedElement.isFinal) {
|
||||
val initializer = resolvedElement.initializer
|
||||
if (initializer != null) {
|
||||
return getObjectType(initializer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw IllegalArgumentException("Illegal value type: ${value::class.java}")
|
||||
}
|
||||
|
||||
private fun castPrimitiveValue(type: PsiType, value: Any?): Any = when (type) {
|
||||
PsiType.BYTE -> byteValue(value)
|
||||
PsiType.SHORT -> shortValue(value)
|
||||
PsiType.INT -> intValue(value)
|
||||
PsiType.CHAR -> charValue(value)
|
||||
PsiType.BOOLEAN -> booleanValue(value)
|
||||
PsiType.LONG -> longValue(value)
|
||||
PsiType.FLOAT -> floatValue(value)
|
||||
PsiType.DOUBLE -> doubleValue(value)
|
||||
else -> unexpectedType(type)
|
||||
}
|
||||
|
||||
private fun byteValue(value: Any?): Byte = (value as? Number)?.toByte() ?: 0
|
||||
private fun intValue(value: Any?): Int = (value as? Number)?.toInt() ?: 0
|
||||
private fun shortValue(value: Any?): Short = (value as? Number)?.toShort() ?: 0
|
||||
private fun booleanValue(value: Any?): Boolean = value == true
|
||||
private fun charValue(value: Any?): Char = value as? Char ?: 0.toChar()
|
||||
|
||||
private fun longValue(value: Any?): Long = (value as? Number)?.toLong() ?: 0
|
||||
private fun floatValue(value: Any?): Float = (value as? Number)?.toFloat() ?: 0f
|
||||
private fun doubleValue(value: Any?): Double = (value as? Number)?.toDouble() ?: 0.0
|
||||
|
||||
private fun unexpectedType(type: String): Nothing = error("Unexpected type: $type")
|
||||
private fun unexpectedType(type: PsiType): Nothing = unexpectedType(type.presentableText)
|
||||
|
||||
private class MirroredTypeExceptionProxy(@Transient private var type: TypeMirror?) : ExceptionProxy() {
|
||||
private val typeString = type.toString()
|
||||
|
||||
@Suppress("IMPLICIT_CAST_TO_ANY")
|
||||
override fun hashCode() = (if (type != null) type else typeString)?.hashCode() ?: 0
|
||||
override fun equals(other: Any?) = type != null && other is MirroredTypeExceptionProxy && type == other.type
|
||||
override fun toString() = typeString
|
||||
|
||||
override fun generateException() = MirroredTypeException(type)
|
||||
|
||||
// Explicitly set all transient fields.
|
||||
private fun readObject(s: ObjectInputStream) {
|
||||
s.defaultReadObject()
|
||||
type = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val serialVersionUID: Long = 269
|
||||
}
|
||||
}
|
||||
|
||||
private class MirroredTypesExceptionProxy(@Transient private var types: List<TypeMirror>?) : ExceptionProxy() {
|
||||
private val typeStrings: String = types.toString()
|
||||
|
||||
@Suppress("IMPLICIT_CAST_TO_ANY")
|
||||
override fun hashCode() = (if (types != null) types else typeStrings)?.hashCode() ?: 0
|
||||
override fun equals(other: Any?) = types != null && other is MirroredTypesExceptionProxy && types == other.types
|
||||
override fun toString() = typeStrings
|
||||
|
||||
override fun generateException() = MirroredTypesException(types)
|
||||
|
||||
// Explicitly set all transient fields.
|
||||
private fun readObject(s: ObjectInputStream) {
|
||||
s.defaultReadObject()
|
||||
types = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val serialVersionUID: Long = 269
|
||||
}
|
||||
}
|
||||
-107
@@ -1,107 +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.java.model.internal
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.PsiModifier.*
|
||||
import com.intellij.psi.impl.PsiSubstitutorImpl
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightAnnotationForSourceEntry
|
||||
import javax.lang.model.element.Modifier
|
||||
|
||||
private val HAS_DEFAULT by lazy {
|
||||
Modifier::class.java.declaredFields.any { it.name == "DEFAULT" }
|
||||
}
|
||||
|
||||
private fun PsiModifierList.getJavaModifiers(): Set<Modifier> {
|
||||
fun MutableSet<Modifier>.check(modifier: String, javaModifier: Modifier) {
|
||||
if (hasModifierProperty(modifier)) this += javaModifier
|
||||
}
|
||||
|
||||
return mutableSetOf<Modifier>().apply {
|
||||
check(PUBLIC, Modifier.PUBLIC)
|
||||
check(PROTECTED, Modifier.PROTECTED)
|
||||
check(PRIVATE, Modifier.PRIVATE)
|
||||
check(STATIC, Modifier.STATIC)
|
||||
check(ABSTRACT, Modifier.ABSTRACT)
|
||||
check(FINAL, Modifier.FINAL)
|
||||
check(NATIVE, Modifier.NATIVE)
|
||||
check(SYNCHRONIZED, Modifier.SYNCHRONIZED)
|
||||
check(STRICTFP, Modifier.STRICTFP)
|
||||
check(TRANSIENT, Modifier.TRANSIENT)
|
||||
check(VOLATILE, Modifier.VOLATILE)
|
||||
|
||||
if (HAS_DEFAULT) {
|
||||
check(DEFAULT, Modifier.DEFAULT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun PsiExpression.calcConstantValue(evaluator: PsiConstantEvaluationHelper? = null): Any? {
|
||||
return when (this) {
|
||||
is PsiLiteral -> value
|
||||
is KtLightAnnotationForSourceEntry.LightExpressionValue<*> -> getConstantValue() ?: delegate.calcConstantValue(evaluator)
|
||||
is PsiExpression -> (evaluator ?: getConstantEvaluator(this)).computeConstantExpression(this)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConstantEvaluator(expression: PsiExpression) = JavaPsiFacade.getInstance(expression.project).constantEvaluationHelper
|
||||
|
||||
internal val PsiModifierListOwner.isStatic: Boolean
|
||||
get() = hasModifierProperty(PsiModifier.STATIC)
|
||||
|
||||
internal val PsiModifierListOwner.isFinal: Boolean
|
||||
get() = hasModifierProperty(PsiModifier.FINAL)
|
||||
|
||||
fun PsiModifierListOwner.getJavaModifiers() = modifierList?.getJavaModifiers() ?: emptySet()
|
||||
|
||||
fun PsiModifierListOwner.getAnnotationsWithInherited(): List<PsiAnnotation> {
|
||||
val annotations = modifierList?.annotations?.filter { it.qualifiedName != null }?.toMutableList() ?: mutableListOf()
|
||||
|
||||
if (this is PsiClass) {
|
||||
var superClass = superClass
|
||||
while (superClass != null) {
|
||||
superClass.modifierList?.annotations?.let { superClassAnnotations ->
|
||||
for (annotation in superClassAnnotations) {
|
||||
// Do not add the inherited annotation from the superclass
|
||||
// if the current class has an annotation with the same qualified name
|
||||
if (!annotation.isInherited()
|
||||
|| annotations.any { it.qualifiedName == annotation.qualifiedName }) continue
|
||||
annotations += annotation
|
||||
}
|
||||
}
|
||||
|
||||
superClass = superClass.superClass
|
||||
}
|
||||
}
|
||||
|
||||
return annotations
|
||||
}
|
||||
|
||||
fun PsiClass.getTypeWithTypeParameters(): PsiClassType {
|
||||
val elementFactory = JavaPsiFacade.getElementFactory(project)
|
||||
val params = mutableMapOf<PsiTypeParameter, PsiType>()
|
||||
typeParameters.forEach { params.put(it, PsiTypesUtil.getClassType(it)) }
|
||||
return elementFactory.createType(this, PsiSubstitutorImpl.createSubstitutor(params))
|
||||
}
|
||||
|
||||
private fun PsiAnnotation.isInherited(): Boolean {
|
||||
val annotationClass = nameReferenceElement?.resolve() as? PsiClass ?: return false
|
||||
val annotations = annotationClass.modifierList?.annotations ?: return false
|
||||
return annotations.any { it.qualifiedName == "java.lang.annotation.Inherited" }
|
||||
}
|
||||
@@ -1,50 +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.java.model.types
|
||||
|
||||
import com.intellij.psi.PsiArrayType
|
||||
import com.intellij.psi.PsiManager
|
||||
import javax.lang.model.type.ArrayType
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
|
||||
class JeArrayType(
|
||||
psiType: PsiArrayType,
|
||||
psiManager: PsiManager,
|
||||
private val isRaw: Boolean
|
||||
) : JePsiTypeBase<PsiArrayType>(psiType, psiManager), ArrayType {
|
||||
override fun getKind() = TypeKind.ARRAY
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitArray(this, p)
|
||||
override fun getComponentType() = psiType.componentType.toJeType(psiManager, isRaw = isRaw)
|
||||
|
||||
override fun toString() = psiType.getCanonicalText(false)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || other::class.java != this::class.java) return false
|
||||
other as? JeArrayType ?: return false
|
||||
|
||||
return componentType == other.componentType
|
||||
&& isRaw == other.isRaw
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = componentType.hashCode()
|
||||
result = 31 * result + isRaw.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
-52
@@ -1,52 +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.java.model.types
|
||||
|
||||
import com.intellij.psi.PsiClassInitializer
|
||||
import org.jetbrains.kotlin.java.model.JeDisposablePsiElementOwner
|
||||
import org.jetbrains.kotlin.java.model.internal.isStatic
|
||||
import javax.lang.model.type.*
|
||||
|
||||
class JeClassInitializerExecutableTypeMirror(
|
||||
psi: PsiClassInitializer
|
||||
) : JeDisposablePsiElementOwner<PsiClassInitializer>(psi), JeTypeMirror, JeTypeWithManager, ExecutableType {
|
||||
override fun getKind() = TypeKind.EXECUTABLE
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitExecutable(this, p)
|
||||
|
||||
override fun getReturnType() = JeVoidType
|
||||
|
||||
override fun getReceiverType() = JeNoneType
|
||||
|
||||
override fun getThrownTypes() = emptyList<TypeMirror>()
|
||||
|
||||
override fun getParameterTypes() = emptyList<TypeMirror>()
|
||||
|
||||
override fun getTypeVariables() = emptyList<TypeVariable>()
|
||||
|
||||
override fun toString() = (psi.containingClass?.qualifiedName?.let { it + "." } ?: "") +
|
||||
(if (psi.isStatic) "<clinit>" else "<instinit>")
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || other::class.java != this::class.java) return false
|
||||
other as? JeClassInitializerExecutableTypeMirror ?: return false
|
||||
return psi == other.psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user