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:
Anton Bannykh
2017-03-30 15:03:38 +03:00
parent 7bbf9861d0
commit 2e9a59819a
48 changed files with 765 additions and 133 deletions
@@ -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);
}