Prohibit creation of JetLightClass on built-ins

If we allow JetLightClass to be created on built-in types, a normal codegen
would be launched, with a mapping from Kotlin to Java types enabled, every time
IDE requests built-in classes. Codegen would then try to make something
meaningless, e.g. create a class for a primitive type (since our jet.Boolean is
mapped to primitive boolean). This would result in different exceptions when
navigating to built-in library from IDE.

Add a helpful error message to ClassFileFactory if we ever again produce
classes for primitive types.
This commit is contained in:
Alexander Udalov
2012-09-11 16:03:33 +04:00
parent 4eea0cafb9
commit bb92655ecd
11 changed files with 129 additions and 39 deletions
@@ -118,7 +118,10 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade
if (packageName != null && qualifiedName.getFqName().startsWith(packageName.getFqName())) {
if (qualifiedName.equals(QualifiedNamesUtil.combine(packageName, Name.identifier(JvmAbi.PACKAGE_CLASS))) &&
NamespaceCodegen.shouldGenerateNSClass(Arrays.asList(file))) {
answer.add(new JetLightClass(psiManager, file, qualifiedName));
JetLightClass lightClass = JetLightClass.create(psiManager, file, qualifiedName);
if (lightClass != null) {
answer.add(lightClass);
}
}
else {
for (JetDeclaration declaration : file.getDeclarations()) {
@@ -137,7 +140,10 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade
FqName fqn = QualifiedNamesUtil.combine(containerFqn, Name.identifier(localName));
if (qualifiedName.equals(fqn)) {
if (!(declaration instanceof JetEnumEntry)) {
answer.add(new JetLightClass(psiManager, file, qualifiedName));
JetLightClass lightClass = JetLightClass.create(psiManager, file, qualifiedName);
if (lightClass != null) {
answer.add(lightClass);
}
}
}
else if (QualifiedNamesUtil.isSubpackageOf(qualifiedName, fqn)) {
@@ -231,12 +237,20 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade
FqName packageFQN = new FqName(psiPackage.getQualifiedName());
for (JetFile file : filesInScope) {
if (packageFQN.equals(JetPsiUtil.getFQName(file))) {
answer.add(new JetLightClass(psiManager, file, QualifiedNamesUtil.combine(packageFQN, Name.identifier(JvmAbi.PACKAGE_CLASS))));
JetLightClass lightClass = JetLightClass
.create(psiManager, file, QualifiedNamesUtil.combine(packageFQN, Name.identifier(JvmAbi.PACKAGE_CLASS)));
if (lightClass != null) {
answer.add(lightClass);
}
for (JetDeclaration declaration : file.getDeclarations()) {
if (declaration instanceof JetClassOrObject) {
String localName = getLocalName(declaration);
if (localName != null) {
answer.add(new JetLightClass(psiManager, file, QualifiedNamesUtil.combine(packageFQN, Name.identifier(localName))));
JetLightClass aClass = JetLightClass.create(psiManager, file,
QualifiedNamesUtil.combine(packageFQN, Name.identifier(localName)));
if (aClass != null) {
answer.add(aClass);
}
}
}
}
@@ -21,7 +21,6 @@ package org.jetbrains.jet.asJava;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.ItemPresentationProviders;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
@@ -36,8 +35,12 @@ import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.util.*;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.codegen.ClassBuilder;
import org.jetbrains.jet.codegen.ClassBuilderFactory;
import org.jetbrains.jet.codegen.ClassBuilderMode;
import org.jetbrains.jet.codegen.CompilationErrorHandler;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.GenerationStrategy;
import org.jetbrains.jet.lang.BuiltinsScopeExtensionMode;
@@ -49,6 +52,7 @@ import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
import org.jetbrains.jet.lang.resolve.java.JetJavaMirrorMarker;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.plugin.JetLanguage;
import javax.swing.*;
@@ -61,20 +65,28 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa
private final FqName qualifiedName;
private PsiClass delegate;
public JetLightClass(PsiManager manager, JetFile file, FqName qualifiedName) {
private JetLightClass(PsiManager manager, JetFile file, FqName qualifiedName) {
super(manager, JetLanguage.INSTANCE);
this.file = file;
this.qualifiedName = qualifiedName;
}
@Nullable
public static JetLightClass create(PsiManager manager, JetFile file, FqName qualifiedName) {
return JetStandardClasses.isStandardClass(qualifiedName) ? null : new JetLightClass(manager, file, qualifiedName);
}
@Override
public String getName() {
return qualifiedName.shortName().getName();
}
@NotNull
@Override
public PsiElement copy() {
return new JetLightClass(getManager(), file, qualifiedName);
JetLightClass result = create(getManager(), file, qualifiedName);
assert result != null;
return result;
}
@NotNull
@@ -233,13 +245,20 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa
return true;
}
@Nullable
public static JetLightClass wrapDelegate(JetClass jetClass) {
return new JetLightClass(jetClass.getManager(), (JetFile) jetClass.getContainingFile(), JetPsiUtil.getFQName(jetClass));
if (jetClass == null) return null;
return create(jetClass.getManager(), (JetFile) jetClass.getContainingFile(), JetPsiUtil.getFQName(jetClass));
}
@Nullable
public static PsiMethod wrapMethod(JetFunction function) {
JetClass containingClass = PsiTreeUtil.getParentOfType(function, JetClass.class);
JetLightClass wrapper = wrapDelegate(containingClass);
if (wrapper == null) {
return null;
}
for (PsiMethod method : wrapper.getMethods()) {
if (method instanceof PsiCompiledElement && ((PsiCompiledElement) method).getMirror() == function) {
return method;