diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java index 0870978796b..12ec52dbd6f 100644 --- a/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java +++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java @@ -27,18 +27,25 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.codegen.ClassBuilderFactory; import org.jetbrains.jet.codegen.ClassFileFactory; import org.jetbrains.jet.codegen.GenerationState; +import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Severity; import org.jetbrains.jet.lang.diagnostics.SimpleDiagnosticFactory; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.plugin.JetFileType; import java.io.File; import java.io.PrintStream; import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** @@ -137,8 +144,33 @@ public class CompileSession { reportSyntaxErrors(errorCollector); analyzeAndReportSemanticErrors(errorCollector); + + boolean hasIncompleteHierarchyErrors; + Collection incompletes = myBindingContext.getKeys(BindingContext.INCOMPLETE_HIERARCHY); + if (!incompletes.isEmpty()) { + out.println("following classes have incomplete hierarchies:"); + for (ClassDescriptor incomplete : incompletes) { + out.println(" " + fqName(incomplete)); + } + hasIncompleteHierarchyErrors = true; + } else { + hasIncompleteHierarchyErrors = false; + } + errorCollector.flushTo(out); - return !errorCollector.hasErrors; + return !errorCollector.hasErrors && !hasIncompleteHierarchyErrors; + } + + /** + * @see JetTypeMapper#getFQName(DeclarationDescriptor) + */ + private String fqName(ClassOrNamespaceDescriptor descriptor) { + DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); + if (containingDeclaration == null || containingDeclaration instanceof ModuleDescriptor || containingDeclaration.getName().equals(JavaDescriptorResolver.JAVA_ROOT)) { + return descriptor.getName(); + } else { + return fqName((ClassOrNamespaceDescriptor) containingDeclaration) + "." + descriptor.getName(); + } } private void analyzeAndReportSemanticErrors(ErrorCollector errorCollector) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 4a6fa6dd0f4..3f3d9f550f3 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -309,7 +309,7 @@ public class JavaDescriptorResolver { TypeVariableResolverFromTypeDescriptors resolverForTypeParameters = new TypeVariableResolverFromTypeDescriptors(classData.getTypeParameters(), null); // TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes - supertypes.addAll(getSupertypes(new PsiClassWrapper(psiClass), classData.getTypeParameters())); + supertypes.addAll(getSupertypes(new PsiClassWrapper(psiClass), classData.classDescriptor, classData.getTypeParameters())); if (psiClass.isInterface()) { //classData.classDescriptor.setSuperclassType(JetStandardClasses.getAnyType()); // TODO : Make it java.lang.Object @@ -669,7 +669,7 @@ public class JavaDescriptorResolver { } } - private Collection getSupertypes(PsiClassWrapper psiClass, List typeParameters) { + private Collection getSupertypes(PsiClassWrapper psiClass, ClassDescriptor classDescriptor, List typeParameters) { final List result = new ArrayList(); if (psiClass.getJetClass().signature().length() > 0) { @@ -703,6 +703,13 @@ public class JavaDescriptorResolver { transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), new TypeVariableResolverFromTypeDescriptors(typeParameters, null)); transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), new TypeVariableResolverFromTypeDescriptors(typeParameters, null)); } + + for (JetType supertype : result) { + if (ErrorUtils.isErrorType(supertype)) { + semanticServices.getTrace().record(BindingContext.INCOMPLETE_HIERARCHY, classDescriptor); + } + } + if (result.isEmpty()) { result.add(JetStandardClasses.getAnyType()); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index 01dd8c3489a..a93299c1363 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -171,6 +171,8 @@ public interface BindingContext { WritableSlice FQNAME_TO_CLASS_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING, true); WritableSlice FQNAME_TO_NAMESPACE_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING); + + WritableSlice INCOMPLETE_HIERARCHY = Slices.createCollectiveSetSlice(); @SuppressWarnings("UnusedDeclaration") @Deprecated // This field is needed only for the side effects of its initializer