Record reference to class object directly
not to containing class descriptor
This commit is contained in:
@@ -1698,10 +1698,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
}
|
||||
|
||||
//if (descriptor instanceof VariableAsFunctionDescriptor) {
|
||||
// descriptor = ((VariableAsFunctionDescriptor) descriptor).getVariableDescriptor();
|
||||
//}
|
||||
|
||||
assert descriptor != null : "Couldn't find descriptor for '" + expression.getText() + "'";
|
||||
descriptor = descriptor.getOriginal();
|
||||
|
||||
@@ -1738,7 +1734,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
||||
if (classDescriptor.getKind() == ClassKind.OBJECT) {
|
||||
if (classDescriptor.getKind() == ClassKind.OBJECT || classDescriptor.getKind() == ClassKind.CLASS_OBJECT) {
|
||||
return StackValue.singleton(classDescriptor, typeMapper);
|
||||
}
|
||||
if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.jet.lang.psi.JetExpression
|
||||
|
||||
|
||||
public fun JetReturnExpression.getTargetFunctionDescriptor(context: BindingContext): FunctionDescriptor? {
|
||||
val targetLabel = getTargetLabel()
|
||||
if (targetLabel != null) return context[LABEL_TARGET, targetLabel]?.let { context[FUNCTION, it] }
|
||||
|
||||
+1
@@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.types.JetType;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.LibrarySourceHacks.filterOutMembersFromLibrarySource;
|
||||
import static org.jetbrains.jet.lang.resolve.descriptorUtil.DescriptorUtilPackage.getClassObjectReferenceTarget;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class CallableDescriptorCollectors<D extends CallableDescriptor> implements Iterable<CallableDescriptorCollector<D>> {
|
||||
|
||||
+8
@@ -37,6 +37,7 @@ import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.impl.PackageFragmentDescriptorImpl
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingContext
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.getTopmostParentQualifiedExpressionForSelector
|
||||
import org.jetbrains.jet.lang.resolve.descriptorUtil.getClassObjectReferenceTarget
|
||||
|
||||
public class QualifierReceiver(
|
||||
val expression: JetSimpleNameExpression,
|
||||
@@ -150,6 +151,13 @@ private fun QualifierReceiver.resolveReferenceTarget(selector: DeclarationDescri
|
||||
return packageView
|
||||
}
|
||||
|
||||
if (classifier != null && containingDeclaration is ClassDescriptor && classifier == containingDeclaration) {
|
||||
return classifier
|
||||
}
|
||||
if (classifier is ClassDescriptor && classifier.getClassObjectDescriptor() != null) {
|
||||
return classifier.getClassObjectReferenceTarget()
|
||||
}
|
||||
|
||||
return descriptor
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package foo
|
||||
fun test() {
|
||||
A.d
|
||||
A.<!INVISIBLE_MEMBER!>f<!>
|
||||
<!INVISIBLE_MEMBER!>CCC<!>
|
||||
<!INVISIBLE_MEMBER!>CCC<!>.<!INVISIBLE_MEMBER!>classObjectVar<!>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package Jet86
|
||||
|
||||
~A~class A {
|
||||
class object {
|
||||
class A {
|
||||
class ~A~object {
|
||||
~A.x~val x = 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ fun test() = <caret>A(1)
|
||||
|
||||
Resolved call:
|
||||
|
||||
Resulting descriptor: class A
|
||||
Resulting descriptor: class object
|
||||
|
||||
Explicit receiver kind = NO_EXPLICIT_RECEIVER
|
||||
This object = NO_RECEIVER
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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.descriptorUtil
|
||||
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind.ENUM_ENTRY
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind.ENUM_CLASS
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind.OBJECT
|
||||
|
||||
|
||||
public fun ClassDescriptor.getClassObjectReferenceTarget(): ClassDescriptor {
|
||||
val classObjectDescriptor = getClassObjectDescriptor()
|
||||
return if (classObjectDescriptor == null || hasSyntheticClassObject()) this else classObjectDescriptor
|
||||
}
|
||||
|
||||
public fun ClassDescriptor.hasSyntheticClassObject(): Boolean = getKind() in setOf(ENUM_ENTRY, ENUM_CLASS, OBJECT)
|
||||
+24
-17
@@ -79,27 +79,29 @@ public class JetSourceNavigationHelper {
|
||||
@Nullable
|
||||
public static JetClassOrObject getSourceClassOrObject(@NotNull JetClassOrObject decompiledClassOrObject) {
|
||||
if (decompiledClassOrObject instanceof JetObjectDeclaration && decompiledClassOrObject.getParent() instanceof JetClassObject) {
|
||||
// class object case
|
||||
|
||||
JetClass decompiledClass = PsiTreeUtil.getParentOfType(decompiledClassOrObject, JetClass.class);
|
||||
assert decompiledClass != null;
|
||||
|
||||
JetClass sourceClass = (JetClass) getSourceForNamedClassOrObject(decompiledClass);
|
||||
if (sourceClass == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (sourceClass.hasModifier(JetTokens.ENUM_KEYWORD)) {
|
||||
return sourceClass;
|
||||
}
|
||||
|
||||
JetClassObject classObject = sourceClass.getClassObject();
|
||||
assert classObject != null;
|
||||
return classObject.getObjectDeclaration();
|
||||
return getSourceClassObject((JetClassObject) decompiledClassOrObject.getParent());
|
||||
}
|
||||
return getSourceForNamedClassOrObject(decompiledClassOrObject);
|
||||
}
|
||||
|
||||
private static JetClassOrObject getSourceClassObject(JetClassObject decompiledClassObject) {
|
||||
JetClass decompiledClass = PsiTreeUtil.getParentOfType(decompiledClassObject, JetClass.class);
|
||||
assert decompiledClass != null;
|
||||
|
||||
JetClass sourceClass = (JetClass) getSourceForNamedClassOrObject(decompiledClass);
|
||||
if (sourceClass == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (sourceClass.hasModifier(JetTokens.ENUM_KEYWORD)) {
|
||||
return sourceClass;
|
||||
}
|
||||
|
||||
JetClassObject classObject = sourceClass.getClassObject();
|
||||
assert classObject != null;
|
||||
return classObject.getObjectDeclaration();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static GlobalSearchScope createLibrarySourcesScope(@NotNull JetNamedDeclaration decompiledDeclaration) {
|
||||
JetFile containingFile = decompiledDeclaration.getContainingJetFile();
|
||||
@@ -448,6 +450,11 @@ public class JetSourceNavigationHelper {
|
||||
return getSourceClassOrObject(declaration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetDeclaration visitClassObject(@NotNull JetClassObject classObject, Void data) {
|
||||
return getSourceClassObject(classObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetDeclaration visitClass(@NotNull JetClass klass, Void data) {
|
||||
return getSourceClassOrObject(klass);
|
||||
|
||||
@@ -30,14 +30,22 @@ import org.jetbrains.jet.plugin.intentions.OperatorToFunctionIntention
|
||||
import org.jetbrains.jet.lang.psi.JetQualifiedExpression
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.jet.lang.psi.JetObjectDeclaration
|
||||
import org.jetbrains.jet.lang.psi.JetClassObject
|
||||
import org.jetbrains.jet.lang.psi.JetClass
|
||||
|
||||
// Navigation element of the resolved reference
|
||||
// For property accessor return enclosing property
|
||||
// For class object return enclosing class
|
||||
public val PsiReference.unwrappedTargets: Set<PsiElement>
|
||||
get() {
|
||||
fun PsiElement.adjust(): PsiElement? {
|
||||
val target = unwrapped
|
||||
return if (target is JetPropertyAccessor) target.getParentByType(javaClass<JetProperty>()) else target
|
||||
return when {
|
||||
target is JetPropertyAccessor -> target.getParentByType(javaClass<JetProperty>())
|
||||
target is JetObjectDeclaration && target.isClassObject() -> target.getParentByType(javaClass<JetClass>())
|
||||
else -> target
|
||||
}
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.jetbrains.jet.lang.psi.psiUtil.*
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||
import org.jetbrains.jet.plugin.JetBundle
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
import com.intellij.psi.PsiPackage
|
||||
import org.jetbrains.jet.lexer.JetTokens
|
||||
import org.jetbrains.jet.plugin.references.JetArrayAccessReference
|
||||
@@ -202,11 +201,10 @@ public object JetUsageTypeProvider : UsageTypeProviderEx {
|
||||
val descriptor = context[BindingContext.REFERENCE_TARGET, refExpr]
|
||||
|
||||
return when (descriptor) {
|
||||
is ClassifierDescriptor -> if (DescriptorUtils.isSingleton(descriptor)) {
|
||||
is ClassifierDescriptor -> when ((descriptor as? ClassDescriptor)?.getKind()) {
|
||||
// Treat object accesses as variables to simulate the old behaviour (when variables were created for objects)
|
||||
getVariableUsageType()
|
||||
} else {
|
||||
getClassUsageType()
|
||||
ClassKind.OBJECT, ClassKind.ENUM_ENTRY -> getVariableUsageType()
|
||||
else -> getClassUsageType()
|
||||
}
|
||||
is PackageViewDescriptor -> {
|
||||
if (refExpr.getReference()?.resolve() is PsiPackage) getPackageUsageType() else getClassUsageType()
|
||||
|
||||
@@ -28,18 +28,18 @@ import org.jetbrains.jet.lang.psi.psiUtil.getReceiverExpression
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
|
||||
private fun DeclarationDescriptor.getImportableDescriptor() =
|
||||
if (this is ConstructorDescriptor || DescriptorUtils.isClassObject(this)) getContainingDeclaration()!! else this
|
||||
|
||||
public val DeclarationDescriptor.importableFqName: FqName?
|
||||
get() {
|
||||
if (this is ConstructorDescriptor) return getContainingDeclaration().importableFqName
|
||||
val mayBeUnsafe = DescriptorUtils.getFqName(this)
|
||||
return if (mayBeUnsafe.isSafe()) {
|
||||
mayBeUnsafe.toSafe()
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
val mayBeUnsafe = DescriptorUtils.getFqName(getImportableDescriptor())
|
||||
return if (mayBeUnsafe.isSafe()) mayBeUnsafe.toSafe() else null
|
||||
}
|
||||
|
||||
public val DeclarationDescriptor.importableFqNameSafe: FqName
|
||||
get() = DescriptorUtils.getFqNameSafe(getImportableDescriptor())
|
||||
|
||||
public fun DeclarationDescriptor.canBeReferencedViaImport(): Boolean {
|
||||
if (this is PackageViewDescriptor || DescriptorUtils.isTopLevelDeclaration(this)) {
|
||||
return true
|
||||
|
||||
+2
-5
@@ -37,7 +37,6 @@ import org.jetbrains.jet.lang.cfg.Label
|
||||
import org.jetbrains.jet.plugin.refactoring.JetNameValidatorImpl
|
||||
import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil
|
||||
import org.jetbrains.jet.plugin.imports.canBeReferencedViaImport
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.jet.lang.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.jet.utils.DFS
|
||||
@@ -61,8 +60,7 @@ import org.jetbrains.jet.lang.resolve.OverridingUtil
|
||||
import org.jetbrains.jet.lang.resolve.bindingContextUtil.isUsedAsStatement
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.isFunctionLiteralOutsideParentheses
|
||||
import org.jetbrains.jet.plugin.util.psiModificationUtil.moveInsideParenthesesAndReplaceWith
|
||||
import org.jetbrains.jet.plugin.imports.importableFqNameSafe
|
||||
|
||||
private val DEFAULT_FUNCTION_NAME = "myFun"
|
||||
private val DEFAULT_RETURN_TYPE = KotlinBuiltIns.getInstance().getUnitType()
|
||||
@@ -476,8 +474,7 @@ private fun ExtractionData.inferParametersInfo(
|
||||
info.typeParameters, info.nonDenotableTypes, false
|
||||
)) continue
|
||||
|
||||
val replacingDescriptor = (originalDescriptor as? ConstructorDescriptor)?.getContainingDeclaration() ?: originalDescriptor
|
||||
info.replacementMap[refInfo.offsetInBody] = FqNameReplacement(DescriptorUtils.getFqNameSafe(replacingDescriptor))
|
||||
info.replacementMap[refInfo.offsetInBody] = FqNameReplacement(originalDescriptor.importableFqNameSafe)
|
||||
}
|
||||
else {
|
||||
val extractThis = hasThisReceiver || thisExpr != null
|
||||
|
||||
@@ -5,6 +5,5 @@ fun foo() {
|
||||
}
|
||||
|
||||
// main.kt
|
||||
//public class <1>WithInnerAndObject {
|
||||
// class object {
|
||||
// class <1>object {
|
||||
// fun <2>foo() {
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.reflect.ReflectionTypes;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.k2js.config.EcmaVersion;
|
||||
import org.jetbrains.k2js.config.LibrarySourcesConfig;
|
||||
@@ -36,6 +37,7 @@ import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lang.descriptors.ClassKind.CLASS_OBJECT;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
||||
import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*;
|
||||
@@ -234,15 +236,14 @@ public final class StaticContext {
|
||||
return scope.declareFreshName(getSuggestedName(descriptor));
|
||||
}
|
||||
};
|
||||
Rule<JsName> constructorHasTheSameNameAsTheClass = new Rule<JsName>() {
|
||||
Rule<JsName> constructorOrClassObjectHasTheSameNameAsTheClass = new Rule<JsName>() {
|
||||
@Override
|
||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (!(descriptor instanceof ConstructorDescriptor)) {
|
||||
return null;
|
||||
if (descriptor instanceof ConstructorDescriptor || (DescriptorUtils.isClassObject(descriptor))) {
|
||||
//noinspection ConstantConditions
|
||||
return getNameForDescriptor(descriptor.getContainingDeclaration());
|
||||
}
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
assert containingClass != null : "Can't have constructor without a class";
|
||||
return getNameForDescriptor(containingClass);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -324,7 +325,7 @@ public final class StaticContext {
|
||||
}
|
||||
};
|
||||
addRule(namesForStandardClasses);
|
||||
addRule(constructorHasTheSameNameAsTheClass);
|
||||
addRule(constructorOrClassObjectHasTheSameNameAsTheClass);
|
||||
addRule(propertyOrPropertyAccessor);
|
||||
addRule(predefinedObjectsHasUnobfuscatableNames);
|
||||
addRule(overridingDescriptorsReferToOriginalName);
|
||||
@@ -469,15 +470,14 @@ public final class StaticContext {
|
||||
return element.getContainingFile().getUserData(LibrarySourcesConfig.EXTERNAL_MODULE_NAME);
|
||||
}
|
||||
};
|
||||
Rule<JsNameRef> constructorHaveTheSameQualifierAsTheClass = new Rule<JsNameRef>() {
|
||||
Rule<JsNameRef> constructorOrClassObjectHasTheSameQualifierAsTheClass = new Rule<JsNameRef>() {
|
||||
@Override
|
||||
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (!(descriptor instanceof ConstructorDescriptor)) {
|
||||
return null;
|
||||
if (descriptor instanceof ConstructorDescriptor || DescriptorUtils.isClassObject(descriptor)) {
|
||||
//noinspection ConstantConditions
|
||||
return getQualifierForDescriptor(descriptor.getContainingDeclaration());
|
||||
}
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
assert containingClass != null : "Can't have constructor without a class";
|
||||
return getQualifierForDescriptor(containingClass);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Rule<JsNameRef> libraryObjectsHaveKotlinQualifier = new Rule<JsNameRef>() {
|
||||
@@ -504,7 +504,7 @@ public final class StaticContext {
|
||||
};
|
||||
|
||||
addRule(libraryObjectsHaveKotlinQualifier);
|
||||
addRule(constructorHaveTheSameQualifierAsTheClass);
|
||||
addRule(constructorOrClassObjectHasTheSameQualifierAsTheClass);
|
||||
addRule(standardObjectsHaveKotlinQualifier);
|
||||
addRule(packageLevelDeclarationsHaveEnclosingPackagesNamesAsQualifier);
|
||||
addRule(nativeObjectsHaveNativePartOfFullQualifier);
|
||||
|
||||
Reference in New Issue
Block a user