JS: support internal visibility from friend modules
Friend modules should be provided using the -Xfriend-modules flag in the same format as -libraries. No manual configuration required for JPS, Gradle and Maven plugins. Friend modules could be switched off using the -Xfriend-modules-disabled flag. Doing that will * prevent internal declarations from being exported, * values provided by -Xfriend-modules ignored, * raise a compilation error on attemps to use internal declarations from other modules Fixes #KT-15135 and #KT-16568.
This commit is contained in:
+5
-3
@@ -46,10 +46,12 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KotlinTestWithEn
|
||||
public class ModuleAndDependencies {
|
||||
final M module;
|
||||
final List<String> dependencies;
|
||||
final List<String> friends;
|
||||
|
||||
ModuleAndDependencies(M module, List<String> dependencies) {
|
||||
ModuleAndDependencies(M module, List<String> dependencies, List<String> friends) {
|
||||
this.module = module;
|
||||
this.dependencies = dependencies;
|
||||
this.friends = friends;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,9 +131,9 @@ public abstract class KotlinMultiFileTestWithJava<M, F> extends KotlinTestWithEn
|
||||
}
|
||||
|
||||
@Override
|
||||
public M createModule(@NotNull String name, @NotNull List<String> dependencies) {
|
||||
public M createModule(@NotNull String name, @NotNull List<String> dependencies, @NotNull List<String> friends) {
|
||||
M module = createTestModule(name);
|
||||
ModuleAndDependencies oldValue = modules.put(name, new ModuleAndDependencies(module, dependencies));
|
||||
ModuleAndDependencies oldValue = modules.put(name, new ModuleAndDependencies(module, dependencies, friends));
|
||||
assert oldValue == null : "Module " + name + " declared more than once";
|
||||
|
||||
return module;
|
||||
|
||||
@@ -118,7 +118,7 @@ public class KotlinTestUtils {
|
||||
private static final String MODULE_DELIMITER = ",\\s*";
|
||||
|
||||
private static final Pattern FILE_OR_MODULE_PATTERN = Pattern.compile(
|
||||
"(?://\\s*MODULE:\\s*([^()\\n]+)(?:\\(([^()]+(?:" + MODULE_DELIMITER + "[^()]+)*)\\))?\\s*)?" +
|
||||
"(?://\\s*MODULE:\\s*([^()\\n]+)(?:\\(([^()]+(?:" + MODULE_DELIMITER + "[^()]+)*)\\))?\\s*(?:\\(([^()]+(?:" + MODULE_DELIMITER + "[^()]+)*)\\))?\\s*)?" +
|
||||
"//\\s*FILE:\\s*(.*)$", Pattern.MULTILINE);
|
||||
private static final Pattern DIRECTIVE_PATTERN = Pattern.compile("^//\\s*!([\\w_]+)(:\\s*(.*)$)?", Pattern.MULTILINE);
|
||||
|
||||
@@ -610,7 +610,7 @@ public class KotlinTestUtils {
|
||||
|
||||
public interface TestFileFactory<M, F> {
|
||||
F createFile(@Nullable M module, @NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives);
|
||||
M createModule(@NotNull String name, @NotNull List<String> dependencies);
|
||||
M createModule(@NotNull String name, @NotNull List<String> dependencies, @NotNull List<String> friends);
|
||||
}
|
||||
|
||||
public static abstract class TestFileFactoryNoModules<F> implements TestFileFactory<Void, F> {
|
||||
@@ -628,7 +628,7 @@ public class KotlinTestUtils {
|
||||
public abstract F create(@NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives);
|
||||
|
||||
@Override
|
||||
public Void createModule(@NotNull String name, @NotNull List<String> dependencies) {
|
||||
public Void createModule(@NotNull String name, @NotNull List<String> dependencies, @NotNull List<String> friends) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -651,12 +651,13 @@ public class KotlinTestUtils {
|
||||
while (true) {
|
||||
String moduleName = matcher.group(1);
|
||||
String moduleDependencies = matcher.group(2);
|
||||
String moduleFriends = matcher.group(3);
|
||||
if (moduleName != null) {
|
||||
hasModules = true;
|
||||
module = factory.createModule(moduleName, parseDependencies(moduleDependencies));
|
||||
module = factory.createModule(moduleName, parseModuleList(moduleDependencies), parseModuleList(moduleFriends));
|
||||
}
|
||||
|
||||
String fileName = matcher.group(3);
|
||||
String fileName = matcher.group(4);
|
||||
int start = processedChars;
|
||||
|
||||
boolean nextFileExists = matcher.find();
|
||||
@@ -681,7 +682,7 @@ public class KotlinTestUtils {
|
||||
}
|
||||
|
||||
if (isDirectiveDefined(expectedText, "WITH_COROUTINES")) {
|
||||
M supportModule = hasModules ? factory.createModule("support", Collections.emptyList()) : null;
|
||||
M supportModule = hasModules ? factory.createModule("support", Collections.emptyList(), Collections.emptyList()) : null;
|
||||
testFiles.add(factory.createFile(supportModule,
|
||||
"CoroutineUtil.kt",
|
||||
"import kotlin.coroutines.experimental.*\n" +
|
||||
@@ -715,7 +716,7 @@ public class KotlinTestUtils {
|
||||
return testFiles;
|
||||
}
|
||||
|
||||
private static List<String> parseDependencies(@Nullable String dependencies) {
|
||||
private static List<String> parseModuleList(@Nullable String dependencies) {
|
||||
if (dependencies == null) return Collections.emptyList();
|
||||
return StringsKt.split(dependencies, Pattern.compile(MODULE_DELIMITER), 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user