Introduced QualifierReceiver instead of PackageType
This commit is contained in:
@@ -229,6 +229,13 @@ public fun JetSimpleNameExpression.getQualifiedElement(): JetElement {
|
||||
}
|
||||
}
|
||||
|
||||
public fun JetSimpleNameExpression.getTopmostParentQualifiedExpressionForSelector(): JetQualifiedExpression? {
|
||||
return stream<JetExpression>(this) {
|
||||
val parentQualified = it.getParent() as? JetQualifiedExpression
|
||||
if (parentQualified?.getSelectorExpression() == it) parentQualified else null
|
||||
}.last() as? JetQualifiedExpression
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns rightmost selector of the qualified element (null if there is no such selector)
|
||||
*/
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.QualifierReceiver;
|
||||
import org.jetbrains.jet.lang.types.DeferredType;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.expressions.CaptureKind;
|
||||
@@ -84,6 +85,8 @@ public interface BindingContext {
|
||||
WritableSlice<JetExpression, DataFlowInfo> EXPRESSION_DATA_FLOW_INFO = new BasicWritableSlice<JetExpression, DataFlowInfo>(DO_NOTHING);
|
||||
WritableSlice<JetExpression, DataFlowInfo> DATAFLOW_INFO_AFTER_CONDITION = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<JetExpression, QualifierReceiver> QUALIFIER_RECEIVER = new BasicWritableSlice<JetExpression, QualifierReceiver>(DO_NOTHING);
|
||||
|
||||
WritableSlice<JetReferenceExpression, DeclarationDescriptor> REFERENCE_TARGET =
|
||||
new BasicWritableSlice<JetReferenceExpression, DeclarationDescriptor>(DO_NOTHING);
|
||||
|
||||
|
||||
@@ -20,19 +20,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.SubpackagesScope;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.SpecialNames;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.types.PackageType;
|
||||
|
||||
public class JetModuleUtil {
|
||||
public static PackageType getRootPackageType(JetElement expression) {
|
||||
// TODO: this is a stub: at least the modules' root packages must be indexed here
|
||||
return new PackageType(SpecialNames.ROOT_PACKAGE, JetScope.EMPTY, ReceiverValue.NO_RECEIVER);
|
||||
}
|
||||
|
||||
public static JetScope getSubpackagesOfRootScope(@NotNull ModuleDescriptor module) {
|
||||
return getRootPackageScope(module, /* scopeIncludingMembers = */ false);
|
||||
}
|
||||
|
||||
+51
-199
@@ -24,8 +24,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.psi.codeFragmentUtil.CodeFragmentUtilPackage;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
|
||||
@@ -37,32 +39,27 @@ import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.jet.lang.resolve.calls.util.FakeCallableDescriptorForObject;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.constants.IntegerValueConstant;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.QualifierReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiversPackage;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeInfo;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lang.types.expressions.BasicExpressionTypingVisitor;
|
||||
import org.jetbrains.jet.lang.types.expressions.DataFlowUtils;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingContext;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.utils.Printer;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.psi.JetPsiUtil.isLHSOfDot;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getStaticNestedClassesScope;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.context.ContextDependency.INDEPENDENT;
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiversPackage.*;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||
|
||||
public class CallExpressionResolver {
|
||||
@@ -74,156 +71,6 @@ public class CallExpressionResolver {
|
||||
this.expressionTypingServices = expressionTypingServices;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType lookupPackageOrClassObject(@NotNull JetSimpleNameExpression expression, @NotNull ExpressionTypingContext context) {
|
||||
Name referencedName = expression.getReferencedNameAsName();
|
||||
final ClassifierDescriptor classifier = context.scope.getClassifier(referencedName);
|
||||
if (classifier != null) {
|
||||
JetType classObjectType = classifier.getClassObjectType();
|
||||
if (classObjectType != null) {
|
||||
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
||||
JetType result = getExtendedClassObjectType(expression, classObjectType, classifier, context.scope);
|
||||
checkClassObjectVisibility(classifier, expression, context);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
JetType[] result = new JetType[1];
|
||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(
|
||||
context.trace, "trace for package/class object lookup of name", referencedName);
|
||||
if (furtherNameLookup(expression, result, context.replaceBindingTrace(temporaryTrace))) {
|
||||
temporaryTrace.commit();
|
||||
return DataFlowUtils.checkType(result[0], expression, context);
|
||||
}
|
||||
// To report NO_CLASS_OBJECT when no package found
|
||||
if (classifier != null) {
|
||||
if (classifier instanceof TypeParameterDescriptor) {
|
||||
if (isLHSOfDot(expression)) {
|
||||
context.trace.report(TYPE_PARAMETER_ON_LHS_OF_DOT.on(expression, (TypeParameterDescriptor) classifier));
|
||||
}
|
||||
else {
|
||||
context.trace.report(TYPE_PARAMETER_IS_NOT_AN_EXPRESSION.on(expression, (TypeParameterDescriptor) classifier));
|
||||
}
|
||||
}
|
||||
else if (!isLHSOfDot(expression)) {
|
||||
context.trace.report(NO_CLASS_OBJECT.on(expression, classifier));
|
||||
}
|
||||
context.trace.record(REFERENCE_TARGET, expression, classifier);
|
||||
JetScope scopeForStaticMembersResolution =
|
||||
classifier instanceof ClassDescriptor
|
||||
? getStaticNestedClassesScope((ClassDescriptor) classifier)
|
||||
: new JetScopeImpl() {
|
||||
@NotNull
|
||||
@Override
|
||||
public DeclarationDescriptor getContainingDeclaration() {
|
||||
return classifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Scope for the type parameter on the left hand side of dot";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printScopeStructure(@NotNull Printer p) {
|
||||
p.println(toString(), " for ", classifier);
|
||||
}
|
||||
};
|
||||
return new PackageType(referencedName, scopeForStaticMembersResolution, NO_RECEIVER);
|
||||
}
|
||||
temporaryTrace.commit();
|
||||
return result[0];
|
||||
}
|
||||
|
||||
private static void checkClassObjectVisibility(
|
||||
@NotNull ClassifierDescriptor classifier,
|
||||
@NotNull JetSimpleNameExpression expression,
|
||||
@NotNull ExpressionTypingContext context
|
||||
) {
|
||||
if (!(classifier instanceof ClassDescriptor)) return;
|
||||
|
||||
ClassDescriptor classObject = ((ClassDescriptor) classifier).getClassObjectDescriptor();
|
||||
assert classObject != null : "This check should be done only for classes with class objects: " + classifier;
|
||||
DeclarationDescriptor from = context.scope.getContainingDeclaration();
|
||||
if (!Visibilities.isVisible(classObject, from)) {
|
||||
context.trace.report(INVISIBLE_MEMBER.on(expression, classObject, classObject.getVisibility(), from));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JetType getExtendedClassObjectType(
|
||||
@NotNull JetSimpleNameExpression expression,
|
||||
@NotNull JetType classObjectType,
|
||||
@NotNull ClassifierDescriptor classifier,
|
||||
@NotNull JetScope receiverScope
|
||||
) {
|
||||
if (!isLHSOfDot(expression) || !(classifier instanceof ClassDescriptor)) {
|
||||
return classObjectType;
|
||||
}
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) classifier;
|
||||
|
||||
if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
return classObjectType;
|
||||
}
|
||||
|
||||
List<JetScope> scopes = new ArrayList<JetScope>(3);
|
||||
|
||||
scopes.add(classObjectType.getMemberScope());
|
||||
scopes.add(getStaticNestedClassesScope(classDescriptor));
|
||||
|
||||
Name referencedName = expression.getReferencedNameAsName();
|
||||
PackageViewDescriptor packageView = receiverScope.getPackage(referencedName);
|
||||
if (packageView != null) {
|
||||
//for enums loaded from java binaries
|
||||
scopes.add(packageView.getMemberScope());
|
||||
}
|
||||
|
||||
JetScope scope = new ChainedScope(
|
||||
classifier, "Member scope for extended class object type " + classifier, scopes.toArray(new JetScope[scopes.size()])
|
||||
);
|
||||
return new PackageType(referencedName, scope, new ExpressionReceiver(expression, classObjectType));
|
||||
}
|
||||
|
||||
private boolean furtherNameLookup(
|
||||
@NotNull JetSimpleNameExpression expression,
|
||||
@NotNull JetType[] result,
|
||||
@NotNull ResolutionContext context
|
||||
) {
|
||||
PackageType packageType = lookupPackageType(expression, context);
|
||||
if (packageType == null) {
|
||||
return false;
|
||||
}
|
||||
if (isLHSOfDot(expression)) {
|
||||
result[0] = packageType;
|
||||
return true;
|
||||
}
|
||||
context.trace.report(EXPRESSION_EXPECTED_PACKAGE_FOUND.on(expression));
|
||||
result[0] = ErrorUtils.createErrorType("Type for " + expression.getReferencedNameAsName());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PackageType lookupPackageType(@NotNull JetSimpleNameExpression expression, @NotNull ResolutionContext context) {
|
||||
Name name = expression.getReferencedNameAsName();
|
||||
PackageViewDescriptor packageView = context.scope.getPackage(name);
|
||||
if (packageView == null) {
|
||||
return null;
|
||||
}
|
||||
context.trace.record(REFERENCE_TARGET, expression, packageView);
|
||||
|
||||
// Construct a PackageType with everything from the package and with nested classes of the corresponding class (if any)
|
||||
JetScope scope;
|
||||
ClassifierDescriptor classifier = context.scope.getClassifier(name);
|
||||
if (classifier instanceof ClassDescriptor) {
|
||||
scope = new ChainedScope(
|
||||
packageView, "Package type member scope for " + expression.getText(), packageView.getMemberScope(), getStaticNestedClassesScope((ClassDescriptor) classifier)
|
||||
);
|
||||
}
|
||||
else {
|
||||
scope = packageView.getMemberScope();
|
||||
}
|
||||
return new PackageType(name, scope, NO_RECEIVER);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ResolvedCall<FunctionDescriptor> getResolvedCallForFunction(
|
||||
@NotNull Call call, @NotNull JetExpression callExpression,
|
||||
@@ -254,36 +101,27 @@ public class CallExpressionResolver {
|
||||
context.replaceTraceAndCache(temporaryForVariable),
|
||||
call, CheckValueArgumentsMode.ENABLED);
|
||||
OverloadResolutionResults<VariableDescriptor> resolutionResult = callResolver.resolveSimpleProperty(contextForVariable);
|
||||
JetScope receiverScope = receiver.exists() ? receiver.getType().getMemberScope() : context.scope;
|
||||
if (resolutionResult.isSuccess()) {
|
||||
result[0] = true;
|
||||
if (resolutionResult.getResultingDescriptor() instanceof FakeCallableDescriptorForObject) {
|
||||
FakeCallableDescriptorForObject fakeCallableDescriptorForObject =
|
||||
(FakeCallableDescriptorForObject) resolutionResult.getResultingDescriptor();
|
||||
ClassDescriptor classDescriptor = fakeCallableDescriptorForObject.getClassDescriptor();
|
||||
context.trace.record(REFERENCE_TARGET, nameExpression, classDescriptor);
|
||||
checkClassObjectVisibility(classDescriptor, nameExpression, context);
|
||||
return getExtendedClassObjectType(nameExpression, fakeCallableDescriptorForObject.getType(), classDescriptor, receiverScope);
|
||||
|
||||
// if the expression is a receiver in a qualified expression, it should be resolved after the selector is resolved
|
||||
boolean isLHSOfDot = JetPsiUtil.isLHSOfDot(nameExpression);
|
||||
if (!resolutionResult.isNothing()) {
|
||||
boolean isQualifier = isLHSOfDot && resolutionResult.isSingleResult()
|
||||
&& resolutionResult.getResultingDescriptor() instanceof FakeCallableDescriptorForObject;
|
||||
if (!isQualifier) {
|
||||
result[0] = true;
|
||||
temporaryForVariable.commit();
|
||||
checkSuper(receiver, resolutionResult, context.trace, nameExpression);
|
||||
return resolutionResult.isSingleResult() ? resolutionResult.getResultingDescriptor().getReturnType() : null;
|
||||
}
|
||||
temporaryForVariable.commit();
|
||||
checkSuper(receiver, resolutionResult, context.trace, nameExpression);
|
||||
return resolutionResult.getResultingDescriptor().getReturnType();
|
||||
}
|
||||
|
||||
ExpressionTypingContext newContext = context.replaceScope(receiverScope);
|
||||
TemporaryTraceAndCache temporaryForPackageOrClassObject = TemporaryTraceAndCache.create(
|
||||
context, "trace to resolve as package or class object", nameExpression);
|
||||
JetType jetType = lookupPackageOrClassObject(nameExpression, newContext.replaceTraceAndCache(temporaryForPackageOrClassObject));
|
||||
if (jetType != null) {
|
||||
temporaryForPackageOrClassObject.commit();
|
||||
|
||||
// Uncommitted changes in temp context
|
||||
context.trace.record(RESOLUTION_SCOPE, nameExpression, context.scope);
|
||||
if (context.dataFlowInfo.hasTypeInfoConstraints()) {
|
||||
context.trace.record(NON_DEFAULT_EXPRESSION_DATA_FLOW, nameExpression, context.dataFlowInfo);
|
||||
}
|
||||
QualifierReceiver qualifierReceiver = createQualifierReceiver(nameExpression, receiver, context);
|
||||
if (qualifierReceiver != null) {
|
||||
result[0] = true;
|
||||
return jetType;
|
||||
if (!isLHSOfDot) {
|
||||
resolveAsStandaloneExpression(qualifierReceiver, context);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
temporaryForVariable.commit();
|
||||
result[0] = !resolutionResult.isNothing();
|
||||
@@ -301,9 +139,6 @@ public class CallExpressionResolver {
|
||||
JetType type = getVariableType(nameExpression, receiver, callOperationNode, context.replaceTraceAndCache(temporaryForVariable), result);
|
||||
if (result[0]) {
|
||||
temporaryForVariable.commit();
|
||||
if (type instanceof PackageType && !isLHSOfDot(nameExpression)) {
|
||||
type = null;
|
||||
}
|
||||
return JetTypeInfo.create(type, context.dataFlowInfo);
|
||||
}
|
||||
|
||||
@@ -425,7 +260,7 @@ public class CallExpressionResolver {
|
||||
private JetTypeInfo getSelectorReturnTypeInfo(
|
||||
@NotNull ReceiverValue receiver,
|
||||
@Nullable ASTNode callOperationNode,
|
||||
@NotNull JetExpression selectorExpression,
|
||||
@Nullable JetExpression selectorExpression,
|
||||
@NotNull ExpressionTypingContext context
|
||||
) {
|
||||
if (selectorExpression instanceof JetCallExpression) {
|
||||
@@ -435,7 +270,7 @@ public class CallExpressionResolver {
|
||||
else if (selectorExpression instanceof JetSimpleNameExpression) {
|
||||
return getSimpleNameExpressionTypeInfo((JetSimpleNameExpression) selectorExpression, receiver, callOperationNode, context);
|
||||
}
|
||||
else {
|
||||
else if (selectorExpression != null) {
|
||||
context.trace.report(ILLEGAL_SELECTOR.on(selectorExpression, selectorExpression.getText()));
|
||||
}
|
||||
return JetTypeInfo.create(null, context.dataFlowInfo);
|
||||
@@ -451,18 +286,21 @@ public class CallExpressionResolver {
|
||||
ResolutionContext contextForReceiver = context.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
|
||||
JetTypeInfo receiverTypeInfo = expressionTypingServices.getTypeInfo(receiverExpression, contextForReceiver);
|
||||
JetType receiverType = receiverTypeInfo.getType();
|
||||
if (selectorExpression == null) return JetTypeInfo.create(null, context.dataFlowInfo);
|
||||
QualifierReceiver qualifierReceiver = context.trace.get(BindingContext.QUALIFIER_RECEIVER, receiverExpression);
|
||||
|
||||
if (receiverType == null) receiverType = ErrorUtils.createErrorType("Type for " + expression.getText());
|
||||
|
||||
context = context.replaceDataFlowInfo(receiverTypeInfo.getDataFlowInfo());
|
||||
|
||||
ReceiverValue receiver = qualifierReceiver == null ? new ExpressionReceiver(receiverExpression, receiverType) : qualifierReceiver;
|
||||
JetTypeInfo selectorReturnTypeInfo = getSelectorReturnTypeInfo(
|
||||
new ExpressionReceiver(receiverExpression, receiverType),
|
||||
expression.getOperationTokenNode(), selectorExpression, context);
|
||||
receiver, expression.getOperationTokenNode(), selectorExpression, context);
|
||||
JetType selectorReturnType = selectorReturnTypeInfo.getType();
|
||||
|
||||
resolveDeferredReceiverInQualifiedExpression(qualifierReceiver, expression, context);
|
||||
|
||||
//TODO move further
|
||||
if (!(receiverType instanceof PackageType) && expression.getOperationSign() == JetTokens.SAFE_ACCESS) {
|
||||
if (expression.getOperationSign() == JetTokens.SAFE_ACCESS) {
|
||||
if (selectorReturnType != null && !KotlinBuiltIns.getInstance().isUnit(selectorReturnType)) {
|
||||
if (receiverType.isNullable()) {
|
||||
selectorReturnType = TypeUtils.makeNullable(selectorReturnType);
|
||||
@@ -486,4 +324,18 @@ public class CallExpressionResolver {
|
||||
}
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
private static void resolveDeferredReceiverInQualifiedExpression(
|
||||
@Nullable QualifierReceiver qualifierReceiver,
|
||||
@NotNull JetQualifiedExpression qualifiedExpression,
|
||||
@NotNull ExpressionTypingContext context
|
||||
) {
|
||||
if (qualifierReceiver == null) return;
|
||||
JetExpression calleeExpression =
|
||||
JetPsiUtil.deparenthesize(CallUtilPackage.getCalleeExpressionIfAny(qualifiedExpression.getSelectorExpression()), false);
|
||||
DeclarationDescriptor selectorDescriptor =
|
||||
calleeExpression instanceof JetReferenceExpression
|
||||
? context.trace.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression) calleeExpression) : null;
|
||||
ReceiversPackage.resolveAsReceiverInQualifiedExpression(qualifierReceiver, context, selectorDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -154,7 +154,7 @@ public class DataFlowValueFactory {
|
||||
return getIdForThisReceiver(declarationDescriptor);
|
||||
}
|
||||
else if (expression instanceof JetRootPackageExpression) {
|
||||
return createPackageInfo(JetModuleUtil.getRootPackageType(expression));
|
||||
//todo return createPackageInfo());
|
||||
}
|
||||
return NO_IDENTIFIER_INFO;
|
||||
}
|
||||
|
||||
+17
-18
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.calls.tasks;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -32,14 +31,13 @@ import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.QualifierReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.PackageType;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -84,25 +82,22 @@ public class TaskPrioritizer {
|
||||
@NotNull TracingStrategy tracing,
|
||||
@NotNull CallableDescriptorCollectors<D> callableDescriptorCollectors
|
||||
) {
|
||||
List<Pair<JetScope, ReceiverValue>> variants = new ArrayList<Pair<JetScope, ReceiverValue>>(2);
|
||||
|
||||
ReceiverValue explicitReceiver = context.call.getExplicitReceiver();
|
||||
if (explicitReceiver.exists() && explicitReceiver.getType() instanceof PackageType) {
|
||||
JetType receiverType = explicitReceiver.getType();
|
||||
variants.add(Pair.create(receiverType.getMemberScope(), NO_RECEIVER));
|
||||
ReceiverValue value = ((PackageType) receiverType).getReceiverValue();
|
||||
if (value.exists()) {
|
||||
variants.add(Pair.create(context.scope, value));
|
||||
ResolutionTaskHolder<D, F> result =
|
||||
new ResolutionTaskHolder<D, F>(context, new MyPriorityProvider<D>(context), tracing);
|
||||
TaskPrioritizerContext<D, F> taskPrioritizerContext =
|
||||
new TaskPrioritizerContext<D, F>(name, result, context, context.scope, callableDescriptorCollectors);
|
||||
|
||||
if (explicitReceiver instanceof QualifierReceiver) {
|
||||
QualifierReceiver qualifierReceiver = (QualifierReceiver) explicitReceiver;
|
||||
doComputeTasks(NO_RECEIVER, taskPrioritizerContext.replaceScope(qualifierReceiver.getNestedClassesAndPackageMembersScope()));
|
||||
ReceiverValue classObjectReceiver = qualifierReceiver.getClassObjectReceiver();
|
||||
if (classObjectReceiver.exists()) {
|
||||
doComputeTasks(classObjectReceiver, taskPrioritizerContext);
|
||||
}
|
||||
}
|
||||
else {
|
||||
variants.add(Pair.create(context.scope, explicitReceiver));
|
||||
}
|
||||
|
||||
ResolutionTaskHolder<D, F> result =
|
||||
new ResolutionTaskHolder<D, F>(context, new MyPriorityProvider<D>(context), tracing);
|
||||
for (Pair<JetScope, ReceiverValue> pair : variants) {
|
||||
doComputeTasks(pair.second, new TaskPrioritizerContext<D, F>(name, result, context, pair.first, callableDescriptorCollectors));
|
||||
doComputeTasks(explicitReceiver, taskPrioritizerContext);
|
||||
}
|
||||
|
||||
return result.getTasks();
|
||||
@@ -401,5 +396,9 @@ public class TaskPrioritizer {
|
||||
this.scope = scope;
|
||||
this.callableDescriptorCollectors = callableDescriptorCollectors;
|
||||
}
|
||||
|
||||
private TaskPrioritizerContext<D, F> replaceScope(JetScope newScope) {
|
||||
return new TaskPrioritizerContext<D, F>(name, result, context, newScope, callableDescriptorCollectors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,12 +114,12 @@ public fun Call.getValueArgumentForExpression(expression: JetExpression): ValueA
|
||||
|
||||
// Get call / resolved call from binding context
|
||||
|
||||
public fun JetElement.getCalleeExpressionIfAny(): JetExpression? {
|
||||
public fun JetElement?.getCalleeExpressionIfAny(): JetExpression? {
|
||||
val element = if (this is JetExpression) JetPsiUtil.safeDeparenthesize(this, false) else this
|
||||
return when (element) {
|
||||
is JetSimpleNameExpression -> element
|
||||
is JetCallElement -> element.getCalleeExpression()
|
||||
is JetQualifiedExpression -> element.getSelectorExpression()?.getCalleeExpressionIfAny()
|
||||
is JetQualifiedExpression -> element.getSelectorExpression().getCalleeExpressionIfAny()
|
||||
is JetOperationExpression -> element.getOperationReference()
|
||||
else -> null
|
||||
}
|
||||
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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.scopes.receivers
|
||||
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqName
|
||||
import org.jetbrains.jet.lang.resolve.name.Name
|
||||
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.utils.addIfNotNull
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext.*
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors.*
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
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
|
||||
|
||||
public class QualifierReceiver(
|
||||
val expression: JetSimpleNameExpression,
|
||||
val packageView: PackageViewDescriptor?,
|
||||
val classifier: ClassifierDescriptor?
|
||||
) : ReceiverValue {
|
||||
|
||||
val name: Name
|
||||
get() = classifier?.getName() ?: packageView!!.getName()
|
||||
|
||||
fun getClassObjectReceiver(): ReceiverValue =
|
||||
classifier?.getClassObjectType()?.let { ExpressionReceiver(expression, it) } ?: ReceiverValue.NO_RECEIVER
|
||||
|
||||
val descriptor: DeclarationDescriptor
|
||||
get() = classifier ?: packageView ?: throw AssertionError("PackageView and classifier both are null")
|
||||
|
||||
fun getScope(): JetScope {
|
||||
val scopes = listOf(classifier?.getClassObjectType()?.getMemberScope(), getNestedClassesAndPackageMembersScope()).filterNotNull().copyToArray()
|
||||
return ChainedScope(descriptor, "Member scope for " + name + " as package or class or object", *scopes as Array<JetScope?>)
|
||||
}
|
||||
|
||||
fun getNestedClassesAndPackageMembersScope(): JetScope {
|
||||
val scopes = ArrayList<JetScope>(3)
|
||||
|
||||
scopes.addIfNotNull(classifier?.getClassObjectType()?.getMemberScope())
|
||||
|
||||
scopes.addIfNotNull(packageView?.getMemberScope())
|
||||
|
||||
if (classifier is ClassDescriptor && classifier.getKind() != ClassKind.ENUM_ENTRY) {
|
||||
scopes.add(DescriptorUtils.getStaticNestedClassesScope(classifier))
|
||||
}
|
||||
|
||||
return ChainedScope(descriptor, "Static scope for " + name + " as package or class or object", *scopes.copyToArray())
|
||||
}
|
||||
|
||||
override fun getType(): JetType = throw IllegalStateException("No type corresponds to QualifierReceiver '$this'")
|
||||
|
||||
override fun exists() = true
|
||||
|
||||
override fun toString() = "Package{$packageView} OR Class{$classifier}"
|
||||
}
|
||||
|
||||
fun createQualifierReceiver(
|
||||
expression: JetSimpleNameExpression,
|
||||
receiver: ReceiverValue,
|
||||
context: ExpressionTypingContext
|
||||
): QualifierReceiver? {
|
||||
val receiverScope = when {
|
||||
!receiver.exists() -> context.scope
|
||||
receiver is QualifierReceiver -> receiver.getScope()
|
||||
else -> receiver.getType().getMemberScope()
|
||||
}
|
||||
|
||||
val name = expression.getReferencedNameAsName()
|
||||
val packageViewDescriptor = receiverScope.getPackage(name)
|
||||
val classifierDescriptor = receiverScope.getClassifier(name)
|
||||
|
||||
if (packageViewDescriptor == null && classifierDescriptor == null) return null
|
||||
|
||||
context.trace.record(RESOLUTION_SCOPE, expression, context.scope)
|
||||
if (context.dataFlowInfo.hasTypeInfoConstraints()) {
|
||||
context.trace.record(NON_DEFAULT_EXPRESSION_DATA_FLOW, expression, context.dataFlowInfo)
|
||||
}
|
||||
|
||||
val qualifierReceiver = QualifierReceiver(expression, packageViewDescriptor, classifierDescriptor)
|
||||
context.trace.record(QUALIFIER_RECEIVER, expression.getTopmostParentQualifiedExpressionForSelector() ?: expression, qualifierReceiver)
|
||||
return qualifierReceiver
|
||||
}
|
||||
|
||||
private fun QualifierReceiver.resolveAsStandaloneExpression(context: ExpressionTypingContext): JetType? {
|
||||
context.trace.record(REFERENCE_TARGET, expression, resolveReferenceTarget(selector = null))
|
||||
if (classifier is TypeParameterDescriptor) {
|
||||
context.trace.report(TYPE_PARAMETER_IS_NOT_AN_EXPRESSION.on(expression, classifier))
|
||||
}
|
||||
else if (classifier is ClassDescriptor && classifier.getClassObjectType() == null) {
|
||||
context.trace.report(NO_CLASS_OBJECT.on(expression, classifier))
|
||||
}
|
||||
else if (packageView != null) {
|
||||
context.trace.report(EXPRESSION_EXPECTED_PACKAGE_FOUND.on(expression))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun QualifierReceiver.resolveAsReceiverInQualifiedExpression(context: ExpressionTypingContext, selector: DeclarationDescriptor?) {
|
||||
context.trace.record(REFERENCE_TARGET, expression, resolveReferenceTarget(selector))
|
||||
if (classifier is TypeParameterDescriptor) {
|
||||
context.trace.report(TYPE_PARAMETER_ON_LHS_OF_DOT.on(expression, classifier as TypeParameterDescriptor))
|
||||
}
|
||||
else if (classifier is ClassDescriptor && classifier.getClassObjectDescriptor() != null) {
|
||||
checkClassObjectVisibility(context)
|
||||
context.trace.record(EXPRESSION_TYPE, expression, classifier.getClassObjectType())
|
||||
}
|
||||
}
|
||||
|
||||
private fun QualifierReceiver.resolveReferenceTarget(selector: DeclarationDescriptor?): DeclarationDescriptor {
|
||||
if (classifier is TypeParameterDescriptor) {
|
||||
return classifier
|
||||
}
|
||||
|
||||
val containingDeclaration = when {
|
||||
selector is ConstructorDescriptor -> selector.getContainingDeclaration().getContainingDeclaration()
|
||||
else -> selector?.getContainingDeclaration()
|
||||
}
|
||||
|
||||
if (packageView != null && (containingDeclaration is PackageFragmentDescriptorImpl || containingDeclaration is PackageViewDescriptor)
|
||||
&& getFqName(packageView) == getFqName(containingDeclaration)) {
|
||||
return packageView
|
||||
}
|
||||
|
||||
return descriptor
|
||||
}
|
||||
|
||||
private fun QualifierReceiver.checkClassObjectVisibility(context: ExpressionTypingContext) {
|
||||
if (classifier !is ClassDescriptor) return
|
||||
|
||||
val scopeContainer = context.scope.getContainingDeclaration()
|
||||
val classObject = classifier.getClassObjectDescriptor()
|
||||
assert(classObject != null) { "This check should be done only for classes with class objects: " + classifier }
|
||||
if (!Visibilities.isVisible(classObject!!, scopeContainer)) {
|
||||
context.trace.report(INVISIBLE_MEMBER.on(expression, classObject, classObject.getVisibility(), scopeContainer))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -1221,10 +1221,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
@Override
|
||||
public JetTypeInfo visitRootPackageExpression(@NotNull JetRootPackageExpression expression, ExpressionTypingContext context) {
|
||||
if (JetPsiUtil.isLHSOfDot(expression)) {
|
||||
return DataFlowUtils.checkType(JetModuleUtil.getRootPackageType(expression), expression, context, context.dataFlowInfo);
|
||||
if (!JetPsiUtil.isLHSOfDot(expression)) {
|
||||
context.trace.report(PACKAGE_IS_NOT_AN_EXPRESSION.on(expression));
|
||||
}
|
||||
context.trace.report(PACKAGE_IS_NOT_AN_EXPRESSION.on(expression));
|
||||
return JetTypeInfo.create(null, context.dataFlowInfo);
|
||||
}
|
||||
|
||||
|
||||
-5
@@ -231,11 +231,6 @@ public class ExpressionTypingUtils {
|
||||
) {
|
||||
JetType type = receiverArgument.getType();
|
||||
|
||||
if (type instanceof PackageType) {
|
||||
// This fake class ruins standard algorithms
|
||||
return false;
|
||||
}
|
||||
|
||||
if (checkReceiverResolution(receiverArgument, type, callableDescriptor)) return true;
|
||||
if (type.isNullable()) {
|
||||
JetType notNullableType = TypeUtils.makeNotNullable(type);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
fun Any.foo() = 1
|
||||
|
||||
class A {
|
||||
class object
|
||||
}
|
||||
|
||||
fun box() = if (A.foo() == 1) "OK" else "fail"
|
||||
@@ -13,7 +13,7 @@ val xssss = <!EXPRESSION_EXPECTED_PACKAGE_FOUND!>foo<!>
|
||||
val f = { <!NO_CLASS_OBJECT!>System<!> }
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
<!EXPRESSION_EXPECTED_PACKAGE_FOUND, VARIABLE_EXPECTED!>java<!> = null
|
||||
<!EXPRESSION_EXPECTED_PACKAGE_FOUND!>java<!> = null
|
||||
<!NO_CLASS_OBJECT!>System<!> = null
|
||||
<!NO_CLASS_OBJECT!>System<!>!!
|
||||
java.lang.<!NO_CLASS_OBJECT!>System<!> = null
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
enum class E {
|
||||
A
|
||||
B
|
||||
C
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val e = E.<!SYNTAX!><!>
|
||||
}
|
||||
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// FILE: a.kt
|
||||
package a
|
||||
|
||||
class A
|
||||
|
||||
// FILE: b.kt
|
||||
package b
|
||||
|
||||
import a.A
|
||||
|
||||
val A.d: Int get() = 1
|
||||
|
||||
// FILE: c.kt
|
||||
package c
|
||||
|
||||
import a.A
|
||||
|
||||
val A.d: Int get() = 2
|
||||
|
||||
// FILE: d.kt
|
||||
|
||||
package d
|
||||
|
||||
import a.A
|
||||
import b.d
|
||||
import c.d
|
||||
|
||||
fun A.test() {
|
||||
<!OVERLOAD_RESOLUTION_AMBIGUITY!>d<!>
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
open class A {
|
||||
fun foo() = 42
|
||||
|
||||
object B: A()
|
||||
}
|
||||
|
||||
fun test() {
|
||||
A.B.(A::foo)()
|
||||
}
|
||||
@@ -3882,6 +3882,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest("compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/funcitonTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("incompleteEnumReference.kt")
|
||||
public void testIncompleteEnumReference() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/incompleteEnumReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("incompleteVal.kt")
|
||||
public void testIncompleteVal() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/incompleteVal.kt");
|
||||
@@ -6973,6 +6978,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/resolve"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("ambiguityOnPropertiesWithTheSamePackageName.kt")
|
||||
public void testAmbiguityOnPropertiesWithTheSamePackageName() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/resolve/ambiguityOnPropertiesWithTheSamePackageName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("incompleteConstructorInvocation.kt")
|
||||
public void testIncompleteConstructorInvocation() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/resolve/incompleteConstructorInvocation.kt");
|
||||
|
||||
@@ -129,6 +129,11 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/function/ambiguityTopLevelVsTopLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("callableRefrenceOnNestedObject.kt")
|
||||
public void testCallableRefrenceOnNestedObject() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/function/callableRefrenceOnNestedObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("constructorFromClass.kt")
|
||||
public void testConstructorFromClass() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/function/constructorFromClass.kt");
|
||||
|
||||
@@ -685,6 +685,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest("compiler/testData/codegen/box/classes/classObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("classObjectAsExtensionReceiver.kt")
|
||||
public void testClassObjectAsExtensionReceiver() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/classes/classObjectAsExtensionReceiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("classObjectAsStaticInitializer.kt")
|
||||
public void testClassObjectAsStaticInitializer() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/classes/classObjectAsStaticInitializer.kt");
|
||||
|
||||
@@ -351,7 +351,6 @@ public class ErrorUtils {
|
||||
|
||||
public static boolean containsErrorType(@Nullable JetType type) {
|
||||
if (type == null) return false;
|
||||
if (type instanceof PackageType) return false;
|
||||
if (type.isError()) return true;
|
||||
for (TypeProjection projection : type.getArguments()) {
|
||||
if (containsErrorType(projection.getType())) return true;
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* 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.types;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This is a fake type assigned to package expressions. Only member lookup is
|
||||
* supposed to be done on these types.
|
||||
*/
|
||||
public class PackageType implements JetType {
|
||||
private final Name name;
|
||||
private final JetScope memberScope;
|
||||
private final ReceiverValue receiver;
|
||||
|
||||
public PackageType(@NotNull Name name, @NotNull JetScope memberScope, @NotNull ReceiverValue receiver) {
|
||||
this.name = name;
|
||||
this.memberScope = memberScope;
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetScope getMemberScope() {
|
||||
return memberScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isError() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ReceiverValue getReceiverValue() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeConstructor getConstructor() {
|
||||
return throwException();
|
||||
}
|
||||
|
||||
private TypeConstructor throwException() {
|
||||
throw new UnsupportedOperationException("Only member lookup is allowed on a package type " + name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TypeProjection> getArguments() {
|
||||
throwException();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
throwException();
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Annotations getAnnotations() {
|
||||
throwException();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[Package-type " + name + "]";
|
||||
}
|
||||
}
|
||||
@@ -519,7 +519,6 @@ public class TypeUtils {
|
||||
) {
|
||||
if (type == null) return false;
|
||||
if (isSpecialType.invoke(type)) return true;
|
||||
if (type instanceof PackageType) return false;
|
||||
for (TypeProjection projection : type.getArguments()) {
|
||||
if (containsSpecialType(projection.getType(), isSpecialType)) return true;
|
||||
}
|
||||
|
||||
@@ -724,7 +724,6 @@ public class KotlinBuiltIns {
|
||||
}
|
||||
|
||||
public boolean isFunctionType(@NotNull JetType type) {
|
||||
if (type instanceof PackageType) return false;
|
||||
if (isExactFunctionType(type)) return true;
|
||||
|
||||
for (JetType superType : type.getConstructor().getSupertypes()) {
|
||||
@@ -735,7 +734,6 @@ public class KotlinBuiltIns {
|
||||
}
|
||||
|
||||
public boolean isExtensionFunctionType(@NotNull JetType type) {
|
||||
if (type instanceof PackageType) return false;
|
||||
if (isExactExtensionFunctionType(type)) return true;
|
||||
|
||||
for (JetType superType : type.getConstructor().getSupertypes()) {
|
||||
@@ -833,21 +831,19 @@ public class KotlinBuiltIns {
|
||||
}
|
||||
|
||||
public boolean isNothingOrNullableNothing(@NotNull JetType type) {
|
||||
return !(type instanceof PackageType)
|
||||
&& type.getConstructor() == getNothing().getTypeConstructor();
|
||||
return type.getConstructor() == getNothing().getTypeConstructor();
|
||||
}
|
||||
|
||||
public boolean isAnyOrNullableAny(@NotNull JetType type) {
|
||||
return !(type instanceof PackageType) &&
|
||||
type.getConstructor() == getAny().getTypeConstructor();
|
||||
return type.getConstructor() == getAny().getTypeConstructor();
|
||||
}
|
||||
|
||||
public boolean isUnit(@NotNull JetType type) {
|
||||
return !(type instanceof PackageType) && type.equals(getUnitType());
|
||||
return type.equals(getUnitType());
|
||||
}
|
||||
|
||||
public boolean isString(@Nullable JetType type) {
|
||||
return !(type instanceof PackageType) && getStringType().equals(type);
|
||||
return getStringType().equals(type);
|
||||
}
|
||||
|
||||
public boolean isCloneable(@NotNull ClassDescriptor descriptor) {
|
||||
|
||||
@@ -279,9 +279,6 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
if (type instanceof PackageType) {
|
||||
return type.toString();
|
||||
}
|
||||
if (type instanceof LazyType && debugMode) {
|
||||
return type.toString();
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.QualifierReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.PackageType;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
|
||||
|
||||
import java.util.*;
|
||||
@@ -58,32 +58,32 @@ public final class TipsManager {
|
||||
if (receiverExpression != null && inPositionForCompletionWithReceiver) {
|
||||
// Process as call expression
|
||||
JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
|
||||
QualifierReceiver qualifierReceiver = context.get(BindingContext.QUALIFIER_RECEIVER, receiverExpression);
|
||||
if (qualifierReceiver != null && resolutionScope != null) {
|
||||
return includeExternalCallableExtensions(
|
||||
excludePrivateDescriptors(qualifierReceiver.getScope().getAllDescriptors()),
|
||||
resolutionScope, qualifierReceiver);
|
||||
}
|
||||
|
||||
JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
||||
|
||||
if (expressionType != null && resolutionScope != null && !expressionType.isError()) {
|
||||
if (!(expressionType instanceof PackageType)) {
|
||||
ExpressionReceiver receiverValue = new ExpressionReceiver(receiverExpression, expressionType);
|
||||
Set<DeclarationDescriptor> descriptors = new HashSet<DeclarationDescriptor>();
|
||||
ExpressionReceiver receiverValue = new ExpressionReceiver(receiverExpression, expressionType);
|
||||
Set<DeclarationDescriptor> descriptors = new HashSet<DeclarationDescriptor>();
|
||||
|
||||
DataFlowInfo info = context.get(BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW, expression);
|
||||
if (info == null) {
|
||||
info = DataFlowInfo.EMPTY;
|
||||
}
|
||||
|
||||
List<JetType> variantsForExplicitReceiver = AutoCastUtils.getAutoCastVariants(receiverValue, context, info);
|
||||
|
||||
for (JetType variant : variantsForExplicitReceiver) {
|
||||
descriptors.addAll(includeExternalCallableExtensions(
|
||||
excludePrivateDescriptors(variant.getMemberScope().getAllDescriptors()),
|
||||
resolutionScope, receiverValue));
|
||||
}
|
||||
|
||||
return descriptors;
|
||||
DataFlowInfo info = context.get(BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW, expression);
|
||||
if (info == null) {
|
||||
info = DataFlowInfo.EMPTY;
|
||||
}
|
||||
|
||||
return includeExternalCallableExtensions(
|
||||
excludePrivateDescriptors(expressionType.getMemberScope().getAllDescriptors()),
|
||||
resolutionScope, new ExpressionReceiver(receiverExpression, expressionType));
|
||||
List<JetType> variantsForExplicitReceiver = AutoCastUtils.getAutoCastVariants(receiverValue, context, info);
|
||||
|
||||
for (JetType variant : variantsForExplicitReceiver) {
|
||||
descriptors.addAll(includeExternalCallableExtensions(
|
||||
excludePrivateDescriptors(variant.getMemberScope().getAllDescriptors()),
|
||||
resolutionScope, receiverValue));
|
||||
}
|
||||
|
||||
return descriptors;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -197,11 +197,9 @@ public final class TipsManager {
|
||||
@NotNull final ReceiverValue receiverValue
|
||||
) {
|
||||
// It's impossible to add extension function for package
|
||||
JetType receiverType = receiverValue.getType();
|
||||
if (receiverType instanceof PackageType) {
|
||||
if (receiverValue instanceof QualifierReceiver) {
|
||||
return new HashSet<DeclarationDescriptor>(descriptors);
|
||||
}
|
||||
|
||||
Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||
|
||||
descriptorsSet.addAll(
|
||||
|
||||
+4
-7
@@ -24,7 +24,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.plugin.JetBundle
|
||||
import org.jetbrains.jet.lang.psi.JetValueArgument
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||
import org.jetbrains.jet.lang.types.PackageType
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUnparsingUtils
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
||||
import com.intellij.codeInsight.hint.HintManager
|
||||
@@ -91,15 +90,13 @@ public open class ReplaceWithInfixFunctionCallIntention : JetSelfTargetingIntent
|
||||
val functionLiteralArguments = element.getFunctionLiteralArguments()
|
||||
val bindingContext = AnalyzerFacadeWithCache.getContextForElement(parent)
|
||||
val receiverType = bindingContext[BindingContext.EXPRESSION_TYPE, receiver]
|
||||
when {
|
||||
receiverType == null -> {
|
||||
intentionFailed(editor, "resolution.failed")
|
||||
return
|
||||
}
|
||||
receiverType is PackageType -> {
|
||||
if (receiverType == null) {
|
||||
if (bindingContext[BindingContext.QUALIFIER_RECEIVER, receiver] != null) {
|
||||
intentionFailed(editor, "package.call")
|
||||
return
|
||||
}
|
||||
intentionFailed(editor, "resolution.failed")
|
||||
return
|
||||
}
|
||||
|
||||
rightHandTextStringBuilder.append(
|
||||
|
||||
@@ -48,8 +48,6 @@ import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.jetAsJava.KotlinLightMethod;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.PackageType;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -432,9 +430,7 @@ public class JetRefactoringUtil {
|
||||
JetExpression expression = (JetExpression)element;
|
||||
BindingContext bindingContext = AnalyzerFacadeWithCache.getContextForElement(expression);
|
||||
JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
if (expressionType == null || !(expressionType instanceof PackageType) &&
|
||||
!JetTypeChecker.DEFAULT.equalTypes(KotlinBuiltIns.
|
||||
getInstance().getUnitType(), expressionType)) {
|
||||
if (expressionType == null || !KotlinBuiltIns.getInstance().isUnit(expressionType)) {
|
||||
expressions.add(expression);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -44,7 +44,6 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.PackageType;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
@@ -139,7 +138,8 @@ public class KotlinIntroduceVariableHandler extends KotlinIntroduceHandlerBase {
|
||||
noTypeInference = true;
|
||||
}
|
||||
}
|
||||
if (expressionType instanceof PackageType) {
|
||||
|
||||
if (expressionType == null && bindingContext.get(BindingContext.QUALIFIER_RECEIVER, expression) != null) {
|
||||
showErrorHint(project, editor, JetRefactoringBundle.message("cannot.refactor.package.expression"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package a
|
||||
|
||||
class Test {
|
||||
class object {
|
||||
class Some
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
a.Test.S<caret>
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package a
|
||||
|
||||
class Test {
|
||||
class object {
|
||||
class Some
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
a.Test.Some<caret>
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
trait A
|
||||
|
||||
fun A.foo(i: Int) = i
|
||||
|
||||
class B {
|
||||
class object : A
|
||||
}
|
||||
|
||||
fun test() {
|
||||
B.foo(<caret>)
|
||||
}
|
||||
|
||||
/*
|
||||
Text: (<highlight>i: Int</highlight>), Disabled: false, Strikeout: false, Green: true
|
||||
*/
|
||||
@@ -137,6 +137,7 @@ public class BasicCompletionHandlerTest : CompletionHandlerTestBase(){
|
||||
fun testEnumMember() = doTest(1, "A", null, '\n')
|
||||
fun testEnumMember1() = doTest(1, "A", null, '\n')
|
||||
fun testClassFromClassObject() = doTest(1, "Some", null, '\n')
|
||||
fun testClassFromClassObjectInPackage() = doTest(1, "Some", null, '\n')
|
||||
|
||||
fun testParameterType() = doTest(1, "StringBuilder", " (java.lang)", '\n')
|
||||
|
||||
|
||||
+5
@@ -38,6 +38,11 @@ public class FunctionParameterInfoTestGenerated extends AbstractFunctionParamete
|
||||
doTest("idea/testData/parameterInfo/functionParameterInfo/Deprecated.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ExtensionOnClassObject.kt")
|
||||
public void testExtensionOnClassObject() throws Exception {
|
||||
doTest("idea/testData/parameterInfo/functionParameterInfo/ExtensionOnClassObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("InheritedFunctions.kt")
|
||||
public void testInheritedFunctions() throws Exception {
|
||||
doTest("idea/testData/parameterInfo/functionParameterInfo/InheritedFunctions.kt");
|
||||
|
||||
Reference in New Issue
Block a user