Module mapping generation
This commit is contained in:
@@ -24,22 +24,24 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.*;
|
||||
|
||||
public class ClassFileFactory implements OutputFileCollection {
|
||||
private final GenerationState state;
|
||||
private final ClassBuilderFactory builderFactory;
|
||||
private final Map<FqName, PackageCodegen> package2codegen = new HashMap<FqName, PackageCodegen>();
|
||||
private final Map<String, ClassBuilderAndSourceFileList> generators = new LinkedHashMap<String, ClassBuilderAndSourceFileList>();
|
||||
private final Map<String, OutAndSourceFileList> generators = new LinkedHashMap<String, OutAndSourceFileList>();
|
||||
|
||||
private boolean isDone = false;
|
||||
|
||||
@@ -72,12 +74,41 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
void done() {
|
||||
if (!isDone) {
|
||||
isDone = true;
|
||||
for (PackageCodegen codegen : package2codegen.values()) {
|
||||
Collection<PackageCodegen> values = package2codegen.values();
|
||||
for (PackageCodegen codegen : values) {
|
||||
codegen.done();
|
||||
}
|
||||
|
||||
writeModuleMappings(values);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeModuleMappings(Collection<PackageCodegen> values) {
|
||||
String outputFilePath = "META-INF/module.mapping";
|
||||
final StringWriter moduleMapping = new StringWriter(1024);
|
||||
for (PackageCodegen codegen : values) {
|
||||
codegen.getFacades().serialize(moduleMapping);
|
||||
}
|
||||
state.getProgress().reportOutput(Collections.<File>emptyList(), new File(outputFilePath));
|
||||
//TODO: source files?
|
||||
generators.put(outputFilePath, new OutAndSourceFileList(Collections.<File>emptyList()) {
|
||||
@Override
|
||||
public byte[] asBytes(ClassBuilderFactory factory) {
|
||||
try {
|
||||
return moduleMapping.toString().getBytes("UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asText(ClassBuilderFactory factory) {
|
||||
return moduleMapping.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<OutputFile> asList() {
|
||||
@@ -163,7 +194,7 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<File> getSourceFiles() {
|
||||
ClassBuilderAndSourceFileList pair = generators.get(relativeClassFilePath);
|
||||
OutAndSourceFileList pair = generators.get(relativeClassFilePath);
|
||||
if (pair == null) {
|
||||
throw new IllegalStateException("No record for binary file " + relativeClassFilePath);
|
||||
}
|
||||
@@ -174,13 +205,13 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
@NotNull
|
||||
@Override
|
||||
public byte[] asByteArray() {
|
||||
return builderFactory.asBytes(generators.get(relativeClassFilePath).classBuilder);
|
||||
return generators.get(relativeClassFilePath).asBytes(builderFactory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String asText() {
|
||||
return builderFactory.asText(generators.get(relativeClassFilePath).classBuilder);
|
||||
return generators.get(relativeClassFilePath).asText(builderFactory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -190,14 +221,36 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ClassBuilderAndSourceFileList {
|
||||
private static final class ClassBuilderAndSourceFileList extends OutAndSourceFileList {
|
||||
private final ClassBuilder classBuilder;
|
||||
private final List<File> sourceFiles;
|
||||
|
||||
private ClassBuilderAndSourceFileList(ClassBuilder classBuilder, List<File> sourceFiles) {
|
||||
super(sourceFiles);
|
||||
this.classBuilder = classBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] asBytes(ClassBuilderFactory factory) {
|
||||
return factory.asBytes(classBuilder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asText(ClassBuilderFactory factory) {
|
||||
return factory.asText(classBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class OutAndSourceFileList {
|
||||
|
||||
protected final List<File> sourceFiles;
|
||||
|
||||
private OutAndSourceFileList(List<File> sourceFiles) {
|
||||
this.sourceFiles = sourceFiles;
|
||||
}
|
||||
|
||||
public abstract byte[] asBytes(ClassBuilderFactory factory);
|
||||
|
||||
public abstract String asText(ClassBuilderFactory factory);
|
||||
}
|
||||
|
||||
public void removeInlinedClasses(Set<String> classNamesToRemove) {
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.context.PackageContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageFacades;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
@@ -83,6 +84,8 @@ public class PackageCodegen {
|
||||
private final PackageFragmentDescriptor compiledPackageFragment;
|
||||
private final List<DeserializedCallableMemberDescriptor> previouslyCompiledCallables;
|
||||
|
||||
private final PackageFacades facades;
|
||||
|
||||
public PackageCodegen(@NotNull GenerationState state, @NotNull Collection<JetFile> files, @NotNull FqName fqName) {
|
||||
this.state = state;
|
||||
this.files = files;
|
||||
@@ -117,6 +120,7 @@ public class PackageCodegen {
|
||||
return v;
|
||||
}
|
||||
});
|
||||
facades = new PackageFacades(fqName.asString().replaceAll("\\.", "/"));
|
||||
}
|
||||
|
||||
// Returns null if file has callables in several files
|
||||
@@ -329,8 +333,11 @@ public class PackageCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!generatePackagePart || !state.getGenerateDeclaredClassFilter().shouldGeneratePackagePart(file)) return null;
|
||||
|
||||
facades.getParts().add(packagePartType.getInternalName());
|
||||
|
||||
ClassBuilder builder = state.getFactory().newVisitor(PackagePart(file, packageFragment), packagePartType, file);
|
||||
|
||||
new PackagePartCodegen(builder, file, packagePartType, packagePartContext, state).generate();
|
||||
@@ -412,4 +419,8 @@ public class PackageCodegen {
|
||||
public void done() {
|
||||
v.done();
|
||||
}
|
||||
|
||||
public PackageFacades getFacades() {
|
||||
return facades;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.load.kotlin
|
||||
|
||||
import java.io.Writer
|
||||
|
||||
public class ModuleMapping(val moduleMapping: String) {
|
||||
|
||||
val package2MiniFacades = hashMapOf<String, PackageFacades>()
|
||||
|
||||
init {
|
||||
for (i in moduleMapping.split("\n")) {
|
||||
if(i.isEmpty()) continue
|
||||
val (pakage, facade) = i.split("->")
|
||||
val miniFacades = package2MiniFacades.getOrPut(pakage, { PackageFacades(pakage) })
|
||||
miniFacades.parts.add(facade)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PackageFacades(val internalName: String) {
|
||||
|
||||
val parts = hashSetOf<String>()
|
||||
|
||||
fun serialize(out: Writer) {
|
||||
for (i in parts) {
|
||||
out.write("$internalName->$i\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user