Add prefix information for Java source root (KT-9167 in progress)
#KT-9167 In Progress
This commit is contained in:
committed by
Nikolay Krasko
parent
77138ecdb7
commit
c0739ef53c
+5
-4
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.cli.common.modules
|
||||
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.modules.JavaRootPath
|
||||
import java.util.*
|
||||
|
||||
public class ModuleBuilder(
|
||||
@@ -26,7 +27,7 @@ public class ModuleBuilder(
|
||||
) : Module {
|
||||
private val sourceFiles = ArrayList<String>()
|
||||
private val classpathRoots = ArrayList<String>()
|
||||
private val javaSourceRoots = ArrayList<String>()
|
||||
private val javaSourceRoots = ArrayList<JavaRootPath>()
|
||||
|
||||
public fun addSourceFiles(pattern: String) {
|
||||
sourceFiles.add(pattern)
|
||||
@@ -36,12 +37,12 @@ public class ModuleBuilder(
|
||||
classpathRoots.add(name)
|
||||
}
|
||||
|
||||
public fun addJavaSourceRoot(name: String) {
|
||||
javaSourceRoots.add(name)
|
||||
public fun addJavaSourceRoot(rootPath: JavaRootPath) {
|
||||
javaSourceRoots.add(rootPath)
|
||||
}
|
||||
|
||||
override fun getOutputDirectory(): String = outputDir
|
||||
override fun getJavaSourceRoots(): List<String> = javaSourceRoots
|
||||
override fun getJavaSourceRoots(): List<JavaRootPath> = javaSourceRoots
|
||||
override fun getSourceFiles(): List<String> = sourceFiles
|
||||
override fun getClasspathRoots(): List<String> = classpathRoots
|
||||
override fun getModuleName(): String = name
|
||||
|
||||
+11
-1
@@ -19,9 +19,11 @@ package org.jetbrains.kotlin.cli.common.modules;
|
||||
import com.intellij.openapi.util.io.StreamUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil;
|
||||
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil;
|
||||
import org.jetbrains.kotlin.modules.JavaRootPath;
|
||||
import org.jetbrains.kotlin.modules.Module;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
@@ -47,6 +49,7 @@ public class ModuleXmlParser {
|
||||
public static final String OUTPUT_DIR = "outputDir";
|
||||
public static final String SOURCES = "sources";
|
||||
public static final String JAVA_SOURCE_ROOTS = "javaSourceRoots";
|
||||
public static final String JAVA_SOURCE_PACKAGE_PREFIX = "packagePrefix";
|
||||
public static final String PATH = "path";
|
||||
public static final String CLASSPATH = "classpath";
|
||||
|
||||
@@ -165,7 +168,8 @@ public class ModuleXmlParser {
|
||||
}
|
||||
else if (JAVA_SOURCE_ROOTS.equalsIgnoreCase(qName)) {
|
||||
String path = getAttribute(attributes, PATH, qName);
|
||||
moduleBuilder.addJavaSourceRoot(path);
|
||||
String packagePrefix = getNullableAttribute(attributes, JAVA_SOURCE_PACKAGE_PREFIX);
|
||||
moduleBuilder.addJavaSourceRoot(new JavaRootPath(path, packagePrefix));
|
||||
}
|
||||
else {
|
||||
throw createError(qName);
|
||||
@@ -189,6 +193,12 @@ public class ModuleXmlParser {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getNullableAttribute(Attributes attributes, String qName) throws SAXException {
|
||||
return attributes.getValue(qName);
|
||||
}
|
||||
|
||||
|
||||
private static SAXException createError(String qName) throws SAXException {
|
||||
return new SAXException("Unexpected tag: " + qName);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.ArrayList
|
||||
import java.util.EnumSet
|
||||
import java.util.HashMap
|
||||
|
||||
public data class JavaRoot(public val file: VirtualFile, public val type: JavaRoot.RootType) {
|
||||
public data class JavaRoot(public val file: VirtualFile, public val type: JavaRoot.RootType, public val prefixFqName: FqName? = null) {
|
||||
public enum class RootType {
|
||||
SOURCE,
|
||||
BINARY
|
||||
@@ -45,7 +45,7 @@ public class JvmDependenciesIndex(_roots: List<JavaRoot>) {
|
||||
private val roots: List<JavaRoot> by lazy { _roots.toList() }
|
||||
|
||||
private val maxIndex: Int
|
||||
get() = roots.size()
|
||||
get() = roots.size
|
||||
|
||||
// each "Cache" object corresponds to a package
|
||||
private class Cache {
|
||||
@@ -112,10 +112,12 @@ public class JvmDependenciesIndex(_roots: List<JavaRoot>) {
|
||||
if (request !is FindClassRequest || lastClassSearch == null) {
|
||||
return doSearch()
|
||||
}
|
||||
|
||||
val (cachedRequest, cachedResult) = lastClassSearch!!
|
||||
if (cachedRequest.classId != request.classId) {
|
||||
return doSearch()
|
||||
}
|
||||
|
||||
when (cachedResult) {
|
||||
is SearchResult.NotFound -> {
|
||||
val limitedRootTypes = request.acceptedRootTypes.toHashSet()
|
||||
@@ -165,7 +167,7 @@ public class JvmDependenciesIndex(_roots: List<JavaRoot>) {
|
||||
}
|
||||
|
||||
// a list of package sub names, ["org", "jb", "kotlin"]
|
||||
val packagesPath = request.packageFqName.pathSegments().map { it.getIdentifier() }
|
||||
val packagesPath = request.packageFqName.pathSegments().map { it.identifier }
|
||||
// a list of caches corresponding to packages, [default, "org", "org.jb", "org.jb.kotlin"]
|
||||
val caches = cachesPath(packagesPath)
|
||||
|
||||
@@ -190,6 +192,7 @@ public class JvmDependenciesIndex(_roots: List<JavaRoot>) {
|
||||
}
|
||||
processedRootsUpTo = cache.rootIndices.lastOrNull() ?: processedRootsUpTo
|
||||
}
|
||||
|
||||
return notFound()
|
||||
}
|
||||
|
||||
@@ -197,7 +200,7 @@ public class JvmDependenciesIndex(_roots: List<JavaRoot>) {
|
||||
// possibly filling "Cache" objects with new information
|
||||
private fun travelPath(rootIndex: Int, packagesPath: List<String>, fillCachesAfter: Int, cachesPath: List<Cache>): VirtualFile? {
|
||||
if (rootIndex >= maxIndex) {
|
||||
for (i in (fillCachesAfter + 1)..cachesPath.size() - 1) {
|
||||
for (i in (fillCachesAfter + 1)..(cachesPath.size - 1)) {
|
||||
// we all know roots that contain this package by now
|
||||
cachesPath[i].rootIndices.add(maxIndex)
|
||||
cachesPath[i].rootIndices.trimToSize()
|
||||
@@ -215,6 +218,7 @@ public class JvmDependenciesIndex(_roots: List<JavaRoot>) {
|
||||
cachesPath[correspondingCacheIndex].rootIndices.add(rootIndex)
|
||||
}
|
||||
}
|
||||
|
||||
return currentFile
|
||||
}
|
||||
|
||||
@@ -231,7 +235,7 @@ public class JvmDependenciesIndex(_roots: List<JavaRoot>) {
|
||||
|
||||
private data class FindClassRequest(val classId: ClassId, override val acceptedRootTypes: Set<JavaRoot.RootType>) : SearchRequest {
|
||||
override val packageFqName: FqName
|
||||
get() = classId.getPackageFqName()
|
||||
get() = classId.packageFqName
|
||||
}
|
||||
|
||||
private data class TraverseRequest(
|
||||
@@ -251,5 +255,5 @@ public class JvmDependenciesIndex(_roots: List<JavaRoot>) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun IntArrayList.lastOrNull() = if (isEmpty()) null else get(size() - 1)
|
||||
private val IntArrayList.indices: IntRange get() = 0..size()-1
|
||||
private fun IntArrayList.lastOrNull() = if (isEmpty) null else get(size() - 1)
|
||||
private val IntArrayList.indices: IntRange get() = 0..(size() - 1)
|
||||
@@ -75,6 +75,8 @@ import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinderFactory
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.isValidJavaFqName
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||
import org.jetbrains.kotlin.parsing.KotlinScriptDefinitionProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -167,12 +169,24 @@ public class KotlinCoreEnvironment private constructor(
|
||||
val virtualFile = contentRootToVirtualFile(javaRoot) ?: continue
|
||||
|
||||
projectEnvironment.addSourcesToClasspath(virtualFile)
|
||||
|
||||
val prefixPackageFqName = (javaRoot as? JavaSourceRoot)?.packagePrefix?.let {
|
||||
if (isValidJavaFqName(it)) {
|
||||
FqName(it)
|
||||
}
|
||||
else {
|
||||
report(WARNING, "Invalid package prefix name is ignored: $it")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
val rootType = when (javaRoot) {
|
||||
is JavaSourceRoot -> JavaRoot.RootType.SOURCE
|
||||
is JvmClasspathRoot -> JavaRoot.RootType.BINARY
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
javaRoots.add(JavaRoot(virtualFile, rootType))
|
||||
|
||||
javaRoots.add(JavaRoot(virtualFile, rootType, prefixPackageFqName))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -49,6 +49,7 @@ import org.jetbrains.kotlin.idea.MainFunctionDetector;
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager;
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache;
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents;
|
||||
import org.jetbrains.kotlin.modules.JavaRootPath;
|
||||
import org.jetbrains.kotlin.modules.Module;
|
||||
import org.jetbrains.kotlin.modules.TargetId;
|
||||
import org.jetbrains.kotlin.modules.TargetIdKt;
|
||||
@@ -183,8 +184,8 @@ public class KotlinToJVMBytecodeCompiler {
|
||||
}
|
||||
|
||||
for (Module module : chunk) {
|
||||
for (String javaSourceRoot : module.getJavaSourceRoots()) {
|
||||
JvmContentRootsKt.addJavaSourceRoot(configuration, new File(javaSourceRoot));
|
||||
for (JavaRootPath javaRootPath : module.getJavaSourceRoots()) {
|
||||
JvmContentRootsKt.addJavaSourceRoot(configuration, new File(javaRootPath.getPath()), javaRootPath.getPackagePrefix());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.io.File
|
||||
|
||||
public data class JvmClasspathRoot(public override val file: File): JvmContentRoot
|
||||
|
||||
public data class JavaSourceRoot(public override val file: File): JvmContentRoot
|
||||
public data class JavaSourceRoot(public override val file: File, public val packagePrefix: String?): JvmContentRoot
|
||||
|
||||
public interface JvmContentRoot : ContentRoot {
|
||||
public val file: File
|
||||
@@ -40,8 +40,10 @@ public val CompilerConfiguration.jvmClasspathRoots: List<File>
|
||||
return get(CommonConfigurationKeys.CONTENT_ROOTS)?.filterIsInstance<JvmClasspathRoot>()?.map { it.file } ?: emptyList()
|
||||
}
|
||||
|
||||
public fun CompilerConfiguration.addJavaSourceRoot(file: File) {
|
||||
add(CommonConfigurationKeys.CONTENT_ROOTS, JavaSourceRoot(file))
|
||||
@JvmOverloads
|
||||
public fun CompilerConfiguration.addJavaSourceRoot(file: File, packagePrefix: String? = null) {
|
||||
add(CommonConfigurationKeys.CONTENT_ROOTS, JavaSourceRoot(file, packagePrefix))
|
||||
}
|
||||
|
||||
public fun CompilerConfiguration.addJavaSourceRoots(files: List<File>): Unit = files.forEach { addJavaSourceRoot(it) }
|
||||
@JvmOverloads
|
||||
public fun CompilerConfiguration.addJavaSourceRoots(files: List<File>, packagePrefix: String? = null): Unit = files.forEach { addJavaSourceRoot(it, packagePrefix) }
|
||||
@@ -27,5 +27,7 @@ public interface Module {
|
||||
|
||||
public fun getClasspathRoots(): List<String>
|
||||
|
||||
public fun getJavaSourceRoots(): List<String>
|
||||
public fun getJavaSourceRoots(): List<JavaRootPath>
|
||||
}
|
||||
|
||||
data class JavaRootPath(val path: String, val packagePrefix: String? = null)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import java.io.File
|
||||
|
||||
data class JvmSourceRoot(val file: File, val packagePrefix: String? = null)
|
||||
+4
-3
@@ -127,13 +127,14 @@ public class KotlinBuilderModuleScriptGenerator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<File> findSourceRoots(@NotNull CompileContext context, @NotNull ModuleBuildTarget target) {
|
||||
private static List<JvmSourceRoot> findSourceRoots(@NotNull CompileContext context, @NotNull ModuleBuildTarget target) {
|
||||
List<JavaSourceRootDescriptor> roots = context.getProjectDescriptor().getBuildRootIndex().getTargetRoots(target, context);
|
||||
List<File> result = ContainerUtil.newArrayList();
|
||||
List<JvmSourceRoot> result = ContainerUtil.newArrayList();
|
||||
for (JavaSourceRootDescriptor root : roots) {
|
||||
File file = root.getRootFile();
|
||||
String prefix = root.getPackagePrefix();
|
||||
if (file.exists()) {
|
||||
result.add(file);
|
||||
result.add(new JvmSourceRoot(file, prefix.isEmpty() ? null : prefix));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.modules;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation;
|
||||
import org.jetbrains.kotlin.jps.build.JvmSourceRoot;
|
||||
import org.jetbrains.kotlin.utils.Printer;
|
||||
|
||||
import java.io.File;
|
||||
@@ -43,7 +44,7 @@ public class KotlinModuleXmlBuilder {
|
||||
String moduleName,
|
||||
String outputDir,
|
||||
List<File> sourceFiles,
|
||||
List<File> javaSourceRoots,
|
||||
List<JvmSourceRoot> javaSourceRoots,
|
||||
Collection<File> classpathRoots,
|
||||
JavaModuleBuildTargetType targetType,
|
||||
Set<File> directoriesToFilterOut
|
||||
@@ -100,10 +101,18 @@ public class KotlinModuleXmlBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private void processJavaSourceRoots(@NotNull List<File> files) {
|
||||
private void processJavaSourceRoots(@NotNull List<JvmSourceRoot> roots) {
|
||||
p.println("<!-- Java source roots -->");
|
||||
for (File file : files) {
|
||||
p.println("<", JAVA_SOURCE_ROOTS, " ", PATH, "=\"", getEscapedPath(file), "\"/>");
|
||||
for (JvmSourceRoot root : roots) {
|
||||
p.print("<");
|
||||
p.printWithNoIndent(JAVA_SOURCE_ROOTS, " ", PATH, "=\"", getEscapedPath(root.getFile()), "\"");
|
||||
|
||||
if (root.getPackagePrefix() != null) {
|
||||
p.printWithNoIndent(" ", JAVA_SOURCE_PACKAGE_PREFIX, "=\"", root.getPackagePrefix(), "\"");
|
||||
}
|
||||
|
||||
p.printWithNoIndent("/>");
|
||||
p.println();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.jvm.compiler
|
||||
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
|
||||
import org.jetbrains.kotlin.jps.build.JvmSourceRoot
|
||||
import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.MockLibraryUtil
|
||||
@@ -43,7 +44,7 @@ public class ClasspathOrderTest : TestCaseWithTmpdir() {
|
||||
"name",
|
||||
File(tmpdir, "output").getAbsolutePath(),
|
||||
listOf(sourceDir),
|
||||
listOf(sourceDir),
|
||||
listOf(JvmSourceRoot(sourceDir)),
|
||||
listOf(PathUtil.getKotlinPathsForDistDirectory().getRuntimePath()),
|
||||
JavaModuleBuildTargetType.PRODUCTION,
|
||||
setOf()
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.modules;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
|
||||
import org.jetbrains.kotlin.jps.build.JvmSourceRoot;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
|
||||
import java.io.File;
|
||||
@@ -30,7 +31,7 @@ public class KotlinModuleXmlGeneratorTest extends TestCase {
|
||||
"name",
|
||||
"output",
|
||||
Arrays.asList(new File("s1"), new File("s2")),
|
||||
Collections.singletonList(new File("java")),
|
||||
Collections.singletonList(new JvmSourceRoot(new File("java"), null)),
|
||||
Arrays.asList(new File("cp1"), new File("cp2")),
|
||||
JavaModuleBuildTargetType.PRODUCTION,
|
||||
Collections.<File>emptySet()
|
||||
@@ -43,7 +44,7 @@ public class KotlinModuleXmlGeneratorTest extends TestCase {
|
||||
"name",
|
||||
"output",
|
||||
Arrays.asList(new File("s1"), new File("s2")),
|
||||
Collections.<File>emptyList(),
|
||||
Collections.<JvmSourceRoot>emptyList(),
|
||||
Arrays.asList(new File("cp1"), new File("cp2")),
|
||||
JavaModuleBuildTargetType.PRODUCTION,
|
||||
Collections.singleton(new File("cp1"))
|
||||
@@ -57,7 +58,7 @@ public class KotlinModuleXmlGeneratorTest extends TestCase {
|
||||
"name",
|
||||
"output",
|
||||
Arrays.asList(new File("s1"), new File("s2")),
|
||||
Collections.<File>emptyList(),
|
||||
Collections.<JvmSourceRoot>emptyList(),
|
||||
Arrays.asList(new File("cp1"), new File("cp2")),
|
||||
JavaModuleBuildTargetType.PRODUCTION,
|
||||
Collections.singleton(new File("cp1"))
|
||||
@@ -66,7 +67,7 @@ public class KotlinModuleXmlGeneratorTest extends TestCase {
|
||||
"name2",
|
||||
"output2",
|
||||
Arrays.asList(new File("s12"), new File("s22")),
|
||||
Collections.<File>emptyList(),
|
||||
Collections.<JvmSourceRoot>emptyList(),
|
||||
Arrays.asList(new File("cp12"), new File("cp22")),
|
||||
JavaModuleBuildTargetType.TEST,
|
||||
Collections.singleton(new File("cp12"))
|
||||
|
||||
Reference in New Issue
Block a user