EA-36473 Wrap method for JetLightClass with invalid fq name
This commit is contained in:
@@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 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.codegen;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
|
||||||
|
|
||||||
|
public final class PsiCodegenPredictor {
|
||||||
|
private PsiCodegenPredictor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean checkPredictedNameFromPsi(
|
||||||
|
@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor, JvmClassName nameFromDescriptors
|
||||||
|
) {
|
||||||
|
PsiElement element = descriptorToDeclaration(bindingTrace.getBindingContext(), descriptor);
|
||||||
|
if (element instanceof JetDeclaration) {
|
||||||
|
JvmClassName classNameFromPsi = getPredefinedJvmClassName((JetDeclaration) element);
|
||||||
|
assert classNameFromPsi == null || classNameFromPsi.equals(nameFromDescriptors) : "Invalid algorithm for getting qualified name from psi!";
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static JvmClassName getPredefinedJvmClassName(@NotNull JetFile jetFile, boolean withNamespace) {
|
||||||
|
String packageName = jetFile.getPackageName();
|
||||||
|
if (packageName == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JvmClassName packageJvmName = JvmClassName.byFqNameWithoutInnerClasses(packageName);
|
||||||
|
return !withNamespace ? packageJvmName : addPackageClass(packageJvmName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Finish this method for all cases. Now it's only used and tested in JetLightClass.
|
||||||
|
*
|
||||||
|
* @return null if no prediction can be done.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static JvmClassName getPredefinedJvmClassName(@NotNull JetDeclaration declaration) {
|
||||||
|
// TODO: Method won't work for declarations inside class objects
|
||||||
|
// TODO: Method won't give correct class name for traits implementations
|
||||||
|
|
||||||
|
JetDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(declaration, JetDeclaration.class);
|
||||||
|
JvmClassName parentClassName = parentDeclaration != null ?
|
||||||
|
getPredefinedJvmClassName(parentDeclaration) :
|
||||||
|
getPredefinedJvmClassName((JetFile) declaration.getContainingFile(), false);
|
||||||
|
if (parentClassName == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration instanceof JetClassObject) {
|
||||||
|
// Get parent and assign Class object prefix
|
||||||
|
return JvmClassName.byInternalName(parentClassName.getInternalName() + JvmAbi.CLASS_OBJECT_SUFFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration instanceof JetNamedDeclaration) {
|
||||||
|
if (!PsiTreeUtil.instanceOf(declaration, JetClass.class, JetObjectDeclaration.class, JetNamedFunction.class, JetProperty.class) ||
|
||||||
|
declaration instanceof JetEnumEntry) {
|
||||||
|
// Other subclasses are not valid for class name prediction.
|
||||||
|
// For example EnumEntry, JetFunctionLiteral
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) declaration;
|
||||||
|
Name name = namedDeclaration.getNameAsName();
|
||||||
|
if (name == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
FqName fqName = parentClassName.getFqName();
|
||||||
|
|
||||||
|
if (declaration instanceof JetNamedFunction) {
|
||||||
|
if (parentDeclaration == null) {
|
||||||
|
JvmClassName packageClass = addPackageClass(parentClassName);
|
||||||
|
return JvmClassName.byInternalName(packageClass.getInternalName() + "$" + name.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(parentDeclaration instanceof JetClass || parentDeclaration instanceof JetObjectDeclaration)) {
|
||||||
|
// Can't generate predefined name for internal functions
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: looks like a bug - for class in getter of top level property class name will be $propertyName$ClassName but not
|
||||||
|
// namespace$propertyName$ClassName
|
||||||
|
if (declaration instanceof JetProperty) {
|
||||||
|
return JvmClassName.byInternalName(parentClassName.getInternalName() + "$" + name.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fqName.isRoot()) {
|
||||||
|
return JvmClassName.byInternalName(name.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return JvmClassName.byInternalName(parentDeclaration == null ?
|
||||||
|
parentClassName.getInternalName() + "/" + name.getName() :
|
||||||
|
parentClassName.getInternalName() + "$" + name.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JvmClassName addPackageClass(JvmClassName packageName) {
|
||||||
|
FqName name = packageName.getFqName();
|
||||||
|
return name.isRoot() ?
|
||||||
|
JvmClassName.byFqNameWithoutInnerClasses(JvmAbi.PACKAGE_CLASS) :
|
||||||
|
JvmClassName.byInternalName(packageName.getInternalName() + "/" + JvmAbi.PACKAGE_CLASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean checkPredictedClassNameForFun(
|
||||||
|
@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor, ClassDescriptor classDescriptor
|
||||||
|
) {
|
||||||
|
PsiElement element = descriptorToDeclaration(bindingTrace.getBindingContext(), descriptor);
|
||||||
|
PsiElement classDeclaration = descriptorToDeclaration(bindingTrace.getBindingContext(), classDescriptor);
|
||||||
|
if (element instanceof JetNamedFunction && classDeclaration instanceof JetDeclaration) {
|
||||||
|
JvmClassName classNameFromPsi = getPredefinedJvmClassName((JetDeclaration) classDeclaration);
|
||||||
|
JvmClassName classNameForFun = getPredefinedJvmClassNameForFun((JetNamedFunction) element);
|
||||||
|
assert classNameForFun == null || classNameForFun.equals(classNameFromPsi) : "Invalid algorithm for getting enclosing method name!";
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static JvmClassName getPredefinedJvmClassNameForFun(@NotNull JetNamedFunction function) {
|
||||||
|
PsiElement parent = function.getParent();
|
||||||
|
if (parent instanceof JetFile) {
|
||||||
|
return getPredefinedJvmClassName((JetFile) parent, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
JetClass containingClass = PsiTreeUtil.getParentOfType(function, JetClass.class, true, JetDeclaration.class);
|
||||||
|
if (containingClass != null) {
|
||||||
|
return getPredefinedJvmClassName(containingClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
JetObjectDeclaration objectDeclaration = PsiTreeUtil.getParentOfType(function, JetObjectDeclaration.class, true, JetDeclaration.class);
|
||||||
|
if (objectDeclaration != null) {
|
||||||
|
if (objectDeclaration.getParent() instanceof JetClassObject) {
|
||||||
|
return getPredefinedJvmClassName((JetClassObject) objectDeclaration.getParent());
|
||||||
|
}
|
||||||
|
|
||||||
|
return getPredefinedJvmClassName(objectDeclaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-1
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.codegen.binding;
|
package org.jetbrains.jet.codegen.binding;
|
||||||
|
|
||||||
import com.intellij.util.containers.Stack;
|
import com.intellij.util.containers.Stack;
|
||||||
|
import org.jetbrains.jet.codegen.PsiCodegenPredictor;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
@@ -69,6 +70,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
: JetStandardClasses.getFunction(arity)).getDefaultType()), JetScope.EMPTY,
|
: JetStandardClasses.getFunction(arity)).getDefaultType()), JetScope.EMPTY,
|
||||||
Collections.<ConstructorDescriptor>emptySet(), null);
|
Collections.<ConstructorDescriptor>emptySet(), null);
|
||||||
|
|
||||||
|
assert PsiCodegenPredictor.checkPredictedClassNameForFun(bindingTrace, funDescriptor, classDescriptor);
|
||||||
bindingTrace.record(CLASS_FOR_FUNCTION, funDescriptor, classDescriptor);
|
bindingTrace.record(CLASS_FOR_FUNCTION, funDescriptor, classDescriptor);
|
||||||
return classDescriptor;
|
return classDescriptor;
|
||||||
}
|
}
|
||||||
@@ -134,7 +136,9 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
super.visitEnumEntry(enumEntry);
|
super.visitEnumEntry(enumEntry);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bindingTrace.record(FQN, descriptor, bindingTrace.get(FQN, peekFromStack(classStack)));
|
JvmClassName jvmClassName = bindingTrace.get(FQN, peekFromStack(classStack));
|
||||||
|
assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, jvmClassName);
|
||||||
|
bindingTrace.record(FQN, descriptor, jvmClassName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiElement;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.codegen.CodegenUtil;
|
import org.jetbrains.jet.codegen.CodegenUtil;
|
||||||
|
import org.jetbrains.jet.codegen.PsiCodegenPredictor;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
@@ -132,6 +133,7 @@ public class CodegenBinding {
|
|||||||
|
|
||||||
recordClosure(bindingTrace, null, classDescriptor, null, className, false);
|
recordClosure(bindingTrace, null, classDescriptor, null, className, false);
|
||||||
|
|
||||||
|
assert PsiCodegenPredictor.checkPredictedClassNameForFun(bindingTrace, scriptDescriptor, classDescriptor);
|
||||||
bindingTrace.record(CLASS_FOR_FUNCTION, scriptDescriptor, classDescriptor);
|
bindingTrace.record(CLASS_FOR_FUNCTION, scriptDescriptor, classDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,6 +172,7 @@ public class CodegenBinding {
|
|||||||
|
|
||||||
final MutableClosure closure = new MutableClosure(superCall, enclosing, enclosingReceiver);
|
final MutableClosure closure = new MutableClosure(superCall, enclosing, enclosingReceiver);
|
||||||
|
|
||||||
|
assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, classDescriptor, name);
|
||||||
bindingTrace.record(FQN, classDescriptor, name);
|
bindingTrace.record(FQN, classDescriptor, name);
|
||||||
bindingTrace.record(CLOSURE, classDescriptor, closure);
|
bindingTrace.record(CLOSURE, classDescriptor, closure);
|
||||||
|
|
||||||
@@ -260,6 +263,8 @@ public class CodegenBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
name = JvmClassName.byInternalName(getJvmInternalFQNameImpl(bindingTrace, descriptor));
|
name = JvmClassName.byInternalName(getJvmInternalFQNameImpl(bindingTrace, descriptor));
|
||||||
|
|
||||||
|
assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, name);
|
||||||
bindingTrace.record(FQN, descriptor, name);
|
bindingTrace.record(FQN, descriptor, name);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,20 +37,15 @@ 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.jet.analyzer.AnalyzeExhaust;
|
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||||
import org.jetbrains.jet.codegen.ClassBuilder;
|
import org.jetbrains.jet.codegen.*;
|
||||||
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.GenerationState;
|
||||||
import org.jetbrains.jet.codegen.state.GenerationStrategy;
|
import org.jetbrains.jet.codegen.state.GenerationStrategy;
|
||||||
import org.jetbrains.jet.lang.BuiltinsScopeExtensionMode;
|
import org.jetbrains.jet.lang.BuiltinsScopeExtensionMode;
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetFunction;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
|
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JetJavaMirrorMarker;
|
import org.jetbrains.jet.lang.resolve.java.JetJavaMirrorMarker;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||||
import org.jetbrains.jet.plugin.JetLanguage;
|
import org.jetbrains.jet.plugin.JetLanguage;
|
||||||
@@ -246,15 +241,33 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static JetLightClass wrapDelegate(JetClass jetClass) {
|
public static JetLightClass wrapDelegate(@Nullable JetClass jetClass) {
|
||||||
if (jetClass == null) return null;
|
if (jetClass == null) {
|
||||||
return create(jetClass.getManager(), (JetFile) jetClass.getContainingFile(), JetPsiUtil.getFQName(jetClass));
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapDelegate(jetClass, PsiCodegenPredictor.getPredefinedJvmClassName(jetClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static PsiMethod wrapMethod(JetFunction function) {
|
private static JetLightClass wrapDelegate(@NotNull JetDeclaration declaration, @Nullable JvmClassName jvmClassName) {
|
||||||
JetClass containingClass = PsiTreeUtil.getParentOfType(function, JetClass.class);
|
if (jvmClassName == null) {
|
||||||
JetLightClass wrapper = wrapDelegate(containingClass);
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return create(declaration.getManager(), (JetFile) declaration.getContainingFile(), jvmClassName.getFqName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static PsiMethod wrapMethod(@NotNull JetNamedFunction function) {
|
||||||
|
//noinspection unchecked
|
||||||
|
if (PsiTreeUtil.getParentOfType(function, JetFunction.class, JetProperty.class) != null) {
|
||||||
|
// Don't generate method wrappers for internal declarations. Their classes are not generated during calcStub
|
||||||
|
// with ClassBuilderMode.SIGNATURES mode, and this produces "Class not found exception" in getDelegate()
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JetLightClass wrapper = wrapDelegate(function, PsiCodegenPredictor.getPredefinedJvmClassNameForFun(function));
|
||||||
if (wrapper == null) {
|
if (wrapper == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -264,6 +277,7 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa
|
|||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ import com.intellij.util.Processor;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.asJava.JetLightClass;
|
import org.jetbrains.jet.asJava.JetLightClass;
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
import org.jetbrains.jet.lang.psi.JetClass;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassBody;
|
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||||
import org.jetbrains.jet.lang.psi.JetFunction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
@@ -46,10 +45,10 @@ public class KotlinReferencesSearcher extends QueryExecutorBase<PsiReference, Re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (element instanceof JetFunction) {
|
else if (element instanceof JetNamedFunction) {
|
||||||
final JetFunction function = (JetFunction) element;
|
final JetNamedFunction function = (JetNamedFunction) element;
|
||||||
final String name = function.getName();
|
final String name = function.getName();
|
||||||
if (function.getParent() instanceof JetClassBody && name != null) {
|
if (name != null) {
|
||||||
final PsiMethod method = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod>() {
|
final PsiMethod method = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod>() {
|
||||||
@Override
|
@Override
|
||||||
public PsiMethod compute() {
|
public PsiMethod compute() {
|
||||||
@@ -57,13 +56,9 @@ public class KotlinReferencesSearcher extends QueryExecutorBase<PsiReference, Re
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
PsiMethod target = JetLightClass.wrapMethod((JetFunction) element);
|
queryParameters.getOptimizer().searchWord(name, queryParameters.getScope(), true, method);
|
||||||
if (target != null) {
|
|
||||||
queryParameters.getOptimizer().searchWord(name, queryParameters.getScope(), true, target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun test() {
|
||||||
|
class Test() {
|
||||||
|
fun <caret>internalFun() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
val a = object {
|
||||||
|
fun <caret>testing() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class Test {
|
||||||
|
class object {
|
||||||
|
fun <caret>testing() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
object SomeObject {
|
||||||
|
fun <caret>testingInObjectNew() = 12
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
trait Some {
|
||||||
|
fun <caret>some() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
trait Some {
|
||||||
|
fun <caret>some()
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fun <caret>test() {
|
||||||
|
}
|
||||||
@@ -18,15 +18,15 @@ package org.jetbrains.jet.plugin.javaFacade;
|
|||||||
|
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
import com.intellij.psi.search.GlobalSearchScope;
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import com.intellij.testFramework.LightProjectDescriptor;
|
import com.intellij.testFramework.LightProjectDescriptor;
|
||||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.asJava.JetLightClass;
|
import org.jetbrains.jet.asJava.JetLightClass;
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
import org.jetbrains.jet.lang.psi.JetClass;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
|
||||||
import org.jetbrains.jet.plugin.JetLightProjectDescriptor;
|
import org.jetbrains.jet.plugin.JetLightProjectDescriptor;
|
||||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||||
|
|
||||||
@@ -46,21 +46,49 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase {
|
|||||||
myFixture.setTestDataPath(PluginTestCaseBase.getTestDataPathBase() + "/javaFacade");
|
myFixture.setTestDataPath(PluginTestCaseBase.getTestDataPathBase() + "/javaFacade");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDoNotWrapFunFromLocalClass() {
|
||||||
|
doTestWrapMethod(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDoNotWrapFunInAnonymousObject() {
|
||||||
|
doTestWrapMethod(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrapFunInClassObject() {
|
||||||
|
doTestWrapMethod(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrapTopLevelFun() {
|
||||||
|
doTestWrapMethod(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrapFunWithImplInTrait() {
|
||||||
|
doTestWrapMethod(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrapFunWithoutImplInTrait() {
|
||||||
|
doTestWrapMethod(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrapFunInObject() {
|
||||||
|
doTestWrapMethod(true);
|
||||||
|
}
|
||||||
|
|
||||||
public void testInnerClass() throws Exception {
|
public void testInnerClass() throws Exception {
|
||||||
myFixture.configureByFile(getTestName(true) + ".kt");
|
myFixture.configureByFile(getTestName(true) + ".kt");
|
||||||
|
|
||||||
JavaPsiFacade facade = myFixture.getJavaFacade();
|
JavaPsiFacade facade = myFixture.getJavaFacade();
|
||||||
PsiClass mirrorClass = facade.findClass("foo.Outer.Inner", GlobalSearchScope.allScope(getProject()));
|
PsiClass mirrorClass = facade.findClass("foo.Outer.Inner", GlobalSearchScope.allScope(getProject()));
|
||||||
|
|
||||||
assertNotNull(mirrorClass);
|
assertNotNull(mirrorClass);
|
||||||
PsiMethod[] fun = mirrorClass.findMethodsByName("innerFun", false);
|
PsiMethod[] fun = mirrorClass.findMethodsByName("innerFun", false);
|
||||||
|
|
||||||
assertEquals(fun[0].getReturnType(), PsiType.VOID);
|
assertEquals(fun[0].getReturnType(), PsiType.VOID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testClassObject() throws Exception {
|
public void testClassObject() throws Exception {
|
||||||
myFixture.configureByFile(getTestName(true) + ".kt");
|
myFixture.configureByFile(getTestName(true) + ".kt");
|
||||||
|
|
||||||
JavaPsiFacade facade = myFixture.getJavaFacade();
|
JavaPsiFacade facade = myFixture.getJavaFacade();
|
||||||
PsiClass theClass = facade.findClass("foo.TheClass", GlobalSearchScope.allScope(getProject()));
|
PsiClass theClass = facade.findClass("foo.TheClass", GlobalSearchScope.allScope(getProject()));
|
||||||
|
|
||||||
@@ -71,7 +99,7 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase {
|
|||||||
|
|
||||||
PsiType type = classobj.getType();
|
PsiType type = classobj.getType();
|
||||||
assertTrue(type instanceof PsiClassType);
|
assertTrue(type instanceof PsiClassType);
|
||||||
|
|
||||||
assertEquals("foo.TheClass.ClassObject$", type.getCanonicalText());
|
assertEquals("foo.TheClass.ClassObject$", type.getCanonicalText());
|
||||||
|
|
||||||
PsiClass classObjectClass = ((PsiClassType) type).resolve();
|
PsiClass classObjectClass = ((PsiClassType) type).resolve();
|
||||||
@@ -98,4 +126,28 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase {
|
|||||||
JetPsiUtil.getFQName(aClass));
|
JetPsiUtil.getFQName(aClass));
|
||||||
assertNull(createdByFactory);
|
assertNull(createdByFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doTestWrapMethod(boolean shouldBeWrapped) {
|
||||||
|
myFixture.configureByFile(getTestName(true) + ".kt");
|
||||||
|
|
||||||
|
int offset = myFixture.getEditor().getCaretModel().getOffset();
|
||||||
|
PsiElement elementAt = myFixture.getFile().findElementAt(offset);
|
||||||
|
|
||||||
|
assertNotNull("Caret should be set for tested file", elementAt);
|
||||||
|
|
||||||
|
JetNamedFunction jetFunction = PsiTreeUtil.getParentOfType(elementAt, JetNamedFunction.class);
|
||||||
|
assertNotNull("Caret should be placed to function definition", jetFunction);
|
||||||
|
|
||||||
|
// Should not fail!
|
||||||
|
PsiMethod psiMethod = JetLightClass.wrapMethod(jetFunction);
|
||||||
|
|
||||||
|
if (shouldBeWrapped) {
|
||||||
|
assertNotNull(String.format("Failed to wrap jetFunction '%s' to method", jetFunction.getText()), psiMethod);
|
||||||
|
assertInstanceOf(psiMethod, PsiCompiledElement.class);
|
||||||
|
assertEquals("Invalid original element for generated method", ((PsiCompiledElement)psiMethod).getMirror(), jetFunction);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertNull("There should be no wrapper for given method", psiMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user