Rework BuiltInsSerializer
BuiltInsSerializer will be distributed with Kotlin compiler from now on. This will allow to serialize binary data of built-ins on 'ant dist', as opposed to storing all *.kotlin_class files in the repository: ant dist will just invoke this serializer from bootstrap-compiler.jar
This commit is contained in:
@@ -1,168 +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.generators.builtins;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.config.CompilerConfiguration;
|
||||
import org.jetbrains.jet.descriptors.serialization.*;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.LazyResolveTestUtil;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.lang.BuiltInsSerializationUtil;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.test.util.DescriptorValidator;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class BuiltInsSerializer {
|
||||
private static final String BUILT_INS_SRC_DIR = "idea/builtinsSrc";
|
||||
public static final String DEST_DIR = "compiler/frontend/builtins";
|
||||
|
||||
private static int totalSize = 0;
|
||||
private static int totalFiles = 0;
|
||||
|
||||
private BuiltInsSerializer() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
System.setProperty("java.awt.headless", "true");
|
||||
serializeToDir(new File(DEST_DIR), System.out);
|
||||
}
|
||||
|
||||
public static void serializeToDir(final File destDir, @Nullable final PrintStream out) throws IOException {
|
||||
Disposable rootDisposable = Disposer.newDisposable();
|
||||
try {
|
||||
List<File> sourceFiles = FileUtil.findFilesByMask(Pattern.compile(".*\\.kt"), new File(BUILT_INS_SRC_DIR));
|
||||
CompilerConfiguration configuration = new CompilerConfiguration();
|
||||
JetCoreEnvironment environment = JetCoreEnvironment.createForTests(rootDisposable, configuration);
|
||||
List<JetFile> files = JetTestUtils.loadToJetFiles(environment, sourceFiles);
|
||||
|
||||
ModuleDescriptor module = LazyResolveTestUtil.resolveLazily(files, environment, false);
|
||||
PackageViewDescriptor packageView = module.getPackage(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME);
|
||||
assert packageView != null : "Package not found: " + KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME;
|
||||
|
||||
DescriptorValidator.validate(packageView);
|
||||
|
||||
if (!FileUtil.delete(destDir)) {
|
||||
System.err.println("Could not delete: " + destDir);
|
||||
}
|
||||
if (!destDir.mkdirs()) {
|
||||
System.err.println("Could not make directories: " + destDir);
|
||||
}
|
||||
|
||||
DescriptorSerializer serializer = new DescriptorSerializer(new SerializerExtension() {
|
||||
private final ImmutableSet<String> set = ImmutableSet.of("Any", "Nothing");
|
||||
|
||||
@Override
|
||||
public boolean hasSupertypes(@NotNull ClassDescriptor classDescriptor) {
|
||||
return !set.contains(classDescriptor.getName().asString());
|
||||
}
|
||||
});
|
||||
|
||||
final List<Name> classNames = new ArrayList<Name>();
|
||||
List<DeclarationDescriptor> allDescriptors = DescriptorSerializer.sort(packageView.getMemberScope().getAllDescriptors());
|
||||
ClassSerializationUtil.serializeClasses(allDescriptors, serializer, new ClassSerializationUtil.Sink() {
|
||||
@Override
|
||||
public void writeClass(@NotNull ClassDescriptor classDescriptor, @NotNull ProtoBuf.Class classProto) {
|
||||
try {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
classProto.writeTo(stream);
|
||||
write(destDir, getFileName(classDescriptor), stream, out);
|
||||
|
||||
if (DescriptorUtils.isTopLevelDeclaration(classDescriptor)) {
|
||||
classNames.add(classDescriptor.getName());
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ByteArrayOutputStream classNamesStream = new ByteArrayOutputStream();
|
||||
writeClassNames(serializer, classNames, classNamesStream);
|
||||
write(destDir, BuiltInsSerializationUtil.getClassNamesFilePath(packageView.getFqName()), classNamesStream, out);
|
||||
|
||||
ByteArrayOutputStream packageStream = new ByteArrayOutputStream();
|
||||
List<PackageFragmentDescriptor> fragments =
|
||||
module.getPackageFragmentProvider().getPackageFragments(packageView.getFqName());
|
||||
ProtoBuf.Package packageProto = serializer.packageProto(fragments).build();
|
||||
packageProto.writeTo(packageStream);
|
||||
write(destDir, BuiltInsSerializationUtil.getPackageFilePath(packageView.getFqName()), packageStream, out);
|
||||
|
||||
ByteArrayOutputStream nameStream = new ByteArrayOutputStream();
|
||||
NameSerializationUtil.serializeNameTable(nameStream, serializer.getNameTable());
|
||||
write(destDir, BuiltInsSerializationUtil.getNameTableFilePath(packageView.getFqName()), nameStream, out);
|
||||
|
||||
if (out != null) {
|
||||
out.println("Total bytes written: " + totalSize + " to " + totalFiles + " files");
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Disposer.dispose(rootDisposable);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeClassNames(
|
||||
@NotNull DescriptorSerializer serializer,
|
||||
@NotNull List<Name> classNames,
|
||||
@NotNull ByteArrayOutputStream stream
|
||||
) throws IOException {
|
||||
DataOutputStream data = new DataOutputStream(stream);
|
||||
try {
|
||||
data.writeInt(classNames.size());
|
||||
for (Name className : classNames) {
|
||||
int index = serializer.getNameTable().getSimpleNameIndex(className);
|
||||
data.writeInt(index);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
data.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void write(
|
||||
@NotNull File destDir,
|
||||
@NotNull String fileName,
|
||||
@NotNull ByteArrayOutputStream stream,
|
||||
@Nullable PrintStream out
|
||||
) throws IOException {
|
||||
totalSize += stream.size();
|
||||
totalFiles++;
|
||||
FileUtil.writeToFile(new File(destDir, fileName), stream.toByteArray());
|
||||
if (out != null) {
|
||||
out.println(stream.size() + " bytes written to " + fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getFileName(@NotNull ClassDescriptor classDescriptor) {
|
||||
return BuiltInsSerializationUtil.getClassMetadataPath(ClassSerializationUtil.getClassId(classDescriptor));
|
||||
}
|
||||
}
|
||||
@@ -1,61 +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.generators.builtins
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import com.intellij.util.Function
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.jet.JetTestUtils
|
||||
import java.io.File
|
||||
import java.util.Arrays
|
||||
import java.util.HashSet
|
||||
import java.util.regex.Pattern
|
||||
import junit.framework.Assert
|
||||
|
||||
public open class BuiltInsSerializerTest() : UsefulTestCase() {
|
||||
public fun testBuiltIns() {
|
||||
val actual = JetTestUtils.tmpDir("builtins")
|
||||
BuiltInsSerializer.serializeToDir(actual, null)
|
||||
|
||||
val expected = File(BuiltInsSerializer.DEST_DIR)
|
||||
|
||||
val actualFiles = getAllFiles(actual)
|
||||
val expectedFiles = getAllFiles(expected)
|
||||
|
||||
val actualNames = getFileNames(actualFiles)
|
||||
val expectedNames = getFileNames(expectedFiles)
|
||||
|
||||
Assert.assertEquals("File name sets differ. Re-run BuiltInsSerializer", expectedNames, actualNames)
|
||||
for (actualFile in actualFiles) {
|
||||
if (actualFile.isDirectory()) continue
|
||||
|
||||
val relativePath = FileUtil.getRelativePath(actual, actualFile)!!
|
||||
val expectedFile = File(expected, relativePath)
|
||||
|
||||
val expectedBytes = FileUtil.loadFileBytes(expectedFile)
|
||||
val actualBytes = FileUtil.loadFileBytes(actualFile)
|
||||
Assert.assertTrue("File contents differ for $expectedFile and $actualFile. Re-run BuiltInsSerializer",
|
||||
Arrays.equals(expectedBytes, actualBytes))
|
||||
}
|
||||
println("${actualFiles.size()} files checked")
|
||||
}
|
||||
|
||||
private fun getAllFiles(actual: File): List<File> = FileUtil.findFilesByMask(Pattern.compile(".*"), actual)
|
||||
|
||||
private fun getFileNames(actualFiles: List<File>): Set<String> = HashSet(ContainerUtil.map(actualFiles, {f -> f!!.getName()}))
|
||||
}
|
||||
Reference in New Issue
Block a user