diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/header/KotlinClassFileHeader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/header/KotlinClassFileHeader.java
index 85a899c0b9e..8815cea621f 100644
--- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/header/KotlinClassFileHeader.java
+++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/header/KotlinClassFileHeader.java
@@ -36,63 +36,45 @@ import java.util.List;
import static org.jetbrains.asm4.ClassReader.*;
import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCompatible;
-public final class KotlinClassFileHeader {
+public abstract class KotlinClassFileHeader {
private static final Logger LOG = Logger.getInstance(KotlinClassFileHeader.class);
@Nullable
public static KotlinClassFileHeader readKotlinHeaderFromClassFile(@NotNull VirtualFile virtualFile) {
try {
ClassReader reader = new ClassReader(virtualFile.contentsToByteArray());
- ReadDataFromAnnotationVisitor visitor = new ReadDataFromAnnotationVisitor();
- reader.accept(visitor, SKIP_CODE | SKIP_FRAMES | SKIP_DEBUG);
- if (visitor.foundType == null) {
+ ReadDataFromAnnotationVisitor v = new ReadDataFromAnnotationVisitor();
+ reader.accept(v, SKIP_CODE | SKIP_FRAMES | SKIP_DEBUG);
+ if (v.foundType == null) {
return null;
}
- if (visitor.fqName == null) {
+ if (v.fqName == null) {
LOG.error("File doesn't have a class name: " + virtualFile);
return null;
}
- return new KotlinClassFileHeader(visitor.version, visitor.annotationData, visitor.foundType, visitor.fqName);
+
+ switch (v.foundType) {
+ case CLASS:
+ return SerializedDataHeader.create(v.version, v.annotationData, SerializedDataHeader.Kind.CLASS, v.fqName);
+ case PACKAGE:
+ return SerializedDataHeader.create(v.version, v.annotationData, SerializedDataHeader.Kind.PACKAGE, v.fqName);
+ case OLD_CLASS:
+ case OLD_PACKAGE:
+ return new OldAnnotationHeader(v.fqName);
+ default:
+ throw new UnsupportedOperationException("Unknown HeaderType: " + v.foundType);
+ }
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
- @SuppressWarnings("deprecation")
- public enum HeaderType {
- CLASS(JvmAnnotationNames.KOTLIN_CLASS),
- PACKAGE(JvmAnnotationNames.KOTLIN_PACKAGE),
- OLD_CLASS(JvmAnnotationNames.OLD_JET_CLASS_ANNOTATION),
- OLD_PACKAGE(JvmAnnotationNames.OLD_JET_PACKAGE_CLASS_ANNOTATION);
-
- @NotNull
- private final JvmClassName annotation;
-
- private HeaderType(@NotNull JvmClassName annotation) {
- this.annotation = annotation;
- }
-
- @Nullable
- private static HeaderType byDescriptor(@NotNull String desc) {
- for (HeaderType headerType : HeaderType.values()) {
- if (desc.equals(headerType.annotation.getDescriptor())) {
- return headerType;
- }
- }
- return null;
- }
- }
-
private final int version;
- private final String[] annotationData;
- private final HeaderType type;
private final FqName fqName;
- private KotlinClassFileHeader(int version, @Nullable String[] annotationData, @NotNull HeaderType type, @NotNull FqName fqName) {
+ protected KotlinClassFileHeader(int version, @NotNull FqName fqName) {
this.version = version;
- this.annotationData = annotationData;
- this.type = type;
this.fqName = fqName;
}
@@ -100,20 +82,6 @@ public final class KotlinClassFileHeader {
return version;
}
- @Nullable
- public String[] getAnnotationData() {
- if (isCompatibleKotlinCompiledFile() && annotationData == null) {
- LOG.error("Kotlin annotation " + type + " is incorrect for class: " + fqName);
- return null;
- }
- return annotationData;
- }
-
- @NotNull
- public HeaderType getType() {
- return type;
- }
-
/**
* @return FQ name for class header or package class FQ name for package header (e.g. test.TestPackage)
*/
@@ -126,10 +94,35 @@ public final class KotlinClassFileHeader {
* @return true if this is a header for compiled Kotlin file with correct abi version which can be processed by compiler or the IDE
*/
public boolean isCompatibleKotlinCompiledFile() {
- return (type == HeaderType.CLASS || type == HeaderType.PACKAGE) && isAbiVersionCompatible(version);
+ return isAbiVersionCompatible(version);
}
private static class ReadDataFromAnnotationVisitor extends ClassVisitor {
+ @SuppressWarnings("deprecation")
+ private enum HeaderType {
+ CLASS(JvmAnnotationNames.KOTLIN_CLASS),
+ PACKAGE(JvmAnnotationNames.KOTLIN_PACKAGE),
+ OLD_CLASS(JvmAnnotationNames.OLD_JET_CLASS_ANNOTATION),
+ OLD_PACKAGE(JvmAnnotationNames.OLD_JET_PACKAGE_CLASS_ANNOTATION);
+
+ @NotNull
+ private final JvmClassName annotation;
+
+ private HeaderType(@NotNull JvmClassName annotation) {
+ this.annotation = annotation;
+ }
+
+ @Nullable
+ private static HeaderType byDescriptor(@NotNull String desc) {
+ for (HeaderType headerType : HeaderType.values()) {
+ if (desc.equals(headerType.annotation.getDescriptor())) {
+ return headerType;
+ }
+ }
+ return null;
+ }
+ }
+
private int version = AbiVersionUtil.INVALID_VERSION;
@Nullable
private String[] annotationData = null;
diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/header/OldAnnotationHeader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/header/OldAnnotationHeader.java
new file mode 100644
index 00000000000..f29d92fd711
--- /dev/null
+++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/header/OldAnnotationHeader.java
@@ -0,0 +1,27 @@
+/*
+ * 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.lang.resolve.java.header;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.lang.resolve.java.AbiVersionUtil;
+import org.jetbrains.jet.lang.resolve.name.FqName;
+
+public class OldAnnotationHeader extends KotlinClassFileHeader {
+ protected OldAnnotationHeader(@NotNull FqName fqName) {
+ super(AbiVersionUtil.INVALID_VERSION, fqName);
+ }
+}
diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/header/SerializedDataHeader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/header/SerializedDataHeader.java
new file mode 100644
index 00000000000..6dadf4262a3
--- /dev/null
+++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/header/SerializedDataHeader.java
@@ -0,0 +1,61 @@
+/*
+ * 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.lang.resolve.java.header;
+
+import com.intellij.openapi.diagnostic.Logger;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.lang.resolve.name.FqName;
+
+import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCompatible;
+
+public class SerializedDataHeader extends KotlinClassFileHeader {
+ private static final Logger LOG = Logger.getInstance(SerializedDataHeader.class);
+
+ public enum Kind {
+ CLASS,
+ PACKAGE
+ }
+
+ private final String[] data;
+ private final Kind kind;
+
+ private SerializedDataHeader(int version, @Nullable String[] annotationData, @NotNull Kind kind, @NotNull FqName fqName) {
+ super(version, fqName);
+ this.data = annotationData;
+ this.kind = kind;
+ }
+
+ @Nullable
+ public static SerializedDataHeader create(int version, @Nullable String[] annotationData, @NotNull Kind kind, @NotNull FqName fqName) {
+ if (isAbiVersionCompatible(version) && annotationData == null) {
+ LOG.error("Kotlin annotation " + kind + " is incorrect for class: " + fqName);
+ return null;
+ }
+ return new SerializedDataHeader(version, annotationData, kind, fqName);
+ }
+
+ @Nullable
+ public String[] getAnnotationData() {
+ return data;
+ }
+
+ @NotNull
+ public Kind getKind() {
+ return kind;
+ }
+}
diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java
index d4888218ee3..a358ed57f18 100644
--- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java
+++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java
@@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.java.header.KotlinClassFileHeader;
+import org.jetbrains.jet.lang.resolve.java.header.SerializedDataHeader;
import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -34,7 +35,6 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import javax.inject.Inject;
import java.util.Collection;
-import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCompatible;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES;
import static org.jetbrains.jet.lang.resolve.java.resolver.DeserializedResolverUtils.kotlinFqNameToJavaFqName;
@@ -127,14 +127,13 @@ public final class DeserializedDescriptorResolver {
@Nullable
private String[] readData(@NotNull VirtualFile virtualFile) {
KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(virtualFile);
- if (header == null) {
- return null;
+ if (header instanceof SerializedDataHeader && header.isCompatibleKotlinCompiledFile()) {
+ return ((SerializedDataHeader) header).getAnnotationData();
}
- int version = header.getVersion();
- if (!isAbiVersionCompatible(version)) {
- errorReporter.reportIncompatibleAbiVersion(header.getFqName(), virtualFile, version);
- return null;
+
+ if (header != null) {
+ errorReporter.reportIncompatibleAbiVersion(header.getFqName(), virtualFile, header.getVersion());
}
- return header.getAnnotationData();
+ return null;
}
}
diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java b/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java
index a6aea3eb93b..df6ae5fa630 100644
--- a/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java
+++ b/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java
@@ -30,6 +30,7 @@ import org.jetbrains.jet.descriptors.serialization.*;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.resolve.java.JavaResolverPsiUtils;
import org.jetbrains.jet.lang.resolve.java.header.KotlinClassFileHeader;
+import org.jetbrains.jet.lang.resolve.java.header.SerializedDataHeader;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.util.QualifiedNamesUtil;
@@ -104,8 +105,8 @@ public class JetFromJavaDescriptorHelper {
VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
if (virtualFile != null) {
KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(virtualFile);
- if (header != null) {
- String[] data = header.getAnnotationData();
+ if (header instanceof SerializedDataHeader) {
+ String[] data = ((SerializedDataHeader) header).getAnnotationData();
if (data != null) {
return JavaProtoBufUtil.readClassDataFrom(data);
}
@@ -119,8 +120,8 @@ public class JetFromJavaDescriptorHelper {
VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
if (virtualFile != null) {
KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(virtualFile);
- if (header != null) {
- String[] data = header.getAnnotationData();
+ if (header instanceof SerializedDataHeader) {
+ String[] data = ((SerializedDataHeader) header).getAnnotationData();
if (data != null) {
return JavaProtoBufUtil.readPackageDataFrom(data);
}
diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java
index c17c338e8e2..7c52dd19643 100644
--- a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java
+++ b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import org.jetbrains.jet.lang.resolve.MemberComparator;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.header.KotlinClassFileHeader;
+import org.jetbrains.jet.lang.resolve.java.header.SerializedDataHeader;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import org.jetbrains.jet.renderer.DescriptorRendererBuilder;
@@ -48,7 +49,7 @@ public final class DecompiledDataFactory {
@NotNull
private final JavaDescriptorResolver javaDescriptorResolver;
@NotNull
- private final KotlinClassFileHeader kotlinClassFileHeader;
+ private final SerializedDataHeader classFileHeader;
@NotNull
private final VirtualFile classFile;
@NotNull
@@ -62,8 +63,8 @@ public final class DecompiledDataFactory {
this.javaDescriptorResolver = injector.getJavaDescriptorResolver();
KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(classFile);
- assert header != null : "Decompiled data factory shouldn't be called on an unsupported file: " + classFile;
- this.kotlinClassFileHeader = header;
+ assert header instanceof SerializedDataHeader : "Decompiled data factory shouldn't be called on an unsupported file: " + classFile;
+ this.classFileHeader = (SerializedDataHeader) header;
}
@NotNull
@@ -72,10 +73,10 @@ public final class DecompiledDataFactory {
}
private JetDecompiledData build() {
- FqName packageFqName = kotlinClassFileHeader.getFqName().parent();
+ FqName packageFqName = classFileHeader.getFqName().parent();
appendDecompiledTextAndPackageName(packageFqName);
- KotlinClassFileHeader.HeaderType type = kotlinClassFileHeader.getType();
- if (type == KotlinClassFileHeader.HeaderType.PACKAGE) {
+ SerializedDataHeader.Kind kind = classFileHeader.getKind();
+ if (kind == SerializedDataHeader.Kind.PACKAGE) {
NamespaceDescriptor nd = javaDescriptorResolver.resolveNamespace(packageFqName, INCLUDE_KOTLIN_SOURCES);
if (nd != null) {
for (DeclarationDescriptor member : sortDeclarations(nd.getMemberScope().getAllDescriptors())) {
@@ -88,13 +89,15 @@ public final class DecompiledDataFactory {
}
}
}
- else {
- assert type == KotlinClassFileHeader.HeaderType.CLASS;
- ClassDescriptor cd = javaDescriptorResolver.resolveClass(kotlinClassFileHeader.getFqName(), INCLUDE_KOTLIN_SOURCES);
+ else if (kind == SerializedDataHeader.Kind.CLASS) {
+ ClassDescriptor cd = javaDescriptorResolver.resolveClass(classFileHeader.getFqName(), INCLUDE_KOTLIN_SOURCES);
if (cd != null) {
appendDescriptor(cd, "");
}
}
+ else {
+ throw new UnsupportedOperationException("Unknown header kind: " + kind);
+ }
JetFile jetFile = JetDummyClassFileViewProvider.createJetFile(PsiManager.getInstance(project), classFile, builder.toString());
return new JetDecompiledData(jetFile, renderedDescriptorsToRange);
diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.java b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.java
index 0cf7234628a..950d079f2a1 100644
--- a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.java
+++ b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.java.header.KotlinClassFileHeader;
+import org.jetbrains.jet.lang.resolve.java.header.SerializedDataHeader;
public final class DecompiledUtils {
@@ -29,7 +30,7 @@ public final class DecompiledUtils {
}
//TODO: check index
KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(file);
- return header != null && header.isCompatibleKotlinCompiledFile();
+ return header instanceof SerializedDataHeader && header.isCompatibleKotlinCompiledFile();
}
private DecompiledUtils() {
diff --git a/idea/src/org/jetbrains/jet/plugin/vfilefinder/KotlinClassFileIndex.java b/idea/src/org/jetbrains/jet/plugin/vfilefinder/KotlinClassFileIndex.java
index ee5435d884d..0485176d125 100644
--- a/idea/src/org/jetbrains/jet/plugin/vfilefinder/KotlinClassFileIndex.java
+++ b/idea/src/org/jetbrains/jet/plugin/vfilefinder/KotlinClassFileIndex.java
@@ -7,6 +7,7 @@ import com.intellij.util.indexing.*;
import com.intellij.util.io.KeyDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.java.header.KotlinClassFileHeader;
+import org.jetbrains.jet.lang.resolve.java.header.SerializedDataHeader;
import org.jetbrains.jet.lang.resolve.name.FqName;
import java.io.DataInput;
@@ -58,7 +59,7 @@ public final class KotlinClassFileIndex extends ScalarIndexExtension {
public Map map(FileContent inputData) {
try {
KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(inputData.getFile());
- if (header != null && header.isCompatibleKotlinCompiledFile()) {
+ if (header instanceof SerializedDataHeader && header.isCompatibleKotlinCompiledFile()) {
return Collections.singletonMap(header.getFqName(), null);
}
}