diff options
author | Jiaxiang Chen <jiaxiang@google.com> | 2021-10-26 13:13:58 -0700 |
---|---|---|
committer | Jiaxiang Chen <roaringacw@gmail.com> | 2022-03-10 15:09:18 -0800 |
commit | 1eb4436dff88e21dda692a147c04fd83c2b128a7 (patch) | |
tree | 23c7a2ec677d5a6ad117c8f5785c2ca635cd99b9 /kotlin-analysis-api | |
parent | 6cac3e09c1761f4c952cc28d7a0bcfac6c6bb6cf (diff) | |
download | ksp-1eb4436dff88e21dda692a147c04fd83c2b128a7.tar.gz |
* Implement skeleton service providers
* Add unit test for analysis API
* Remove dependency on prebuilt binaries
Diffstat (limited to 'kotlin-analysis-api')
12 files changed, 519 insertions, 5 deletions
diff --git a/kotlin-analysis-api/build.gradle.kts b/kotlin-analysis-api/build.gradle.kts index 2c7dd330..356af147 100644 --- a/kotlin-analysis-api/build.gradle.kts +++ b/kotlin-analysis-api/build.gradle.kts @@ -1,8 +1,10 @@ description = "Kotlin Symbol Processing implementation using Kotlin Analysis API" val intellijVersion: String by project -val kotlinBaseVersion: String by project val junitVersion: String by project +val kotlinVersionFir = "1.6.20-dev-2497" +val analysisAPIVersion = "1.6.20-dev-3387" +val libsForTesting by configurations.creating plugins { kotlin("jvm") @@ -25,16 +27,80 @@ fun ModuleDependency.includeJars(vararg names: String) { } dependencies { - implementation(kotlin("stdlib", kotlinBaseVersion)) - implementation("org.jetbrains.kotlin:high-level-api-for-ide:1.6.255") - implementation("org.jetbrains.kotlin:kotlin-compiler:$kotlinBaseVersion") + implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.1") + implementation(kotlin("stdlib", kotlinVersionFir)) + implementation("org.jetbrains.kotlin:kotlin-compiler:$kotlinVersionFir") + + implementation("org.jetbrains.kotlin:high-level-api-fir-for-ide:$analysisAPIVersion") { + isTransitive = false + } + implementation("org.jetbrains.kotlin:high-level-api-for-ide:$analysisAPIVersion") { + isTransitive = false + } + implementation("org.jetbrains.kotlin:low-level-api-fir-for-ide:$analysisAPIVersion") { + isTransitive = false + } + implementation("org.jetbrains.kotlin:analysis-api-providers-for-ide:$analysisAPIVersion") { + isTransitive = false + } + implementation("org.jetbrains.kotlin:analysis-project-structure-for-ide:$analysisAPIVersion") { + isTransitive = false + } implementation(project(":api")) + + libsForTesting(kotlin("stdlib", kotlinVersionFir)) + libsForTesting(kotlin("test", kotlinVersionFir)) + libsForTesting(kotlin("script-runtime", kotlinVersionFir)) +} + +tasks.register<Copy>("CopyLibsForTesting") { + from(configurations.get("libsForTesting")) + into("dist/kotlinc/lib") + val escaped = Regex.escape(kotlinVersionFir) + rename("(.+)-$escaped\\.jar", "$1.jar") +} + +sourceSets.main { + java.srcDirs("src/main/kotlin") } + +fun Project.javaPluginConvention(): JavaPluginConvention = the() +val JavaPluginConvention.testSourceSet: SourceSet + get() = sourceSets.getByName("test") +val Project.testSourceSet: SourceSet + get() = javaPluginConvention().testSourceSet + +tasks.test { + dependsOn("CopyLibsForTesting") + maxHeapSize = "2g" + + systemProperty("idea.is.unit.test", "true") + systemProperty("idea.home.path", buildDir) + systemProperty("java.awt.headless", "true") + environment("NO_FS_ROOTS_ACCESS_CHECK", "true") + environment("PROJECT_CLASSES_DIRS", testSourceSet.output.classesDirs.asPath) + environment("PROJECT_BUILD_DIR", buildDir) + testLogging { + events("passed", "skipped", "failed") + } + + var tempTestDir: File? = null + doFirst { + tempTestDir = createTempDir() + systemProperty("java.io.tmpdir", tempTestDir.toString()) + } + + doLast { + tempTestDir?.let { delete(it) } + } +} + repositories { flatDir { dirs("${project.rootDir}/third_party/prebuilt/repo/") } maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/bootstrap/") - maven("https://www.jetbrains.com/intellij-repository/snapshots") + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-ide-plugin-dependencies") + maven("https://www.jetbrains.com/intellij-repository/releases") } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/DeclarationProviderImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/DeclarationProviderImpl.kt new file mode 100644 index 00000000..e94c03fc --- /dev/null +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/DeclarationProviderImpl.kt @@ -0,0 +1,87 @@ +package com.google.devtools.ksp.impl + +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider +import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName +import org.jetbrains.kotlin.name.CallableId +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType + +class DeclarationProviderImpl( + val searchScope: GlobalSearchScope, + ktFiles: Collection<KtFile> +) : KotlinDeclarationProvider() { + + private val filesInScope = ktFiles.filter { searchScope.contains(it.virtualFile) } + + private fun filesByPackage(packageFqName: FqName) = + filesInScope.asSequence() + .filter { it.packageFqName == packageFqName } + + override fun getClassesByClassId(classId: ClassId): Collection<KtClassOrObject> = + filesByPackage(classId.packageFqName).flatMap { file -> + file.collectDescendantsOfType<KtClassOrObject> { ktClass -> + ktClass.getClassId() == classId + } + }.toList() + + override fun getTypeAliasesByClassId(classId: ClassId): Collection<KtTypeAlias> = + filesByPackage(classId.packageFqName).flatMap { file -> + file.collectDescendantsOfType<KtTypeAlias> { typeAlias -> + typeAlias.getClassId() == classId + } + }.toList() + + override fun getTypeAliasNamesInPackage(packageFqName: FqName): Set<Name> = + filesByPackage(packageFqName) + .flatMap { it.declarations } + .filterIsInstance<KtTypeAlias>() + .mapNotNullTo(mutableSetOf()) { it.nameAsName } + + override fun getPropertyNamesInPackage(packageFqName: FqName): Set<Name> = + filesByPackage(packageFqName) + .flatMap { it.declarations } + .filterIsInstance<KtProperty>() + .mapNotNullTo(mutableSetOf()) { it.nameAsName } + + override fun getFunctionsNamesInPackage(packageFqName: FqName): Set<Name> = + filesByPackage(packageFqName) + .flatMap { it.declarations } + .filterIsInstance<KtNamedFunction>() + .mapNotNullTo(mutableSetOf()) { it.nameAsName } + + override fun getFacadeFilesInPackage(packageFqName: FqName): Collection<KtFile> = + filesByPackage(packageFqName) + .filter { file -> file.hasTopLevelCallables() } + .toSet() + + override fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile> { + if (facadeFqName.shortNameOrSpecial().isSpecial) return emptyList() + return getFacadeFilesInPackage(facadeFqName.parent()) + .filter { it.javaFileFacadeFqName == facadeFqName } + } + + override fun getTopLevelProperties(callableId: CallableId): Collection<KtProperty> = + filesByPackage(callableId.packageName) + .flatMap { it.declarations } + .filterIsInstance<KtProperty>() + .filter { it.nameAsName == callableId.callableName } + .toList() + + override fun getTopLevelFunctions(callableId: CallableId): Collection<KtNamedFunction> = + filesByPackage(callableId.packageName) + .flatMap { it.declarations } + .filterIsInstance<KtNamedFunction>() + .filter { it.nameAsName == callableId.callableName } + .toList() + + + override fun getClassNamesInPackage(packageFqName: FqName): Set<Name> = + filesByPackage(packageFqName) + .flatMap { it.declarations } + .filterIsInstance<KtClassOrObject>() + .mapNotNullTo(mutableSetOf()) { it.nameAsName } +} diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/FirSealedClassInheritorsProcessorFactoryImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/FirSealedClassInheritorsProcessorFactoryImpl.kt new file mode 100644 index 00000000..fa5dd3ea --- /dev/null +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/FirSealedClassInheritorsProcessorFactoryImpl.kt @@ -0,0 +1,19 @@ +package com.google.devtools.ksp.impl + +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory +import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider +import org.jetbrains.kotlin.name.ClassId + +class FirSealedClassInheritorsProcessorFactoryImpl: FirSealedClassInheritorsProcessorFactory() { + override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider { + return SealedClassInheritorProviderImpl() + } +} + +class SealedClassInheritorProviderImpl: SealedClassInheritorsProvider() { + override fun getSealedClassInheritors(firClass: FirRegularClass): List<ClassId> { + return emptyList() + } + +} diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/HackPomModel.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/HackPomModel.kt new file mode 100644 index 00000000..36a006a9 --- /dev/null +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/HackPomModel.kt @@ -0,0 +1,21 @@ +package com.google.devtools.ksp.impl + +import com.intellij.openapi.project.Project +import com.intellij.pom.PomModelAspect +import com.intellij.pom.core.impl.PomModelImpl +import com.intellij.pom.event.PomModelEvent +import com.intellij.psi.impl.source.PostprocessReformattingAspect + +class HackPomModel(project: Project) : PomModelImpl(project) { + + var myAspect = PostprocessReformattingAspect(project) + + override fun <T : PomModelAspect> getModelAspect(aClass: Class<T>): T { + return if (myAspect.javaClass == aClass) myAspect as T else super.getModelAspect<T>(aClass) + } + + override fun updateDependentAspects(event: PomModelEvent?) { + super.updateDependentAspects(event) + myAspect.update(event!!) + } +} diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinOutOfBlockModificationTrackerFactoryImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinOutOfBlockModificationTrackerFactoryImpl.kt new file mode 100644 index 00000000..c547214d --- /dev/null +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinOutOfBlockModificationTrackerFactoryImpl.kt @@ -0,0 +1,31 @@ +package com.google.devtools.ksp.impl + +import com.intellij.openapi.util.ModificationTracker +import com.intellij.openapi.util.SimpleModificationTracker +import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule +import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory +import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase + +class KotlinOutOfBlockModificationTrackerFactoryImpl : KotlinModificationTrackerFactory() { + private val projectWide = SimpleModificationTracker() + private val library = SimpleModificationTracker() + private val forModule = mutableMapOf<KtSourceModule, SimpleModificationTracker>() + + override fun createProjectWideOutOfBlockModificationTracker(): ModificationTracker { + return projectWide + } + + override fun createLibrariesModificationTracker(): ModificationTracker { + return library + } + + override fun createModuleWithoutDependenciesOutOfBlockModificationTracker(module: KtSourceModule): ModificationTracker { + return forModule.getOrPut(module) { SimpleModificationTracker() } + } + + override fun incrementModificationsCount() { + projectWide.incModificationCount() + library.incModificationCount() + forModule.values.forEach { it.incModificationCount() } + } +} diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinPackageProviderImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinPackageProviderImpl.kt new file mode 100644 index 00000000..95a0a931 --- /dev/null +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinPackageProviderImpl.kt @@ -0,0 +1,23 @@ +package com.google.devtools.ksp.impl + +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtFile + +class KotlinPackageProviderImpl( + scope: GlobalSearchScope, + files: Collection<KtFile> +) : KotlinPackageProvider() { + private val filesInScope = files.filter { scope.contains(it.virtualFile) } + + + override fun doKotlinPackageExists(packageFqName: FqName): Boolean { + return filesInScope.any { it.packageFqName == packageFqName } + } + + override fun getKotlinSubPackageFqNames(packageFqName: FqName): Set<Name> { + TODO("Not yet implemented") + } +} diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinSymbolProcessing.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinSymbolProcessing.kt index 2987cb5e..5e8bfc85 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinSymbolProcessing.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinSymbolProcessing.kt @@ -1,4 +1,184 @@ package com.google.devtools.ksp.impl +import com.intellij.core.CoreApplicationEnvironment +import com.intellij.formatting.Formatter +import com.intellij.formatting.FormatterImpl +import com.intellij.mock.MockApplication +import com.intellij.mock.MockProject +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.AsyncExecutionService +import com.intellij.openapi.application.impl.AsyncExecutionServiceImpl +import com.intellij.openapi.editor.impl.DocumentWriteAccessGuard +import com.intellij.openapi.extensions.Extensions +import com.intellij.openapi.fileEditor.impl.FileEditorPsiTreeChangeListener +import com.intellij.openapi.util.Disposer +import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.util.text.StringUtilRt +import com.intellij.openapi.vfs.CharsetToolkit +import com.intellij.pom.PomModel +import com.intellij.pom.tree.TreeAspect +import com.intellij.psi.PsiTreeChangeListener +import com.intellij.psi.codeStyle.CodeStyleManager +import com.intellij.psi.impl.DocumentCommitProcessor +import com.intellij.psi.impl.DocumentCommitThread +import com.intellij.psi.impl.PsiFileFactoryImpl +import com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.testFramework.LightVirtualFile +import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession +import org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProvider +import org.jetbrains.kotlin.analysis.api.analyseWithReadAction +import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSessionProvider +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.PackagePartProviderFactory +import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider +import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider +import org.jetbrains.kotlin.analysis.providers.* +import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.idea.KotlinLanguage +import org.jetbrains.kotlin.idea.references.* +import org.jetbrains.kotlin.load.kotlin.PackagePartProvider +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.serialization.deserialization.ClassData +import java.io.File + +@OptIn(InvalidWayOfUsingAnalysisSession::class) +fun registerComponents(project: MockProject, environment: KotlinCoreEnvironment, ktFiles: List<KtFile>) { + + project.picoContainer.registerComponentInstance( + KtAnalysisSessionProvider::class.qualifiedName, + KtFirAnalysisSessionProvider(project) + ) + + project.picoContainer.registerComponentInstance( + ProjectStructureProvider::class.qualifiedName, + ProjectStructureProviderImpl() + ) + + project.picoContainer.registerComponentInstance( + KotlinModificationTrackerFactory::class.qualifiedName, + KotlinOutOfBlockModificationTrackerFactoryImpl() + ) + + RegisterComponentService.registerFirIdeResolveStateService(project) + + project.picoContainer.registerComponentInstance( + KotlinDeclarationProviderFactory::class.qualifiedName, + object : KotlinDeclarationProviderFactory() { + override fun createDeclarationProvider(searchScope: GlobalSearchScope): KotlinDeclarationProvider { + return DeclarationProviderImpl(searchScope, ktFiles.filter { searchScope.contains(it.virtualFile) }) + } + } + ) + + project.picoContainer.registerComponentInstance( + KotlinPackageProviderFactory::class.qualifiedName, + object : KotlinPackageProviderFactory() { + override fun createPackageProvider(searchScope: GlobalSearchScope): KotlinPackageProvider { + return KotlinPackageProviderImpl(searchScope, ktFiles.filter { searchScope.contains(it.virtualFile) }) + } + } + ) + + project.picoContainer.registerComponentInstance( + FirSealedClassInheritorsProcessorFactory::class.qualifiedName, + FirSealedClassInheritorsProcessorFactoryImpl() + ) + project.picoContainer.registerComponentInstance( + PackagePartProviderFactory::class.qualifiedName, + object : PackagePartProviderFactory() { + override fun createPackagePartProviderForLibrary(scope: GlobalSearchScope): PackagePartProvider { + return object : PackagePartProvider { + override fun findPackageParts(packageFqName: String): List<String> { + return emptyList() + } + + override fun getAllOptionalAnnotationClasses(): List<ClassData> { + return emptyList() + } + + override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> { + return emptyList() + } + } + } + } + ) + + val application = ApplicationManager.getApplication() as MockApplication + KotlinCoreEnvironment.underApplicationLock { + application.registerService( + KotlinReferenceProviderContributor::class.java, KotlinFirReferenceContributor::class.java + ) + application.registerService(DocumentCommitProcessor::class.java, DocumentCommitThread::class.java) + application.registerService(AsyncExecutionService::class.java, AsyncExecutionServiceImpl::class.java) + application.registerService(Formatter::class.java, FormatterImpl::class.java) + } + + project.picoContainer.registerComponentInstance( + CodeStyleManager::class.qualifiedName, + CodeStyleManagerImpl(project) + ) + project.picoContainer.registerComponentInstance( + TreeAspect::class.qualifiedName, + TreeAspect() + ) + project.picoContainer.registerComponentInstance( + PomModel::class.qualifiedName, + HackPomModel(project) + ) + + project.picoContainer.registerComponentInstance( + KtModuleScopeProvider::class.qualifiedName, + KtModuleScopeProviderImpl() + ) + + CoreApplicationEnvironment.registerExtensionPoint( + Extensions.getRootArea(), + DocumentWriteAccessGuard.EP_NAME, + DocumentWriteAccessGuard::class.java + ) + CoreApplicationEnvironment.registerExtensionPoint( + project.extensionArea, + PsiTreeChangeListener.EP, + FileEditorPsiTreeChangeListener::class.java + ) +} +fun findSomeReference(ktFile: KtFile): KtReference? { + for (i in 1..300) { + val reference = ktFile.findReferenceAt(i) + if (reference != null && reference is KtReference) + return reference + } + + return null +} + fun main() { + val compilerConfiguration = CompilerConfiguration() + compilerConfiguration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE) + val env = KotlinCoreEnvironment.createForProduction( + Disposer.newDisposable(), compilerConfiguration, + EnvironmentConfigFiles.JVM_CONFIG_FILES + ) + + val project = env.project as MockProject + val factory = PsiFileFactoryImpl(project) + + val file = File("testData/api/hello.kt") + val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim { it <= ' ' } + + val virtualFile = LightVirtualFile("a.kt", KotlinLanguage.INSTANCE, StringUtilRt.convertLineSeparators(text)) + val ktFile = factory.trySetupPsiForFile(virtualFile, KotlinLanguage.INSTANCE, true, false) as KtFile + registerComponents(project, env, listOf(ktFile)) + analyseWithReadAction(ktFile) { + val mainRef = ktFile.mainReference + val reference = findSomeReference(ktFile) + reference?.resolveToSymbol() + } } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KtModuleScopeProviderImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KtModuleScopeProviderImpl.kt new file mode 100644 index 00000000..6f0b1136 --- /dev/null +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KtModuleScopeProviderImpl.kt @@ -0,0 +1,12 @@ +package com.google.devtools.ksp.impl + +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider +import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule + +class KtModuleScopeProviderImpl: KtModuleScopeProvider() { + override fun getModuleLibrariesScope(sourceModule: KtSourceModule): GlobalSearchScope { + return GlobalSearchScope.filesScope(sourceModule.project, emptyList()) + } + +} diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ProjectStructureProviderImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ProjectStructureProviderImpl.kt new file mode 100644 index 00000000..a9e072ae --- /dev/null +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ProjectStructureProviderImpl.kt @@ -0,0 +1,41 @@ +package com.google.devtools.ksp.impl + +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule +import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider +import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.platform.jvm.JdkPlatform +import org.jetbrains.kotlin.platform.jvm.JvmPlatform +import org.jetbrains.kotlin.platform.jvm.JvmPlatforms +import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices +import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices + +class ProjectStructureProviderImpl : ProjectStructureProvider() { + override fun getKtModuleForKtElement(element: PsiElement): KtModule { + return object: KtSourceModule { + override val analyzerServices: PlatformDependentAnalyzerServices + get() = JvmPlatformAnalyzerServices + override val contentScope: GlobalSearchScope + get() = GlobalSearchScope.EMPTY_SCOPE + override val directFriendDependencies: List<KtModule> + get() = emptyList() + override val directRefinementDependencies: List<KtModule> + get() = emptyList() + override val directRegularDependencies: List<KtModule> + get() = emptyList() + override val languageVersionSettings: LanguageVersionSettings + get() = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST) + override val moduleName: String + get() = "main" + override val platform: TargetPlatform + get() = TargetPlatform(setOf(JdkPlatform(JvmTarget.DEFAULT))) + override val project: Project + get() = element.project + + } + } +} diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/RegisterComponentService.java b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/RegisterComponentService.java new file mode 100644 index 00000000..54bfcbcb --- /dev/null +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/RegisterComponentService.java @@ -0,0 +1,10 @@ +package com.google.devtools.ksp.impl; + +import com.intellij.mock.MockProject; +import org.jetbrains.kotlin.analysis.low.level.api.fir.FirIdeResolveStateService; + +public class RegisterComponentService { + public static void registerFirIdeResolveStateService(MockProject project) { + project.getPicoContainer().registerComponentInstance(FirIdeResolveStateService.class.getName(), new FirIdeResolveStateService(project)); + } +} diff --git a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/KotlinAnalysisAPITest.kt b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/KotlinAnalysisAPITest.kt new file mode 100644 index 00000000..de4d8dfc --- /dev/null +++ b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/KotlinAnalysisAPITest.kt @@ -0,0 +1,12 @@ +package com.google.devtools.ksp.impl.test + +import com.google.devtools.ksp.impl.main +import org.junit.Test + +class KotlinAnalysisAPITest { + + @Test + fun testHello() { + main() + } +} diff --git a/kotlin-analysis-api/testData/api/hello.kt b/kotlin-analysis-api/testData/api/hello.kt new file mode 100644 index 00000000..6a33984c --- /dev/null +++ b/kotlin-analysis-api/testData/api/hello.kt @@ -0,0 +1,12 @@ +package test +annotation class Anno + +@Anno +class Foo() { + val k = "123" + var a : String = "123" + val aaa : (Int) -> Int = { a -> 1 } + fun bar(): Int { + return 3 + } +} |