diff options
author | Jiaxiang Chen <jiaxiang@google.com> | 2022-03-21 22:41:44 -0700 |
---|---|---|
committer | Jiaxiang Chen <roaringacw@gmail.com> | 2022-03-28 19:06:44 -0700 |
commit | 6c906beef9720a431343914c523d700af9c510a6 (patch) | |
tree | 8e6cabc439b3466232d5dba625eae94bc5b14d7d /common-util | |
parent | d6f2b6eef0b466a35fc4b8e1e14ee8ef05cf03e6 (diff) | |
download | ksp-6c906beef9720a431343914c523d700af9c510a6.tar.gz |
* Extract CodeGeneratorImpl, PlatformInfoImpl into common-util module, add copyright to common-util module classes.
* Add KSP Command line processor and logger.
* Implement KSP main execution and initialization logic.
Diffstat (limited to 'common-util')
7 files changed, 311 insertions, 0 deletions
diff --git a/common-util/src/main/kotlin/com/google/devtools/ksp/DescriptorUtils.kt b/common-util/src/main/kotlin/com/google/devtools/ksp/DescriptorUtils.kt index d360d263..9e4ba3c6 100644 --- a/common-util/src/main/kotlin/com/google/devtools/ksp/DescriptorUtils.kt +++ b/common-util/src/main/kotlin/com/google/devtools/ksp/DescriptorUtils.kt @@ -1,3 +1,20 @@ +/* + * Copyright 2022 Google LLC + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.google.devtools.ksp import com.google.devtools.ksp.symbol.KSAnnotated diff --git a/common-util/src/main/kotlin/com/google/devtools/ksp/IncrementalUtil.kt b/common-util/src/main/kotlin/com/google/devtools/ksp/IncrementalUtil.kt new file mode 100644 index 00000000..f0c94dc7 --- /dev/null +++ b/common-util/src/main/kotlin/com/google/devtools/ksp/IncrementalUtil.kt @@ -0,0 +1,64 @@ +/* + * Copyright 2022 Google LLC + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.devtools.ksp + +import com.google.devtools.ksp.symbol.* +import java.io.File + +abstract class KSVirtualFile(val baseDir: File, val name: String) : KSFile { + override val annotations: Sequence<KSAnnotation> + get() = throw Exception("$name should not be used.") + + override val declarations: Sequence<KSDeclaration> + get() = throw Exception("$name should not be used.") + + override val fileName: String + get() = "<$name is a virtual file; DO NOT USE.>" + + override val filePath: String + get() = File(baseDir, fileName).path + + override val packageName: KSName + get() = throw Exception("$name should not be used.") + + override val origin: Origin + get() = throw Exception("$name should not be used.") + + override val location: Location + get() = throw Exception("$name should not be used.") + + override val parent: KSNode? + get() = throw Exception("$name should not be used.") + + override fun <D, R> accept(visitor: KSVisitor<D, R>, data: D): R { + throw Exception("$name should not be used.") + } +} + +/** + * Used when an output potentially depends on new information. + */ +class AnyChanges(baseDir: File) : KSVirtualFile(baseDir, "AnyChanges") + +/** + * Used for classes from classpath, i.e., classes without source files. + */ +class NoSourceFile(baseDir: File, val fqn: String) : KSVirtualFile(baseDir, "NoSourceFile") { + override val fileName: String + get() = "<NoSourceFile for $fqn is a virtual file; DO NOT USE.>" +} diff --git a/common-util/src/main/kotlin/com/google/devtools/ksp/KspOptions.kt b/common-util/src/main/kotlin/com/google/devtools/ksp/KspOptions.kt index 907e650f..83759d30 100644 --- a/common-util/src/main/kotlin/com/google/devtools/ksp/KspOptions.kt +++ b/common-util/src/main/kotlin/com/google/devtools/ksp/KspOptions.kt @@ -1,3 +1,20 @@ +/* + * Copyright 2022 Google LLC + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.google.devtools.ksp import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption diff --git a/common-util/src/main/kotlin/com/google/devtools/ksp/MemoizedSequence.kt b/common-util/src/main/kotlin/com/google/devtools/ksp/MemoizedSequence.kt index 9fa09323..be7a05d6 100644 --- a/common-util/src/main/kotlin/com/google/devtools/ksp/MemoizedSequence.kt +++ b/common-util/src/main/kotlin/com/google/devtools/ksp/MemoizedSequence.kt @@ -1,3 +1,20 @@ +/* + * Copyright 2022 Google LLC + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.google.devtools.ksp // TODO: garbage collect underlying sequence after exhaust. diff --git a/common-util/src/main/kotlin/com/google/devtools/ksp/PsiUtils.kt b/common-util/src/main/kotlin/com/google/devtools/ksp/PsiUtils.kt index fa31dca2..9003a7fe 100644 --- a/common-util/src/main/kotlin/com/google/devtools/ksp/PsiUtils.kt +++ b/common-util/src/main/kotlin/com/google/devtools/ksp/PsiUtils.kt @@ -1,3 +1,20 @@ +/* + * Copyright 2022 Google LLC + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.google.devtools.ksp import com.google.devtools.ksp.symbol.* diff --git a/common-util/src/main/kotlin/com/google/devtools/ksp/processing/impl/CodeGeneratorImpl.kt b/common-util/src/main/kotlin/com/google/devtools/ksp/processing/impl/CodeGeneratorImpl.kt new file mode 100644 index 00000000..6bf1941d --- /dev/null +++ b/common-util/src/main/kotlin/com/google/devtools/ksp/processing/impl/CodeGeneratorImpl.kt @@ -0,0 +1,130 @@ +/* + * Copyright 2020 Google LLC + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.devtools.ksp.processing.impl + +import com.google.devtools.ksp.NoSourceFile +import com.google.devtools.ksp.processing.CodeGenerator +import com.google.devtools.ksp.processing.Dependencies +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.google.devtools.ksp.symbol.KSFile +import java.io.File +import java.io.FileOutputStream +import java.io.OutputStream + +class CodeGeneratorImpl( + private val classDir: File, + private val javaDir: File, + private val kotlinDir: File, + private val resourcesDir: File, + private val projectBase: File, + private val anyChangesWildcard: KSFile, + private val allSources: List<KSFile>, + private val isIncremental: Boolean +) : CodeGenerator { + private val fileMap = mutableMapOf<String, File>() + private val fileOutputStreamMap = mutableMapOf<String, FileOutputStream>() + + private val separator = File.separator + + val sourceToOutputs: MutableMap<File, MutableSet<File>> = mutableMapOf() + + // This function will also clear `fileOutputStreamMap` which will change the result of `generatedFile` + fun closeFiles() { + fileOutputStreamMap.keys.forEach { + fileOutputStreamMap[it]!!.close() + } + fileOutputStreamMap.clear() + } + + fun pathOf(packageName: String, fileName: String, extensionName: String): String { + val packageDirs = if (packageName != "") "${packageName.split(".").joinToString(separator)}$separator" else "" + val extension = if (extensionName != "") ".$extensionName" else "" + val typeRoot = when (extensionName) { + "class" -> classDir + "java" -> javaDir + "kt" -> kotlinDir + else -> resourcesDir + }.path + return "$typeRoot$separator$packageDirs$fileName$extension" + } + + override fun createNewFile( + dependencies: Dependencies, + packageName: String, + fileName: String, + extensionName: String + ): OutputStream { + val path = pathOf(packageName, fileName, extensionName) + val file = File(path) + if (path in fileMap) { + throw FileAlreadyExistsException(file) + } + val parentFile = file.parentFile + if (!parentFile.exists() && !parentFile.mkdirs()) { + throw IllegalStateException("failed to make parent directories.") + } + file.writeText("") + fileMap[path] = file + val sources = if (dependencies.isAllSources) { + allSources + anyChangesWildcard + } else { + if (dependencies.aggregating) { + dependencies.originatingFiles + anyChangesWildcard + } else { + dependencies.originatingFiles + } + } + associate(sources, path) + fileOutputStreamMap[path] = fileMap[path]!!.outputStream() + return fileOutputStreamMap[path]!! + } + + override fun associate(sources: List<KSFile>, packageName: String, fileName: String, extensionName: String) { + val path = pathOf(packageName, fileName, extensionName) + associate(sources, path) + } + + override fun associateWithClasses( + classes: List<KSClassDeclaration>, + packageName: String, + fileName: String, + extensionName: String + ) { + val path = pathOf(packageName, fileName, extensionName) + val files = classes.map { + it.containingFile ?: NoSourceFile(projectBase, it.qualifiedName?.asString().toString()) + } + associate(files, path) + } + + private fun associate(sources: List<KSFile>, outputPath: String) { + if (!isIncremental) + return + + val output = File(outputPath).relativeTo(projectBase) + sources.forEach { source -> + sourceToOutputs.getOrPut(File(source.filePath).relativeTo(projectBase)) { mutableSetOf() }.add(output) + } + } + + val outputs: Set<File> + get() = fileMap.keys.mapTo(mutableSetOf()) { File(it).relativeTo(projectBase) } + + override val generatedFile: Collection<File> + get() = fileOutputStreamMap.keys.map { fileMap[it]!! } +} diff --git a/common-util/src/main/kotlin/com/google/devtools/ksp/processing/impl/PlatformInfoImpl.kt b/common-util/src/main/kotlin/com/google/devtools/ksp/processing/impl/PlatformInfoImpl.kt new file mode 100644 index 00000000..cccae381 --- /dev/null +++ b/common-util/src/main/kotlin/com/google/devtools/ksp/processing/impl/PlatformInfoImpl.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2022 Google LLC + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.devtools.ksp.processing.impl + +import com.google.devtools.ksp.processing.JsPlatformInfo +import com.google.devtools.ksp.processing.JvmPlatformInfo +import com.google.devtools.ksp.processing.NativePlatformInfo +import com.google.devtools.ksp.processing.UnknownPlatformInfo + +class JvmPlatformInfoImpl( + override val platformName: String, + override val jvmTarget: String +) : JvmPlatformInfo { + override fun toString() = "$platformName ($jvmTarget)" +} + +class JsPlatformInfoImpl( + override val platformName: String +) : JsPlatformInfo { + override fun toString() = platformName +} + +class NativePlatformInfoImpl( + override val platformName: String, + override val targetName: String +) : NativePlatformInfo { + override fun toString() = "$platformName ($targetName)" +} + +class UnknownPlatformInfoImpl( + override val platformName: String +) : UnknownPlatformInfo { + override fun toString() = platformName +} |