Split OutputFileFactory to OutputFileCollection and OutputFile

This commit is contained in:
Zalim Bashorov
2013-11-08 12:21:07 +04:00
parent e041e950c8
commit ae8ac28ddc
5 changed files with 97 additions and 91 deletions
@@ -18,10 +18,14 @@ package org.jetbrains.jet
import java.io.File import java.io.File
public trait OutputFileFactory { public trait OutputFileCollection {
public val outputFiles: List<String> public fun get(relativePath: String): OutputFile?
public fun asList(): List<OutputFile>
}
public fun getSourceFiles(file: String): List<File> public trait OutputFile {
public fun asBytes(file: String): ByteArray public val relativePath: String
public fun asText(file: String): String public val sourceFiles: List<File>
public fun asByteArray(): ByteArray
public fun asText(): String
} }
@@ -1,38 +0,0 @@
/*
* Copyright 2010-2013 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.jet.outputUtils
import java.io.File
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.jet.OutputFileFactory
import org.jetbrains.jet.SingleDirectoryDirector
import org.jetbrains.jet.OutputDirector
public fun OutputFileFactory.writeAll(outputDirector: OutputDirector, report: (sources: List<File>, output: File) -> Unit) {
for (file in outputFiles) {
val sources = getSourceFiles(file)
val output = File(outputDirector.getOutputDirectory(sources), file)
report(sources, output)
FileUtil.writeToFile(output, this.asBytes(file))
}
}
private val REPORT_NOTHING = { (sources: List<File>, output: File) -> }
public inline fun OutputFileFactory.writeAllTo(outputDir: File) {
writeAll(SingleDirectoryDirector(outputDir), REPORT_NOTHING)
}
@@ -23,8 +23,10 @@ import com.intellij.psi.PsiFile;
import com.intellij.util.Function; import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type; import org.jetbrains.asm4.Type;
import org.jetbrains.jet.OutputFileFactory; import org.jetbrains.jet.OutputFile;
import org.jetbrains.jet.OutputFileCollection;
import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.GenerationStateAware; import org.jetbrains.jet.codegen.state.GenerationStateAware;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
@@ -39,7 +41,7 @@ import static org.jetbrains.jet.codegen.AsmUtil.asmTypeByFqNameWithoutInnerClass
import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive; import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.jet.lang.resolve.java.PackageClassUtils.getPackageClassFqName; import static org.jetbrains.jet.lang.resolve.java.PackageClassUtils.getPackageClassFqName;
public final class ClassFileFactory extends GenerationStateAware implements OutputFileFactory { public final class ClassFileFactory extends GenerationStateAware implements OutputFileCollection {
@NotNull private ClassBuilderFactory builderFactory; @NotNull private ClassBuilderFactory builderFactory;
private final Map<FqName, NamespaceCodegen> ns2codegen = new HashMap<FqName, NamespaceCodegen>(); private final Map<FqName, NamespaceCodegen> ns2codegen = new HashMap<FqName, NamespaceCodegen>();
@@ -50,7 +52,6 @@ public final class ClassFileFactory extends GenerationStateAware implements Outp
super(state); super(state);
} }
@Inject @Inject
public void setBuilderFactory(@NotNull ClassBuilderFactory builderFactory) { public void setBuilderFactory(@NotNull ClassBuilderFactory builderFactory) {
this.builderFactory = builderFactory; this.builderFactory = builderFactory;
@@ -80,53 +81,30 @@ public final class ClassFileFactory extends GenerationStateAware implements Outp
} }
@Override @Override
public String asText(String file) { public List<OutputFile> asList() {
done(); done();
return builderFactory.asText(generators.get(file).classBuilder); return ContainerUtil.map(generators.keySet(), new Function<String, OutputFile>() {
@Override
public OutputFile fun(String relativeClassFilePath) {
return new OutputClassFile(relativeClassFilePath);
}
});
} }
@Override @Override
public byte[] asBytes(String file) { @Nullable
done(); public OutputFile get(@NotNull String relativePath) {
return builderFactory.asBytes(generators.get(file).classBuilder); if (generators.containsKey(relativePath)) return new OutputClassFile(relativePath);
}
@Override return null;
public List<String> getOutputFiles() {
done();
return new ArrayList<String>(generators.keySet());
}
@Override
public List<File> getSourceFiles(String relativeClassFilePath) {
ClassBuilderAndSourceFileList pair = generators.get(relativeClassFilePath);
if (pair == null) {
throw new IllegalStateException("No record for binary file " + relativeClassFilePath);
}
return ContainerUtil.mapNotNull(
pair.sourceFiles,
new Function<PsiFile, File>() {
@Override
public File fun(PsiFile file) {
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile == null) return null;
return VfsUtilCore.virtualToIoFile(virtualFile);
}
}
);
} }
public String createText() { public String createText() {
StringBuilder answer = new StringBuilder(); StringBuilder answer = new StringBuilder();
List<String> files = getOutputFiles(); for (OutputFile file : asList()) {
for (String file : files) { answer.append("@").append(file.getRelativePath()).append('\n');
// if (!file.startsWith("kotlin/")) { answer.append(file.asText());
answer.append("@").append(file).append('\n');
answer.append(asText(file));
// }
} }
return answer.toString(); return answer.toString();
@@ -181,7 +159,53 @@ public final class ClassFileFactory extends GenerationStateAware implements Outp
return result; return result;
} }
private static class ClassBuilderAndSourceFileList { private final class OutputClassFile implements OutputFile {
final String relativeClassFilePath;
OutputClassFile(String relativeClassFilePath) {
this.relativeClassFilePath = relativeClassFilePath;
}
@Override
public String getRelativePath() {
return relativeClassFilePath;
}
@Override
public List<File> getSourceFiles() {
ClassBuilderAndSourceFileList pair = generators.get(relativeClassFilePath);
if (pair == null) {
throw new IllegalStateException("No record for binary file " + relativeClassFilePath);
}
return ContainerUtil.mapNotNull(
pair.sourceFiles,
new Function<PsiFile, File>() {
@Override
public File fun(PsiFile file) {
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile == null) return null;
return VfsUtilCore.virtualToIoFile(virtualFile);
}
}
);
}
@Override
public byte[] asByteArray() {
done();
return builderFactory.asBytes(generators.get(relativeClassFilePath).classBuilder);
}
@Override
public String asText() {
done();
return builderFactory.asText(generators.get(relativeClassFilePath).classBuilder);
}
}
private static final class ClassBuilderAndSourceFileList {
private final ClassBuilder classBuilder; private final ClassBuilder classBuilder;
private final Collection<? extends PsiFile> sourceFiles; private final Collection<? extends PsiFile> sourceFiles;
@@ -190,5 +214,4 @@ public final class ClassFileFactory extends GenerationStateAware implements Outp
this.sourceFiles = sourceFiles; this.sourceFiles = sourceFiles;
} }
} }
} }
@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.jet package org.jetbrains.jet.cli.common.output
import java.io.File import java.io.File
@@ -14,17 +14,34 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.jet.cli.common.outputUtils package org.jetbrains.jet.cli.common.output.outputUtils
import org.jetbrains.jet.OutputFileFactory import org.jetbrains.jet.OutputFileCollection
import org.jetbrains.jet.OutputDirector
import org.jetbrains.jet.outputUtils.writeAll
import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation
import org.jetbrains.jet.cli.common.messages.OutputMessageUtil import org.jetbrains.jet.cli.common.messages.OutputMessageUtil
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.jet.cli.common.messages.MessageCollector import org.jetbrains.jet.cli.common.messages.MessageCollector
import org.jetbrains.jet.cli.common.output.OutputDirector
import java.io.File
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.jet.cli.common.output.SingleDirectoryDirector
public inline fun OutputFileFactory.writeAll(outputDirector: OutputDirector, messageCollector: MessageCollector) { public fun OutputFileCollection.writeAll(outputDirector: OutputDirector, report: (sources: List<File>, output: File) -> Unit) {
for (file in asList()) {
val sources = file.sourceFiles
val output = File(outputDirector.getOutputDirectory(sources), file.relativePath)
report(sources, output)
FileUtil.writeToFile(output, file.asByteArray())
}
}
private val REPORT_NOTHING = { (sources: List<File>, output: File) -> }
public inline fun OutputFileCollection.writeAllTo(outputDir: File) {
writeAll(SingleDirectoryDirector(outputDir), REPORT_NOTHING)
}
public inline fun OutputFileCollection.writeAll(outputDirector: OutputDirector, messageCollector: MessageCollector) {
writeAll(outputDirector) { sources, output -> writeAll(outputDirector) { sources, output ->
messageCollector.report(CompilerMessageSeverity.OUTPUT, OutputMessageUtil.formatOutputMessage(sources, output), CompilerMessageLocation.NO_LOCATION) messageCollector.report(CompilerMessageSeverity.OUTPUT, OutputMessageUtil.formatOutputMessage(sources, output), CompilerMessageLocation.NO_LOCATION)
} }