Report ABI errors without PsiClass

This commit is contained in:
Alexander Udalov
2013-07-22 19:47:43 +04:00
committed by Pavel V. Talanov
parent 19299daacd
commit 8746ee2895
9 changed files with 35 additions and 62 deletions
@@ -33,7 +33,6 @@ import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSignatureResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.DeserializedDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.AnnotationDescriptorDeserializer;
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaNamespaceResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSupertypeResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver;
@@ -62,7 +61,6 @@ public class InjectorForJavaDescriptorResolver {
private final JavaSignatureResolver javaSignatureResolver;
private final DeserializedDescriptorResolver deserializedDescriptorResolver;
private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer;
private final ErrorReporter errorReporter;
private final JavaNamespaceResolver javaNamespaceResolver;
private final JavaSupertypeResolver javaSupertypeResolver;
private final JavaConstructorResolver javaConstructorResolver;
@@ -91,7 +89,6 @@ public class InjectorForJavaDescriptorResolver {
this.javaSignatureResolver = new JavaSignatureResolver();
this.deserializedDescriptorResolver = new DeserializedDescriptorResolver();
this.annotationDescriptorDeserializer = new AnnotationDescriptorDeserializer();
this.errorReporter = new ErrorReporter();
this.javaNamespaceResolver = new JavaNamespaceResolver();
this.javaSupertypeResolver = new JavaSupertypeResolver();
this.javaConstructorResolver = new JavaConstructorResolver();
@@ -144,15 +141,12 @@ public class InjectorForJavaDescriptorResolver {
javaSignatureResolver.setJavaSemanticServices(javaSemanticServices);
deserializedDescriptorResolver.setAnnotationDeserializer(annotationDescriptorDeserializer);
deserializedDescriptorResolver.setErrorReporter(errorReporter);
deserializedDescriptorResolver.setJavaClassResolver(javaClassResolver);
deserializedDescriptorResolver.setJavaNamespaceResolver(javaNamespaceResolver);
annotationDescriptorDeserializer.setJavaClassResolver(javaClassResolver);
annotationDescriptorDeserializer.setPsiClassFinder(psiClassFinder);
errorReporter.setTrace(bindingTrace);
javaNamespaceResolver.setDeserializedDescriptorResolver(deserializedDescriptorResolver);
javaNamespaceResolver.setJavaSemanticServices(javaSemanticServices);
javaNamespaceResolver.setPsiClassFinder(psiClassFinder);
@@ -33,7 +33,6 @@ import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSignatureResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.DeserializedDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.AnnotationDescriptorDeserializer;
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaNamespaceResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSupertypeResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver;
@@ -62,7 +61,6 @@ public class InjectorForJavaSemanticServices {
private final JavaSignatureResolver javaSignatureResolver;
private final DeserializedDescriptorResolver deserializedDescriptorResolver;
private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer;
private final ErrorReporter errorReporter;
private final JavaNamespaceResolver javaNamespaceResolver;
private final JavaSupertypeResolver javaSupertypeResolver;
private final JavaConstructorResolver javaConstructorResolver;
@@ -89,7 +87,6 @@ public class InjectorForJavaSemanticServices {
this.javaSignatureResolver = new JavaSignatureResolver();
this.deserializedDescriptorResolver = new DeserializedDescriptorResolver();
this.annotationDescriptorDeserializer = new AnnotationDescriptorDeserializer();
this.errorReporter = new ErrorReporter();
this.javaNamespaceResolver = new JavaNamespaceResolver();
this.javaSupertypeResolver = new JavaSupertypeResolver();
this.javaConstructorResolver = new JavaConstructorResolver();
@@ -144,15 +141,12 @@ public class InjectorForJavaSemanticServices {
javaSignatureResolver.setJavaSemanticServices(javaSemanticServices);
deserializedDescriptorResolver.setAnnotationDeserializer(annotationDescriptorDeserializer);
deserializedDescriptorResolver.setErrorReporter(errorReporter);
deserializedDescriptorResolver.setJavaClassResolver(javaClassResolver);
deserializedDescriptorResolver.setJavaNamespaceResolver(javaNamespaceResolver);
annotationDescriptorDeserializer.setJavaClassResolver(javaClassResolver);
annotationDescriptorDeserializer.setPsiClassFinder(psiClassFinder);
errorReporter.setTrace(bindingTrace);
javaNamespaceResolver.setDeserializedDescriptorResolver(deserializedDescriptorResolver);
javaNamespaceResolver.setJavaSemanticServices(javaSemanticServices);
javaNamespaceResolver.setPsiClassFinder(psiClassFinder);
@@ -58,7 +58,6 @@ import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSignatureResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.DeserializedDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.AnnotationDescriptorDeserializer;
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaNamespaceResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSupertypeResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver;
@@ -112,7 +111,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
private final JavaSignatureResolver javaSignatureResolver;
private final DeserializedDescriptorResolver deserializedDescriptorResolver;
private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer;
private final ErrorReporter errorReporter;
private final JavaNamespaceResolver javaNamespaceResolver;
private final JavaSupertypeResolver javaSupertypeResolver;
private final JavaConstructorResolver javaConstructorResolver;
@@ -167,7 +165,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
this.javaSignatureResolver = new JavaSignatureResolver();
this.deserializedDescriptorResolver = new DeserializedDescriptorResolver();
this.annotationDescriptorDeserializer = new AnnotationDescriptorDeserializer();
this.errorReporter = new ErrorReporter();
this.javaNamespaceResolver = new JavaNamespaceResolver();
this.javaSupertypeResolver = new JavaSupertypeResolver();
this.javaConstructorResolver = new JavaConstructorResolver();
@@ -322,15 +319,12 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
javaSignatureResolver.setJavaSemanticServices(javaSemanticServices);
deserializedDescriptorResolver.setAnnotationDeserializer(annotationDescriptorDeserializer);
deserializedDescriptorResolver.setErrorReporter(errorReporter);
deserializedDescriptorResolver.setJavaClassResolver(javaClassResolver);
deserializedDescriptorResolver.setJavaNamespaceResolver(javaNamespaceResolver);
annotationDescriptorDeserializer.setJavaClassResolver(javaClassResolver);
annotationDescriptorDeserializer.setPsiClassFinder(psiClassFinder);
errorReporter.setTrace(bindingTrace);
javaNamespaceResolver.setDeserializedDescriptorResolver(deserializedDescriptorResolver);
javaNamespaceResolver.setJavaSemanticServices(javaSemanticServices);
javaNamespaceResolver.setPsiClassFinder(psiClassFinder);
@@ -35,12 +35,6 @@ public class AbiVersionUtil {
return abiVersion == JvmAbi.VERSION;
}
public static void checkAbiVersion(@NotNull PsiClass psiClass, int version, @NotNull BindingTrace trace) {
if (!isAbiVersionCompatible(version)) {
reportIncompatibleAbiVersion(psiClass, version, trace);
}
}
public static void reportIncompatibleAbiVersion(@NotNull PsiClass psiClass, int version, @NotNull BindingTrace trace) {
trace.record(ABI_VERSION_ERRORS, psiClass, version);
}
@@ -23,7 +23,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -172,4 +174,14 @@ public final class DescriptorResolverUtils {
) {
return isEnumClassObject(ownerDescriptor) == shouldBeInEnumClassObject(member);
}
@NotNull
public static ErrorReporter createPsiBasedErrorReporter(@NotNull final PsiClass psiClass, @NotNull final BindingTrace trace) {
return new ErrorReporter() {
@Override
public void reportIncompatibleAbiVersion(int actualVersion) {
AbiVersionUtil.reportIncompatibleAbiVersion(psiClass, actualVersion, trace);
}
};
}
}
@@ -50,8 +50,6 @@ public final class DeserializedDescriptorResolver {
private JavaClassResolver javaClassResolver;
private ErrorReporter errorReporter;
@NotNull
private final DescriptorFinder javaDescriptorFinder = new DescriptorFinder() {
@Nullable
@@ -88,23 +86,19 @@ public final class DeserializedDescriptorResolver {
this.javaClassResolver = javaClassResolver;
}
@Inject
public void setErrorReporter(ErrorReporter errorReporter) {
this.errorReporter = errorReporter;
}
@Nullable
public ClassDescriptor resolveClass(
@NotNull FqName fqName,
@NotNull PsiClass psiClass,
@NotNull ClassOrNamespaceDescriptor containingDeclaration
@NotNull ClassOrNamespaceDescriptor containingDeclaration,
@NotNull ErrorReporter reporter
) {
VirtualFile virtualFile = getVirtualFile(psiClass, fqName, containingDeclaration);
if (virtualFile == null) {
// TODO: use ErrorReporter here
return null;
}
ClassData classData = readClassDataFromClassFile(virtualFile, psiClass);
ClassData classData = readClassDataFromClassFile(virtualFile, reporter);
if (classData == null) {
return null;
}
@@ -112,12 +106,16 @@ public final class DeserializedDescriptorResolver {
}
@Nullable
public JetScope createKotlinPackageScope(@NotNull PsiClass kotlinPackagePsiClass, @NotNull NamespaceDescriptor packageDescriptor) {
public JetScope createKotlinPackageScope(
@NotNull PsiClass kotlinPackagePsiClass,
@NotNull NamespaceDescriptor packageDescriptor,
@NotNull ErrorReporter reporter
) {
VirtualFile virtualFile = kotlinPackagePsiClass.getContainingFile().getVirtualFile();
if (virtualFile == null) {
return null;
}
PackageData packageData = readPackageDataFromClassFile(virtualFile, kotlinPackagePsiClass);
PackageData packageData = readPackageDataFromClassFile(virtualFile, reporter);
if (packageData == null) {
return null;
}
@@ -144,19 +142,19 @@ public final class DeserializedDescriptorResolver {
}
@Nullable
private ClassData readClassDataFromClassFile(@NotNull VirtualFile virtualFile, @NotNull PsiClass psiClass) {
String[] data = readData(virtualFile, psiClass);
private static ClassData readClassDataFromClassFile(@NotNull VirtualFile file, @NotNull ErrorReporter reporter) {
String[] data = readData(file, reporter);
return data == null ? null : JavaProtoBufUtil.readClassDataFrom(data);
}
@Nullable
private PackageData readPackageDataFromClassFile(@NotNull VirtualFile virtualFile, @NotNull PsiClass psiClass) {
String[] data = readData(virtualFile, psiClass);
private static PackageData readPackageDataFromClassFile(@NotNull VirtualFile file, @NotNull ErrorReporter reporter) {
String[] data = readData(file, reporter);
return data == null ? null : JavaProtoBufUtil.readPackageDataFrom(data);
}
@Nullable
private String[] readData(@NotNull VirtualFile virtualFile, @NotNull PsiClass psiClass) {
private static String[] readData(@NotNull VirtualFile virtualFile, @NotNull ErrorReporter reporter) {
KotlinClassFileHeader headerData = KotlinClassFileHeader.readKotlinHeaderFromClassFile(virtualFile);
int version = headerData.getVersion();
String[] annotationData = headerData.getAnnotationData();
@@ -164,7 +162,7 @@ public final class DeserializedDescriptorResolver {
return annotationData;
}
if (annotationData != null) {
errorReporter.reportIncompatibleAbiVersion(psiClass, version);
reporter.reportIncompatibleAbiVersion(version);
}
return null;
}
@@ -16,22 +16,6 @@
package org.jetbrains.jet.lang.resolve.java.resolver;
import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.java.AbiVersionUtil;
import javax.inject.Inject;
public class ErrorReporter {
private BindingTrace trace;
@Inject
public void setTrace(BindingTrace trace) {
this.trace = trace;
}
public void reportIncompatibleAbiVersion(@NotNull PsiClass psiClass, int version) {
AbiVersionUtil.reportIncompatibleAbiVersion(psiClass, version, trace);
}
public interface ErrorReporter {
void reportIncompatibleAbiVersion(int actualVersion);
}
@@ -245,7 +245,9 @@ public final class JavaClassResolver {
assert (!unresolvedCache.contains(fqName)) : "We can resolve the class, so it can't be 'unresolved' during parent resolution";
ClassDescriptor deserializedDescriptor = kotlinDescriptorResolver.resolveClass(fqName, psiClass, containingDeclaration);
ClassDescriptor deserializedDescriptor = kotlinDescriptorResolver.resolveClass(fqName, psiClass, containingDeclaration,
DescriptorResolverUtils.createPsiBasedErrorReporter(psiClass, trace));
if (deserializedDescriptor != null) {
//TODO: class object and psi class
cache(javaClassToKotlinFqName(fqName), deserializedDescriptor);
@@ -169,12 +169,13 @@ public final class JavaNamespaceResolver {
boolean isCompiledKotlinPackageClass = DescriptorResolverUtils.isCompiledKotlinPackageClass(psiClass);
if (isOldKotlinPackageClass(psiClass) && !isCompiledKotlinPackageClass) {
// If psiClass has old annotations (@JetPackage) but doesn't have @KotlinPackage, report ABI version error
AbiVersionUtil.checkAbiVersion(psiClass, INVALID_VERSION, trace);
AbiVersionUtil.reportIncompatibleAbiVersion(psiClass, INVALID_VERSION, trace);
}
if (isCompiledKotlinPackageClass) {
// If psiClass has @KotlinPackage (regardless of whether it has @JetPackage or not), deserialize it to Kotlin descriptor.
// Note that @KotlinPackage may still have an old ABI version, in which case null is returned by createKotlinPackageScope
JetScope kotlinPackageScope = deserializedDescriptorResolver.createKotlinPackageScope(psiClass, namespaceDescriptor);
JetScope kotlinPackageScope = deserializedDescriptorResolver.createKotlinPackageScope(psiClass, namespaceDescriptor,
DescriptorResolverUtils.createPsiBasedErrorReporter(psiClass, trace));
if (kotlinPackageScope != null) return kotlinPackageScope;
}
}