Add support of light classes for local class/object declarations
This commit is contained in:
@@ -1,4 +1,8 @@
|
|||||||
<root>
|
<root>
|
||||||
|
<item
|
||||||
|
name='com.intellij.psi.util.CachedValueProvider.Result com.intellij.psi.util.CachedValueProvider.Result<T> create(T, java.lang.Object...)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
<item
|
<item
|
||||||
name='com.intellij.psi.util.CachedValuesManager com.intellij.psi.util.CachedValue<T> createCachedValue(com.intellij.psi.util.CachedValueProvider<T>, boolean)'>
|
name='com.intellij.psi.util.CachedValuesManager com.intellij.psi.util.CachedValue<T> createCachedValue(com.intellij.psi.util.CachedValueProvider<T>, boolean)'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
|||||||
@@ -234,7 +234,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
boolean isLocalOrAnonymousClass = isObjectLiteral ||
|
boolean isLocalOrAnonymousClass = isObjectLiteral ||
|
||||||
!(parentDescriptor instanceof NamespaceDescriptor || parentDescriptor instanceof ClassDescriptor);
|
!(parentDescriptor instanceof NamespaceDescriptor || parentDescriptor instanceof ClassDescriptor);
|
||||||
if (isLocalOrAnonymousClass) {
|
// Do not emit enclosing method in "light-classes mode" since currently we genenerate local light classes as if they're top level
|
||||||
|
if (isLocalOrAnonymousClass && getState().getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES) {
|
||||||
String outerClassName = getOuterClassName(descriptor, typeMapper);
|
String outerClassName = getOuterClassName(descriptor, typeMapper);
|
||||||
FunctionDescriptor function = DescriptorUtils.getParentOfType(descriptor, FunctionDescriptor.class);
|
FunctionDescriptor function = DescriptorUtils.getParentOfType(descriptor, FunctionDescriptor.class);
|
||||||
|
|
||||||
|
|||||||
@@ -78,14 +78,15 @@ public class MemberCodegen extends ParentCodegenAwareImpl {
|
|||||||
public void genClassOrObject(CodegenContext parentContext, JetClassOrObject aClass) {
|
public void genClassOrObject(CodegenContext parentContext, JetClassOrObject aClass) {
|
||||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||||
|
|
||||||
if (descriptor == null || ErrorUtils.isError(descriptor) || descriptor.getName().equals(SpecialNames.NO_NAME_PROVIDED)) {
|
if (descriptor == null || ErrorUtils.isError(descriptor)) {
|
||||||
if (state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES) {
|
badDescriptor(descriptor);
|
||||||
throw new IllegalStateException(
|
|
||||||
"Generating bad descriptor in ClassBuilderMode = " + state.getClassBuilderMode() + ": " + descriptor);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (descriptor.getName().equals(SpecialNames.NO_NAME_PROVIDED)) {
|
||||||
|
badDescriptor(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
ClassBuilder classBuilder = state.getFactory().forClassImplementation(descriptor, aClass.getContainingFile());
|
ClassBuilder classBuilder = state.getFactory().forClassImplementation(descriptor, aClass.getContainingFile());
|
||||||
ClassContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state);
|
ClassContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state);
|
||||||
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, this).generate();
|
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, this).generate();
|
||||||
@@ -98,4 +99,11 @@ public class MemberCodegen extends ParentCodegenAwareImpl {
|
|||||||
traitBuilder.done();
|
traitBuilder.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void badDescriptor(ClassDescriptor descriptor) {
|
||||||
|
if (state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Generating bad descriptor in ClassBuilderMode = " + state.getClassBuilderMode() + ": " + descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public class CliJetFilesProvider extends JetFilesProvider {
|
|||||||
return allFiles;
|
return allFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<JetFile> allInScope(@NotNull GlobalSearchScope scope) {
|
public List<JetFile> allInScope(@NotNull GlobalSearchScope scope) {
|
||||||
List<JetFile> answer = new ArrayList<JetFile>();
|
List<JetFile> answer = new ArrayList<JetFile>();
|
||||||
|
|||||||
+11
-1
@@ -82,10 +82,20 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport
|
|||||||
trace = null;
|
trace = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LightClassConstructionContext analyzeRelevantCode() {
|
||||||
|
return new LightClassConstructionContext(getTrace().getBindingContext(), null);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public LightClassConstructionContext analyzeRelevantCode(@NotNull Collection<JetFile> files) {
|
public LightClassConstructionContext analyzeRelevantCode(@NotNull Collection<JetFile> files) {
|
||||||
return new LightClassConstructionContext(getTrace().getBindingContext(), null);
|
return analyzeRelevantCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public LightClassConstructionContext analyzeRelevantCode(@NotNull JetClassOrObject classOrObject) {
|
||||||
|
return analyzeRelevantCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public abstract class JetFilesProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract Function<JetFile, Collection<JetFile>> sampleToAllFilesInModule();
|
public abstract Function<JetFile, Collection<JetFile>> sampleToAllFilesInModule();
|
||||||
|
@NotNull
|
||||||
public abstract Collection<JetFile> allInScope(@NotNull GlobalSearchScope scope);
|
public abstract Collection<JetFile> allInScope(@NotNull GlobalSearchScope scope);
|
||||||
public abstract boolean isFileInScope(@NotNull JetFile file, @NotNull GlobalSearchScope scope);
|
public abstract boolean isFileInScope(@NotNull JetFile file, @NotNull GlobalSearchScope scope);
|
||||||
|
|
||||||
|
|||||||
@@ -570,10 +570,6 @@ public class JetPsiUtil {
|
|||||||
return statements.isEmpty() ? null : statements.get(statements.size() - 1);
|
return statements.isEmpty() ? null : statements.get(statements.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isLocalClass(@NotNull JetClassOrObject classOrObject) {
|
|
||||||
return getOutermostClassOrObject(classOrObject) == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isTrait(@NotNull JetClassOrObject classOrObject) {
|
public static boolean isTrait(@NotNull JetClassOrObject classOrObject) {
|
||||||
return classOrObject instanceof JetClass && ((JetClass) classOrObject).isTrait();
|
return classOrObject instanceof JetClass && ((JetClass) classOrObject).isTrait();
|
||||||
}
|
}
|
||||||
@@ -595,7 +591,7 @@ public class JetPsiUtil {
|
|||||||
}
|
}
|
||||||
if (!(parent instanceof JetClassBody)) {
|
if (!(parent instanceof JetClassBody)) {
|
||||||
// It is a local class, no legitimate outer
|
// It is a local class, no legitimate outer
|
||||||
return null;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
current = (JetClassOrObject) parent.getParent();
|
current = (JetClassOrObject) parent.getParent();
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* 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.asJava
|
||||||
|
|
||||||
|
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||||
|
|
||||||
|
data class GeneratedLightClassData(
|
||||||
|
val javaFileStub: PsiJavaFileStub,
|
||||||
|
val jvmInternalName: String,
|
||||||
|
val descriptor: ClassDescriptor?
|
||||||
|
)
|
||||||
+102
-49
@@ -37,20 +37,24 @@ import com.intellij.testFramework.LightVirtualFile;
|
|||||||
import com.intellij.util.containers.Stack;
|
import com.intellij.util.containers.Stack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.asm4.Type;
|
||||||
import org.jetbrains.jet.codegen.CompilationErrorHandler;
|
import org.jetbrains.jet.codegen.CompilationErrorHandler;
|
||||||
import org.jetbrains.jet.codegen.NamespaceCodegen;
|
import org.jetbrains.jet.codegen.NamespaceCodegen;
|
||||||
|
import org.jetbrains.jet.codegen.binding.CodegenBinding;
|
||||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||||
import org.jetbrains.jet.codegen.state.Progress;
|
import org.jetbrains.jet.codegen.state.Progress;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.types.lang.InlineUtil;
|
import org.jetbrains.jet.lang.types.lang.InlineUtil;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
public class KotlinJavaFileStubProvider implements CachedValueProvider<PsiJavaFileStub> {
|
public class KotlinJavaFileStubProvider implements CachedValueProvider<GeneratedLightClassData> {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static KotlinJavaFileStubProvider createForPackageClass(
|
public static KotlinJavaFileStubProvider createForPackageClass(
|
||||||
@@ -58,90 +62,131 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<PsiJavaFi
|
|||||||
@NotNull final FqName packageFqName,
|
@NotNull final FqName packageFqName,
|
||||||
@NotNull final GlobalSearchScope searchScope
|
@NotNull final GlobalSearchScope searchScope
|
||||||
) {
|
) {
|
||||||
return new KotlinJavaFileStubProvider(project, new StubGenerationStrategy.NoDeclaredClasses() {
|
return new KotlinJavaFileStubProvider(
|
||||||
|
project,
|
||||||
|
false,
|
||||||
|
new StubGenerationStrategy.NoDeclaredClasses() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public LightClassConstructionContext createLightClassConstructionContext(@NotNull Collection<JetFile> files) {
|
||||||
|
return LightClassGenerationSupport.getInstance(project).analyzeRelevantCode(files);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<JetFile> getFiles() {
|
public Collection<JetFile> getFiles() {
|
||||||
// Don't memoize this, it can be called again after an out-of-code-block modification occurs,
|
// Don't memoize this, it can be called again after an out-of-code-block modification occurs,
|
||||||
// and the set of files changes
|
// and the set of files changes
|
||||||
return LightClassGenerationSupport.getInstance(project).findFilesForPackage(packageFqName, searchScope);
|
return LightClassGenerationSupport.getInstance(project).findFilesForPackage(packageFqName, searchScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public FqName getPackageFqName() {
|
public GeneratedLightClassData createStubWithName(PsiJavaFileStub javaFileStub, BindingContext bindingContext) {
|
||||||
return packageFqName;
|
return new GeneratedLightClassData(javaFileStub, "", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@NotNull
|
||||||
public void generate(@NotNull GenerationState state, @NotNull Collection<JetFile> files) {
|
@Override
|
||||||
NamespaceCodegen codegen = state.getFactory().forNamespace(packageFqName, files);
|
public FqName getPackageFqName() {
|
||||||
codegen.generate(CompilationErrorHandler.THROW_EXCEPTION);
|
return packageFqName;
|
||||||
state.getFactory().asList();
|
}
|
||||||
}
|
|
||||||
});
|
@Override
|
||||||
|
public void generate(@NotNull GenerationState state, @NotNull Collection<JetFile> files) {
|
||||||
|
NamespaceCodegen codegen = state.getFactory().forNamespace(packageFqName, files);
|
||||||
|
codegen.generate(CompilationErrorHandler.THROW_EXCEPTION);
|
||||||
|
state.getFactory().asList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static KotlinJavaFileStubProvider createForDeclaredTopLevelClass(@NotNull final JetClassOrObject classOrObject) {
|
public static KotlinJavaFileStubProvider createForDeclaredClass(@NotNull final JetClassOrObject classOrObject) {
|
||||||
return new KotlinJavaFileStubProvider(classOrObject.getProject(), new StubGenerationStrategy.WithDeclaredClasses() {
|
return new KotlinJavaFileStubProvider(
|
||||||
private JetFile getFile() {
|
classOrObject.getProject(),
|
||||||
JetFile file = (JetFile) classOrObject.getContainingFile();
|
JetPsiUtil.isLocal(classOrObject),
|
||||||
assert classOrObject.getParent() == file : "Not a top-level class: " + classOrObject.getText();
|
new StubGenerationStrategy.WithDeclaredClasses() {
|
||||||
return file;
|
private JetFile getFile() {
|
||||||
}
|
return (JetFile) classOrObject.getContainingFile();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<JetFile> getFiles() {
|
public LightClassConstructionContext createLightClassConstructionContext(@NotNull Collection<JetFile> files) {
|
||||||
return Collections.singletonList(getFile());
|
return LightClassGenerationSupport.getInstance(classOrObject.getProject()).analyzeRelevantCode(classOrObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public FqName getPackageFqName() {
|
public GeneratedLightClassData createStubWithName(PsiJavaFileStub javaFileStub, BindingContext bindingContext) {
|
||||||
return JetPsiUtil.getFQName(getFile());
|
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject);
|
||||||
}
|
assert (classDescriptor != null);
|
||||||
|
|
||||||
@Override
|
Type asmType = bindingContext.get(CodegenBinding.ASM_TYPE, classDescriptor);
|
||||||
public void generate(@NotNull GenerationState state, @NotNull Collection<JetFile> files) {
|
assert (asmType != null);
|
||||||
NamespaceCodegen namespaceCodegen = state.getFactory().forNamespace(getPackageFqName(), files);
|
|
||||||
namespaceCodegen.generateClassOrObject(classOrObject);
|
String jvmInternalName = asmType.getClassName();
|
||||||
state.getFactory().asList();
|
assert (jvmInternalName != null);
|
||||||
}
|
|
||||||
});
|
return new GeneratedLightClassData(javaFileStub, jvmInternalName, classDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<JetFile> getFiles() {
|
||||||
|
return Collections.singletonList(getFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public FqName getPackageFqName() {
|
||||||
|
return JetPsiUtil.getFQName(getFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(@NotNull GenerationState state, @NotNull Collection<JetFile> files) {
|
||||||
|
NamespaceCodegen namespaceCodegen = state.getFactory().forNamespace(getPackageFqName(), files);
|
||||||
|
namespaceCodegen.generateClassOrObject(classOrObject);
|
||||||
|
state.getFactory().asList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getInstance(KotlinJavaFileStubProvider.class);
|
private static final Logger LOG = Logger.getInstance(KotlinJavaFileStubProvider.class);
|
||||||
|
|
||||||
private final Project project;
|
private final Project project;
|
||||||
private final StubGenerationStrategy stubGenerationStrategy;
|
private final StubGenerationStrategy stubGenerationStrategy;
|
||||||
|
private final boolean local;
|
||||||
|
|
||||||
private KotlinJavaFileStubProvider(
|
private KotlinJavaFileStubProvider(
|
||||||
@NotNull Project project,
|
@NotNull Project project,
|
||||||
|
boolean local,
|
||||||
@NotNull StubGenerationStrategy stubGenerationStrategy
|
@NotNull StubGenerationStrategy stubGenerationStrategy
|
||||||
) {
|
) {
|
||||||
this.project = project;
|
this.project = project;
|
||||||
this.stubGenerationStrategy = stubGenerationStrategy;
|
this.stubGenerationStrategy = stubGenerationStrategy;
|
||||||
|
this.local = local;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Result<PsiJavaFileStub> compute() {
|
public Result<GeneratedLightClassData> compute() {
|
||||||
FqName packageFqName = stubGenerationStrategy.getPackageFqName();
|
FqName packageFqName = stubGenerationStrategy.getPackageFqName();
|
||||||
Collection<JetFile> files = stubGenerationStrategy.getFiles();
|
Collection<JetFile> files = stubGenerationStrategy.getFiles();
|
||||||
|
|
||||||
checkForBuiltIns(packageFqName, files);
|
checkForBuiltIns(packageFqName, files);
|
||||||
|
|
||||||
LightClassConstructionContext context = LightClassGenerationSupport.getInstance(project).analyzeRelevantCode(files);
|
LightClassConstructionContext context = stubGenerationStrategy.createLightClassConstructionContext(files);
|
||||||
|
|
||||||
Throwable error = context.getError();
|
Throwable error = context.getError();
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
throw new IllegalStateException("failed to analyze: " + error, error);
|
throw new IllegalStateException("failed to analyze: " + error, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
PsiJavaFileStub javaFileStub = createJavaFileStub(packageFqName, getRepresentativeVirtualFile(files));
|
PsiJavaFileStub javaFileStub = createJavaFileStub(packageFqName, getRepresentativeVirtualFile(files));
|
||||||
|
BindingContext bindingContext;
|
||||||
try {
|
try {
|
||||||
Stack<StubElement> stubStack = new Stack<StubElement>();
|
Stack<StubElement> stubStack = new Stack<StubElement>();
|
||||||
stubStack.push(javaFileStub);
|
stubStack.push(javaFileStub);
|
||||||
@@ -157,6 +202,8 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<PsiJavaFi
|
|||||||
InlineUtil.DEFAULT_INLINE_FLAG_FOR_STUB);
|
InlineUtil.DEFAULT_INLINE_FLAG_FOR_STUB);
|
||||||
state.beforeCompile();
|
state.beforeCompile();
|
||||||
|
|
||||||
|
bindingContext = state.getBindingContext();
|
||||||
|
|
||||||
stubGenerationStrategy.generate(state, files);
|
stubGenerationStrategy.generate(state, files);
|
||||||
|
|
||||||
StubElement pop = stubStack.pop();
|
StubElement pop = stubStack.pop();
|
||||||
@@ -173,7 +220,10 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<PsiJavaFi
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.create(javaFileStub, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
|
return Result.create(
|
||||||
|
stubGenerationStrategy.createStubWithName(javaFileStub, bindingContext),
|
||||||
|
local ? PsiModificationTracker.MODIFICATION_COUNT : PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -231,6 +281,9 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider<PsiJavaFi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private interface StubGenerationStrategy {
|
private interface StubGenerationStrategy {
|
||||||
|
@NotNull LightClassConstructionContext createLightClassConstructionContext(@NotNull Collection<JetFile> files);
|
||||||
|
@NotNull
|
||||||
|
GeneratedLightClassData createStubWithName(PsiJavaFileStub javaFileStub, BindingContext bindingContext);
|
||||||
@NotNull Collection<JetFile> getFiles();
|
@NotNull Collection<JetFile> getFiles();
|
||||||
@NotNull FqName getPackageFqName();
|
@NotNull FqName getPackageFqName();
|
||||||
boolean generateDeclaredClasses();
|
boolean generateDeclaredClasses();
|
||||||
|
|||||||
+46
-11
@@ -42,7 +42,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor;
|
import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||||
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetJavaMirrorMarker;
|
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetJavaMirrorMarker;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
@@ -59,7 +59,7 @@ import java.util.List;
|
|||||||
import static org.jetbrains.jet.lexer.JetTokens.*;
|
import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||||
|
|
||||||
public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightClass implements KotlinLightClass, JetJavaMirrorMarker {
|
public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightClass implements KotlinLightClass, JetJavaMirrorMarker {
|
||||||
private final static Key<CachedValue<PsiJavaFileStub>> JAVA_API_STUB = Key.create("JAVA_API_STUB");
|
private final static Key<CachedValue<GeneratedLightClassData>> JAVA_API_STUB = Key.create("JAVA_API_STUB");
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static KotlinLightClassForExplicitDeclaration create(@NotNull PsiManager manager, @NotNull JetClassOrObject classOrObject) {
|
public static KotlinLightClassForExplicitDeclaration create(@NotNull PsiManager manager, @NotNull JetClassOrObject classOrObject) {
|
||||||
@@ -67,18 +67,21 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO temporary not building light classes for local classes: e.g., they won't be visible in hierarchy
|
String jvmInternalName = getJvmInternalName(classOrObject);
|
||||||
if (JetPsiUtil.getOutermostClassOrObject(classOrObject) == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String jvmInternalName = PsiCodegenPredictor.getPredefinedJvmInternalName(classOrObject);
|
|
||||||
if (jvmInternalName == null) return null;
|
if (jvmInternalName == null) return null;
|
||||||
|
|
||||||
FqName fqName = JvmClassName.byInternalName(jvmInternalName).getFqNameForClassNameWithoutDollars();
|
FqName fqName = JvmClassName.byInternalName(jvmInternalName).getFqNameForClassNameWithoutDollars();
|
||||||
|
|
||||||
return new KotlinLightClassForExplicitDeclaration(manager, fqName, classOrObject);
|
return new KotlinLightClassForExplicitDeclaration(manager, fqName, classOrObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getJvmInternalName(JetClassOrObject classOrObject) {
|
||||||
|
if (JetPsiUtil.isLocal(classOrObject)) {
|
||||||
|
return getGeneratedLightClassData(classOrObject).getJvmInternalName();
|
||||||
|
}
|
||||||
|
return PsiCodegenPredictor.getPredefinedJvmInternalName(classOrObject);
|
||||||
|
}
|
||||||
|
|
||||||
private final FqName classFqName; // FqName of (possibly inner) class
|
private final FqName classFqName; // FqName of (possibly inner) class
|
||||||
private final JetClassOrObject classOrObject;
|
private final JetClassOrObject classOrObject;
|
||||||
private PsiClass delegate;
|
private PsiClass delegate;
|
||||||
@@ -153,12 +156,31 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private PsiJavaFileStub getJavaFileStub() {
|
private PsiJavaFileStub getJavaFileStub() {
|
||||||
|
return getGeneratedLightClassData().getJavaFileStub();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private ClassDescriptor getDescriptor() {
|
||||||
|
ClassDescriptor descriptor = getGeneratedLightClassData().getDescriptor();
|
||||||
|
assert descriptor != null;
|
||||||
|
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private GeneratedLightClassData getGeneratedLightClassData() {
|
||||||
|
return getGeneratedLightClassData(classOrObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static GeneratedLightClassData getGeneratedLightClassData(JetClassOrObject classOrObject) {
|
||||||
JetClassOrObject outermostClassOrObject = getOutermostClassOrObject(classOrObject);
|
JetClassOrObject outermostClassOrObject = getOutermostClassOrObject(classOrObject);
|
||||||
return CachedValuesManager.getManager(getProject()).getCachedValue(
|
return CachedValuesManager.getManager(classOrObject.getProject()).getCachedValue(
|
||||||
outermostClassOrObject,
|
outermostClassOrObject,
|
||||||
JAVA_API_STUB,
|
JAVA_API_STUB,
|
||||||
KotlinJavaFileStubProvider.createForDeclaredTopLevelClass(outermostClassOrObject),
|
KotlinJavaFileStubProvider.createForDeclaredClass(outermostClassOrObject),
|
||||||
/*trackValue = */false);
|
/*trackValue = */false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -392,6 +414,19 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC
|
|||||||
return classOrObject.isValid();
|
return classOrObject.isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInheritor(@NotNull PsiClass baseClass, boolean checkDeep) {
|
||||||
|
String qualifiedName;
|
||||||
|
if (baseClass instanceof KotlinLightClassForExplicitDeclaration) {
|
||||||
|
qualifiedName = DescriptorUtils.getFQName(((KotlinLightClassForExplicitDeclaration) baseClass).getDescriptor()).asString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qualifiedName = baseClass.getQualifiedName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResolvePackage.checkSuperTypeByFQName(getDescriptor(), qualifiedName, checkDeep);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
|
public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
|
||||||
throw new IncorrectOperationException("Cannot modify compiled kotlin element");
|
throw new IncorrectOperationException("Cannot modify compiled kotlin element");
|
||||||
|
|||||||
+3
-4
@@ -21,7 +21,6 @@ import com.intellij.navigation.ItemPresentation;
|
|||||||
import com.intellij.navigation.ItemPresentationProviders;
|
import com.intellij.navigation.ItemPresentationProviders;
|
||||||
import com.intellij.openapi.util.Comparing;
|
import com.intellij.openapi.util.Comparing;
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub;
|
|
||||||
import com.intellij.psi.impl.light.LightEmptyImplementsList;
|
import com.intellij.psi.impl.light.LightEmptyImplementsList;
|
||||||
import com.intellij.psi.impl.light.LightModifierList;
|
import com.intellij.psi.impl.light.LightModifierList;
|
||||||
import com.intellij.psi.javadoc.PsiDocComment;
|
import com.intellij.psi.javadoc.PsiDocComment;
|
||||||
@@ -32,8 +31,8 @@ import org.jetbrains.annotations.NonNls;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetJavaMirrorMarker;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
|
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetJavaMirrorMarker;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.plugin.JetLanguage;
|
import org.jetbrains.jet.plugin.JetLanguage;
|
||||||
|
|
||||||
@@ -48,7 +47,7 @@ public class KotlinLightClassForPackage extends KotlinWrappingLightClass impleme
|
|||||||
private final GlobalSearchScope searchScope;
|
private final GlobalSearchScope searchScope;
|
||||||
private final Collection<JetFile> files;
|
private final Collection<JetFile> files;
|
||||||
private final int hashCode;
|
private final int hashCode;
|
||||||
private final CachedValue<PsiJavaFileStub> javaFileStub;
|
private final CachedValue<GeneratedLightClassData> javaFileStub;
|
||||||
private final PsiModifierList modifierList;
|
private final PsiModifierList modifierList;
|
||||||
private final LightEmptyImplementsList implementsList;
|
private final LightEmptyImplementsList implementsList;
|
||||||
|
|
||||||
@@ -266,7 +265,7 @@ public class KotlinLightClassForPackage extends KotlinWrappingLightClass impleme
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public PsiClass getDelegate() {
|
public PsiClass getDelegate() {
|
||||||
PsiClass psiClass = LightClassUtil.findClass(packageClassFqName, javaFileStub.getValue());
|
PsiClass psiClass = LightClassUtil.findClass(packageClassFqName, javaFileStub.getValue().getJavaFileStub());
|
||||||
if (psiClass == null) {
|
if (psiClass == null) {
|
||||||
throw new IllegalStateException("Package class was not found " + packageFqName);
|
throw new IllegalStateException("Package class was not found " + packageFqName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ public abstract class LightClassGenerationSupport {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public abstract LightClassConstructionContext analyzeRelevantCode(@NotNull Collection<JetFile> files);
|
public abstract LightClassConstructionContext analyzeRelevantCode(@NotNull Collection<JetFile> files);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public abstract LightClassConstructionContext analyzeRelevantCode(@NotNull JetClassOrObject classOrObject);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public abstract Collection<JetClassOrObject> findClassOrObjectDeclarations(@NotNull FqName fqName, @NotNull GlobalSearchScope searchScope);
|
public abstract Collection<JetClassOrObject> findClassOrObjectDeclarations(@NotNull FqName fqName, @NotNull GlobalSearchScope searchScope);
|
||||||
|
|
||||||
|
|||||||
@@ -78,10 +78,10 @@ public class JetPsiUtilTest extends JetLiteFixture {
|
|||||||
for (JetClassOrObject classOrObject : classOrObjects) {
|
for (JetClassOrObject classOrObject : classOrObjects) {
|
||||||
String classOrObjectName = classOrObject.getName();
|
String classOrObjectName = classOrObject.getName();
|
||||||
if (classOrObjectName != null && classOrObjectName.contains("Local")) {
|
if (classOrObjectName != null && classOrObjectName.contains("Local")) {
|
||||||
assertTrue("JetPsiUtil.isLocalClass should return true for " + classOrObjectName, JetPsiUtil.isLocalClass(classOrObject));
|
assertTrue("JetPsiUtil.isLocalClass should return true for " + classOrObjectName, JetPsiUtil.isLocal(classOrObject));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assertFalse("JetPsiUtil.isLocalClass should return false for " + classOrObjectName, JetPsiUtil.isLocalClass(classOrObject));
|
assertFalse("JetPsiUtil.isLocalClass should return false for " + classOrObjectName, JetPsiUtil.isLocal(classOrObject));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||||
|
|
||||||
|
public fun ClassDescriptor.checkSuperTypeByFQName(qualifiedName: String, deep: Boolean): Boolean {
|
||||||
|
fun checkDescriptor(descriptor: DeclarationDescriptor): Boolean {
|
||||||
|
return qualifiedName == DescriptorUtils.getFQName(descriptor).asString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deep && checkDescriptor(this)) return true
|
||||||
|
|
||||||
|
for (superType in getTypeConstructor().getSupertypes()) {
|
||||||
|
val superDescriptor = superType.getConstructor().getDeclarationDescriptor()
|
||||||
|
if (superDescriptor is ClassDescriptor) {
|
||||||
|
if (checkDescriptor(superDescriptor)) return true
|
||||||
|
if (deep && superDescriptor.checkSuperTypeByFQName(qualifiedName, deep)) return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
@@ -67,6 +67,13 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
|
|||||||
return new LightClassConstructionContext(declarationsCache.getBindingContext(), null);
|
return new LightClassConstructionContext(declarationsCache.getBindingContext(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public LightClassConstructionContext analyzeRelevantCode(@NotNull JetClassOrObject classOrObject) {
|
||||||
|
KotlinCacheManager cacheManager = KotlinCacheManager.getInstance(project);
|
||||||
|
return new LightClassConstructionContext(cacheManager.getLightClassContextCache().getLightClassContext(classOrObject), null);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<JetClassOrObject> findClassOrObjectDeclarations(@NotNull FqName fqName, @NotNull GlobalSearchScope searchScope) {
|
public Collection<JetClassOrObject> findClassOrObjectDeclarations(@NotNull FqName fqName, @NotNull GlobalSearchScope searchScope) {
|
||||||
|
|||||||
@@ -23,22 +23,26 @@ import com.intellij.openapi.project.Project;
|
|||||||
import com.intellij.openapi.util.DefaultModificationTracker;
|
import com.intellij.openapi.util.DefaultModificationTracker;
|
||||||
import com.intellij.openapi.util.ModificationTracker;
|
import com.intellij.openapi.util.ModificationTracker;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.asJava.KotlinLightClassContextCache;
|
||||||
import org.jetbrains.jet.plugin.project.TargetPlatform;
|
import org.jetbrains.jet.plugin.project.TargetPlatform;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class KotlinCacheManager {
|
public class KotlinCacheManager {
|
||||||
|
@NotNull
|
||||||
public static KotlinCacheManager getInstance(@NotNull Project project) {
|
public static KotlinCacheManager getInstance(@NotNull Project project) {
|
||||||
return ServiceManager.getService(project, KotlinCacheManager.class);
|
return ServiceManager.getService(project, KotlinCacheManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<TargetPlatform, DeclarationsCacheProvider> cacheProviders = Maps.newHashMap();
|
private final Map<TargetPlatform, DeclarationsCacheProvider> cacheProviders = Maps.newHashMap();
|
||||||
|
private final KotlinLightClassContextCache lightClassContextCache;
|
||||||
|
|
||||||
private final DefaultModificationTracker kotlinDeclarationsTracker = new DefaultModificationTracker();
|
private final DefaultModificationTracker kotlinDeclarationsTracker = new DefaultModificationTracker();
|
||||||
|
|
||||||
public KotlinCacheManager(@NotNull Project project) {
|
public KotlinCacheManager(@NotNull Project project) {
|
||||||
cacheProviders.put(TargetPlatform.JVM, new JvmDeclarationsCacheProvider(project));
|
cacheProviders.put(TargetPlatform.JVM, new JvmDeclarationsCacheProvider(project));
|
||||||
cacheProviders.put(TargetPlatform.JS, new JSDeclarationsCacheProvider(project));
|
cacheProviders.put(TargetPlatform.JS, new JSDeclarationsCacheProvider(project));
|
||||||
|
lightClassContextCache = new KotlinLightClassContextCache(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,6 +88,10 @@ public class KotlinCacheManager {
|
|||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KotlinLightClassContextCache getLightClassContextCache() {
|
||||||
|
return lightClassContextCache;
|
||||||
|
}
|
||||||
|
|
||||||
public void invalidateCache() {
|
public void invalidateCache() {
|
||||||
kotlinDeclarationsTracker.incModificationCount();
|
kotlinDeclarationsTracker.incModificationCount();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* 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.asJava
|
||||||
|
|
||||||
|
import com.intellij.psi.util.CachedValueProvider
|
||||||
|
import com.intellij.psi.util.CachedValueProvider.Result
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClassOrObject
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.jet.lang.psi.JetPsiUtil
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
|
import java.util.HashMap
|
||||||
|
import com.intellij.psi.util.PsiModificationTracker
|
||||||
|
import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDeclaration
|
||||||
|
import org.jetbrains.jet.lang.psi.JetNamedFunction
|
||||||
|
import org.jetbrains.jet.lang.psi.JetProperty
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClassInitializer
|
||||||
|
import org.jetbrains.jet.plugin.project.ResolveElementCache
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM
|
||||||
|
import java.util.Collections
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile
|
||||||
|
import com.intellij.psi.util.CachedValuesManager
|
||||||
|
import com.intellij.psi.util.CachedValue
|
||||||
|
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace
|
||||||
|
import org.jetbrains.jet.di.InjectorForJavaDescriptorResolver
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
|
||||||
|
class KotlinLightClassContextCache(val project: Project) {
|
||||||
|
private val cacheKey = Key.create<CachedValue<ResolveElementCache>>("KOTLIN_LIGHT_CLASS_CONTEXT_CACHE")
|
||||||
|
|
||||||
|
private val lock = Any()
|
||||||
|
|
||||||
|
private val provider = object: CachedValueProvider<ResolveElementCache> {
|
||||||
|
override fun compute(): CachedValueProvider.Result<ResolveElementCache> {
|
||||||
|
val trace = DelegatingBindingTrace(
|
||||||
|
KotlinCacheManager.getInstance(project).getPossiblyIncompleteDeclarationsForLightClassGeneration().getBindingContext(),
|
||||||
|
"Trace for KotlinLightClassContextCache"
|
||||||
|
)
|
||||||
|
val resolveSession = AnalyzerFacadeForJVM.createLazyResolveSession(
|
||||||
|
project,
|
||||||
|
JetFilesProvider.getInstance(project)!!.allInScope(GlobalSearchScope.allScope(project)),
|
||||||
|
trace,
|
||||||
|
InjectorForJavaDescriptorResolver(project, trace),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
return Result.create(
|
||||||
|
ResolveElementCache(resolveSession, project),
|
||||||
|
PsiModificationTracker.MODIFICATION_COUNT,
|
||||||
|
KotlinCacheManager.getInstance(project).getDeclarationsTracker()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun getLightClassContext(classOrObject: JetClassOrObject): BindingContext {
|
||||||
|
if (!JetPsiUtil.isLocal(classOrObject)) {
|
||||||
|
return KotlinCacheManager.getInstance(project).getPossiblyIncompleteDeclarationsForLightClassGeneration().getBindingContext()
|
||||||
|
}
|
||||||
|
|
||||||
|
val resolveElementCache = CachedValuesManager.getManager(project).getCachedValue(project, cacheKey, provider, false)
|
||||||
|
return resolveElementCache?.resolveElement(classOrObject) ?: BindingContext.EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -360,7 +360,7 @@ public class JetSourceNavigationHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return JetPsiUtil.isLocalClass(classOrObject) ? null : LightClassUtil.getPsiClass(classOrObject);
|
return LightClassUtil.getPsiClass(classOrObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ public class PluginJetFilesProvider extends JetFilesProvider {
|
|||||||
!JetPluginUtil.isKtFileInGradleProjectInWrongFolder(virtualFile, project);
|
!JetPluginUtil.isKtFileInGradleProjectInWrongFolder(virtualFile, project);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<JetFile> allInScope(@NotNull GlobalSearchScope scope) {
|
public Collection<JetFile> allInScope(@NotNull GlobalSearchScope scope) {
|
||||||
return cache.getValue(scope);
|
return cache.getValue(scope);
|
||||||
|
|||||||
@@ -26,12 +26,10 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer;
|
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.plugin.libraries.JetSourceNavigationHelper;
|
import org.jetbrains.jet.plugin.libraries.JetSourceNavigationHelper;
|
||||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
import org.jetbrains.jet.plugin.search.usagesSearch.UsagesSearchPackage;
|
||||||
import org.jetbrains.jet.plugin.stubindex.JetSuperClassIndex;
|
import org.jetbrains.jet.plugin.stubindex.JetSuperClassIndex;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -60,9 +58,9 @@ public class KotlinDirectInheritorsSearcher extends QueryExecutorBase<PsiClass,
|
|||||||
GlobalSearchScope scope = (GlobalSearchScope) queryParameters.getScope();
|
GlobalSearchScope scope = (GlobalSearchScope) queryParameters.getScope();
|
||||||
Collection<JetClassOrObject> candidates = JetSuperClassIndex.getInstance().get(name, clazz.getProject(), scope);
|
Collection<JetClassOrObject> candidates = JetSuperClassIndex.getInstance().get(name, clazz.getProject(), scope);
|
||||||
for (JetClassOrObject candidate : candidates) {
|
for (JetClassOrObject candidate : candidates) {
|
||||||
JetFile containingFile = (JetFile) candidate.getContainingFile();
|
ClassDescriptor classDescriptor = (ClassDescriptor) UsagesSearchPackage.getDescriptor(candidate);
|
||||||
KotlinCodeAnalyzer sessionForFile = AnalyzerFacadeWithCache.getLazyResolveSessionForFile(containingFile);
|
if (classDescriptor == null) continue;
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) sessionForFile.resolveToDescriptor(candidate);
|
|
||||||
for (JetType type : classDescriptor.getTypeConstructor().getSupertypes()) {
|
for (JetType type : classDescriptor.getTypeConstructor().getSupertypes()) {
|
||||||
ClassifierDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
ClassifierDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||||
if (declarationDescriptor != null) {
|
if (declarationDescriptor != null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user