Simplify logic in KotlinClassFileHeader
When processing annotations, we should ensure not only that we have no more than one KotlinClass/KotlinPackage annotation, but any supported header type at all. Also instead of throwing an exception it's safer to just log the error
This commit is contained in:
+42
-30
@@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* 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.resolver;
|
package org.jetbrains.jet.lang.resolve.java.resolver;
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
@@ -29,14 +45,14 @@ public final class KotlinClassFileHeader {
|
|||||||
ClassReader reader = new ClassReader(virtualFile.contentsToByteArray());
|
ClassReader reader = new ClassReader(virtualFile.contentsToByteArray());
|
||||||
ReadDataFromAnnotationVisitor visitor = new ReadDataFromAnnotationVisitor();
|
ReadDataFromAnnotationVisitor visitor = new ReadDataFromAnnotationVisitor();
|
||||||
reader.accept(visitor, SKIP_CODE | SKIP_FRAMES | SKIP_DEBUG);
|
reader.accept(visitor, SKIP_CODE | SKIP_FRAMES | SKIP_DEBUG);
|
||||||
if (visitor.type == null) {
|
if (visitor.foundType == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (visitor.fqName == null) {
|
if (visitor.fqName == null) {
|
||||||
LOG.error("File doesn't have a class name: " + virtualFile);
|
LOG.error("File doesn't have a class name: " + virtualFile);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new KotlinClassFileHeader(visitor.version, visitor.annotationData, visitor.type, visitor.fqName);
|
return new KotlinClassFileHeader(visitor.version, visitor.annotationData, visitor.foundType, visitor.fqName);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@@ -50,25 +66,17 @@ public final class KotlinClassFileHeader {
|
|||||||
OLD_CLASS(JvmAnnotationNames.OLD_JET_CLASS_ANNOTATION),
|
OLD_CLASS(JvmAnnotationNames.OLD_JET_CLASS_ANNOTATION),
|
||||||
OLD_PACKAGE(JvmAnnotationNames.OLD_JET_PACKAGE_CLASS_ANNOTATION);
|
OLD_PACKAGE(JvmAnnotationNames.OLD_JET_PACKAGE_CLASS_ANNOTATION);
|
||||||
|
|
||||||
@Nullable
|
@NotNull
|
||||||
private final JvmClassName correspondingAnnotation;
|
private final JvmClassName annotation;
|
||||||
|
|
||||||
private HeaderType(@Nullable JvmClassName annotation) {
|
private HeaderType(@NotNull JvmClassName annotation) {
|
||||||
correspondingAnnotation = annotation;
|
this.annotation = annotation;
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isValidAnnotation() {
|
|
||||||
return this == CLASS || this == PACKAGE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static HeaderType byDescriptor(@NotNull String desc) {
|
private static HeaderType byDescriptor(@NotNull String desc) {
|
||||||
for (HeaderType headerType : HeaderType.values()) {
|
for (HeaderType headerType : HeaderType.values()) {
|
||||||
JvmClassName annotation = headerType.correspondingAnnotation;
|
if (desc.equals(headerType.annotation.getDescriptor())) {
|
||||||
if (annotation == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (desc.equals(annotation.getDescriptor())) {
|
|
||||||
return headerType;
|
return headerType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +126,7 @@ 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
|
* @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() {
|
public boolean isCompatibleKotlinCompiledFile() {
|
||||||
return type.isValidAnnotation() && isAbiVersionCompatible(version);
|
return (type == HeaderType.CLASS || type == HeaderType.PACKAGE) && isAbiVersionCompatible(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ReadDataFromAnnotationVisitor extends ClassVisitor {
|
private static class ReadDataFromAnnotationVisitor extends ClassVisitor {
|
||||||
@@ -126,7 +134,7 @@ public final class KotlinClassFileHeader {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private String[] annotationData = null;
|
private String[] annotationData = null;
|
||||||
@Nullable
|
@Nullable
|
||||||
private HeaderType type = null;
|
private HeaderType foundType = null;
|
||||||
@Nullable
|
@Nullable
|
||||||
private FqName fqName = null;
|
private FqName fqName = null;
|
||||||
|
|
||||||
@@ -140,22 +148,26 @@ public final class KotlinClassFileHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
|
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||||
HeaderType headerTypeByAnnotation = HeaderType.byDescriptor(desc);
|
HeaderType newType = HeaderType.byDescriptor(desc);
|
||||||
if (headerTypeByAnnotation == null) {
|
if (newType == null) return null;
|
||||||
|
|
||||||
|
if (foundType != null) {
|
||||||
|
LOG.error("Both annotations are present for compiled Kotlin file: " + foundType + " and " + newType);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
boolean alreadyFoundValid = type != null && type.isValidAnnotation();
|
|
||||||
if (headerTypeByAnnotation.isValidAnnotation() && alreadyFoundValid) {
|
foundType = newType;
|
||||||
throw new IllegalStateException("Both " + type.correspondingAnnotation + " and "
|
|
||||||
+ headerTypeByAnnotation.correspondingAnnotation + " present!");
|
if (newType == HeaderType.CLASS || newType == HeaderType.PACKAGE) {
|
||||||
}
|
return kotlinClassOrPackageVisitor(desc);
|
||||||
if (!alreadyFoundValid) {
|
|
||||||
type = headerTypeByAnnotation;
|
|
||||||
}
|
|
||||||
if (!headerTypeByAnnotation.isValidAnnotation()) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private AnnotationVisitor kotlinClassOrPackageVisitor(final String desc) {
|
||||||
return new AnnotationVisitor(Opcodes.ASM4) {
|
return new AnnotationVisitor(Opcodes.ASM4) {
|
||||||
@Override
|
@Override
|
||||||
public void visit(String name, Object value) {
|
public void visit(String name, Object value) {
|
||||||
|
|||||||
Reference in New Issue
Block a user