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)
|
* 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.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
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.DeferredType;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.expressions.CaptureKind;
|
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> EXPRESSION_DATA_FLOW_INFO = new BasicWritableSlice<JetExpression, DataFlowInfo>(DO_NOTHING);
|
||||||
WritableSlice<JetExpression, DataFlowInfo> DATAFLOW_INFO_AFTER_CONDITION = Slices.createSimpleSlice();
|
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 =
|
WritableSlice<JetReferenceExpression, DeclarationDescriptor> REFERENCE_TARGET =
|
||||||
new BasicWritableSlice<JetReferenceExpression, DeclarationDescriptor>(DO_NOTHING);
|
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.ModuleDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.SubpackagesScope;
|
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.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.SpecialNames;
|
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
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 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) {
|
public static JetScope getSubpackagesOfRootScope(@NotNull ModuleDescriptor module) {
|
||||||
return getRootPackageScope(module, /* scopeIncludingMembers = */ false);
|
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.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
|
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.psi.codeFragmentUtil.CodeFragmentUtilPackage;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.*;
|
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.BasicCallResolutionContext;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode;
|
import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
|
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.calls.util.FakeCallableDescriptorForObject;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.IntegerValueConstant;
|
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.ExpressionReceiver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.QualifierReceiver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
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.BasicExpressionTypingVisitor;
|
||||||
import org.jetbrains.jet.lang.types.expressions.DataFlowUtils;
|
import org.jetbrains.jet.lang.types.expressions.DataFlowUtils;
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingContext;
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingContext;
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.jetbrains.jet.utils.Printer;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
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.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;
|
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||||
|
|
||||||
public class CallExpressionResolver {
|
public class CallExpressionResolver {
|
||||||
@@ -74,156 +71,6 @@ public class CallExpressionResolver {
|
|||||||
this.expressionTypingServices = expressionTypingServices;
|
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
|
@Nullable
|
||||||
public ResolvedCall<FunctionDescriptor> getResolvedCallForFunction(
|
public ResolvedCall<FunctionDescriptor> getResolvedCallForFunction(
|
||||||
@NotNull Call call, @NotNull JetExpression callExpression,
|
@NotNull Call call, @NotNull JetExpression callExpression,
|
||||||
@@ -254,36 +101,27 @@ public class CallExpressionResolver {
|
|||||||
context.replaceTraceAndCache(temporaryForVariable),
|
context.replaceTraceAndCache(temporaryForVariable),
|
||||||
call, CheckValueArgumentsMode.ENABLED);
|
call, CheckValueArgumentsMode.ENABLED);
|
||||||
OverloadResolutionResults<VariableDescriptor> resolutionResult = callResolver.resolveSimpleProperty(contextForVariable);
|
OverloadResolutionResults<VariableDescriptor> resolutionResult = callResolver.resolveSimpleProperty(contextForVariable);
|
||||||
JetScope receiverScope = receiver.exists() ? receiver.getType().getMemberScope() : context.scope;
|
|
||||||
if (resolutionResult.isSuccess()) {
|
// if the expression is a receiver in a qualified expression, it should be resolved after the selector is resolved
|
||||||
result[0] = true;
|
boolean isLHSOfDot = JetPsiUtil.isLHSOfDot(nameExpression);
|
||||||
if (resolutionResult.getResultingDescriptor() instanceof FakeCallableDescriptorForObject) {
|
if (!resolutionResult.isNothing()) {
|
||||||
FakeCallableDescriptorForObject fakeCallableDescriptorForObject =
|
boolean isQualifier = isLHSOfDot && resolutionResult.isSingleResult()
|
||||||
(FakeCallableDescriptorForObject) resolutionResult.getResultingDescriptor();
|
&& resolutionResult.getResultingDescriptor() instanceof FakeCallableDescriptorForObject;
|
||||||
ClassDescriptor classDescriptor = fakeCallableDescriptorForObject.getClassDescriptor();
|
if (!isQualifier) {
|
||||||
context.trace.record(REFERENCE_TARGET, nameExpression, classDescriptor);
|
result[0] = true;
|
||||||
checkClassObjectVisibility(classDescriptor, nameExpression, context);
|
temporaryForVariable.commit();
|
||||||
return getExtendedClassObjectType(nameExpression, fakeCallableDescriptorForObject.getType(), classDescriptor, receiverScope);
|
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);
|
QualifierReceiver qualifierReceiver = createQualifierReceiver(nameExpression, receiver, context);
|
||||||
TemporaryTraceAndCache temporaryForPackageOrClassObject = TemporaryTraceAndCache.create(
|
if (qualifierReceiver != null) {
|
||||||
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);
|
|
||||||
}
|
|
||||||
result[0] = true;
|
result[0] = true;
|
||||||
return jetType;
|
if (!isLHSOfDot) {
|
||||||
|
resolveAsStandaloneExpression(qualifierReceiver, context);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
temporaryForVariable.commit();
|
temporaryForVariable.commit();
|
||||||
result[0] = !resolutionResult.isNothing();
|
result[0] = !resolutionResult.isNothing();
|
||||||
@@ -301,9 +139,6 @@ public class CallExpressionResolver {
|
|||||||
JetType type = getVariableType(nameExpression, receiver, callOperationNode, context.replaceTraceAndCache(temporaryForVariable), result);
|
JetType type = getVariableType(nameExpression, receiver, callOperationNode, context.replaceTraceAndCache(temporaryForVariable), result);
|
||||||
if (result[0]) {
|
if (result[0]) {
|
||||||
temporaryForVariable.commit();
|
temporaryForVariable.commit();
|
||||||
if (type instanceof PackageType && !isLHSOfDot(nameExpression)) {
|
|
||||||
type = null;
|
|
||||||
}
|
|
||||||
return JetTypeInfo.create(type, context.dataFlowInfo);
|
return JetTypeInfo.create(type, context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,7 +260,7 @@ public class CallExpressionResolver {
|
|||||||
private JetTypeInfo getSelectorReturnTypeInfo(
|
private JetTypeInfo getSelectorReturnTypeInfo(
|
||||||
@NotNull ReceiverValue receiver,
|
@NotNull ReceiverValue receiver,
|
||||||
@Nullable ASTNode callOperationNode,
|
@Nullable ASTNode callOperationNode,
|
||||||
@NotNull JetExpression selectorExpression,
|
@Nullable JetExpression selectorExpression,
|
||||||
@NotNull ExpressionTypingContext context
|
@NotNull ExpressionTypingContext context
|
||||||
) {
|
) {
|
||||||
if (selectorExpression instanceof JetCallExpression) {
|
if (selectorExpression instanceof JetCallExpression) {
|
||||||
@@ -435,7 +270,7 @@ public class CallExpressionResolver {
|
|||||||
else if (selectorExpression instanceof JetSimpleNameExpression) {
|
else if (selectorExpression instanceof JetSimpleNameExpression) {
|
||||||
return getSimpleNameExpressionTypeInfo((JetSimpleNameExpression) selectorExpression, receiver, callOperationNode, context);
|
return getSimpleNameExpressionTypeInfo((JetSimpleNameExpression) selectorExpression, receiver, callOperationNode, context);
|
||||||
}
|
}
|
||||||
else {
|
else if (selectorExpression != null) {
|
||||||
context.trace.report(ILLEGAL_SELECTOR.on(selectorExpression, selectorExpression.getText()));
|
context.trace.report(ILLEGAL_SELECTOR.on(selectorExpression, selectorExpression.getText()));
|
||||||
}
|
}
|
||||||
return JetTypeInfo.create(null, context.dataFlowInfo);
|
return JetTypeInfo.create(null, context.dataFlowInfo);
|
||||||
@@ -451,18 +286,21 @@ public class CallExpressionResolver {
|
|||||||
ResolutionContext contextForReceiver = context.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
|
ResolutionContext contextForReceiver = context.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
|
||||||
JetTypeInfo receiverTypeInfo = expressionTypingServices.getTypeInfo(receiverExpression, contextForReceiver);
|
JetTypeInfo receiverTypeInfo = expressionTypingServices.getTypeInfo(receiverExpression, contextForReceiver);
|
||||||
JetType receiverType = receiverTypeInfo.getType();
|
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());
|
if (receiverType == null) receiverType = ErrorUtils.createErrorType("Type for " + expression.getText());
|
||||||
|
|
||||||
context = context.replaceDataFlowInfo(receiverTypeInfo.getDataFlowInfo());
|
context = context.replaceDataFlowInfo(receiverTypeInfo.getDataFlowInfo());
|
||||||
|
|
||||||
|
ReceiverValue receiver = qualifierReceiver == null ? new ExpressionReceiver(receiverExpression, receiverType) : qualifierReceiver;
|
||||||
JetTypeInfo selectorReturnTypeInfo = getSelectorReturnTypeInfo(
|
JetTypeInfo selectorReturnTypeInfo = getSelectorReturnTypeInfo(
|
||||||
new ExpressionReceiver(receiverExpression, receiverType),
|
receiver, expression.getOperationTokenNode(), selectorExpression, context);
|
||||||
expression.getOperationTokenNode(), selectorExpression, context);
|
|
||||||
JetType selectorReturnType = selectorReturnTypeInfo.getType();
|
JetType selectorReturnType = selectorReturnTypeInfo.getType();
|
||||||
|
|
||||||
|
resolveDeferredReceiverInQualifiedExpression(qualifierReceiver, expression, context);
|
||||||
|
|
||||||
//TODO move further
|
//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 (selectorReturnType != null && !KotlinBuiltIns.getInstance().isUnit(selectorReturnType)) {
|
||||||
if (receiverType.isNullable()) {
|
if (receiverType.isNullable()) {
|
||||||
selectorReturnType = TypeUtils.makeNullable(selectorReturnType);
|
selectorReturnType = TypeUtils.makeNullable(selectorReturnType);
|
||||||
@@ -486,4 +324,18 @@ public class CallExpressionResolver {
|
|||||||
}
|
}
|
||||||
return typeInfo;
|
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);
|
return getIdForThisReceiver(declarationDescriptor);
|
||||||
}
|
}
|
||||||
else if (expression instanceof JetRootPackageExpression) {
|
else if (expression instanceof JetRootPackageExpression) {
|
||||||
return createPackageInfo(JetModuleUtil.getRootPackageType(expression));
|
//todo return createPackageInfo());
|
||||||
}
|
}
|
||||||
return NO_IDENTIFIER_INFO;
|
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.Lists;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||||
import com.intellij.openapi.util.Pair;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
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.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
|
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.ExpressionReceiver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.QualifierReceiver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
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.checker.JetTypeChecker;
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -84,25 +82,22 @@ public class TaskPrioritizer {
|
|||||||
@NotNull TracingStrategy tracing,
|
@NotNull TracingStrategy tracing,
|
||||||
@NotNull CallableDescriptorCollectors<D> callableDescriptorCollectors
|
@NotNull CallableDescriptorCollectors<D> callableDescriptorCollectors
|
||||||
) {
|
) {
|
||||||
List<Pair<JetScope, ReceiverValue>> variants = new ArrayList<Pair<JetScope, ReceiverValue>>(2);
|
|
||||||
|
|
||||||
ReceiverValue explicitReceiver = context.call.getExplicitReceiver();
|
ReceiverValue explicitReceiver = context.call.getExplicitReceiver();
|
||||||
if (explicitReceiver.exists() && explicitReceiver.getType() instanceof PackageType) {
|
ResolutionTaskHolder<D, F> result =
|
||||||
JetType receiverType = explicitReceiver.getType();
|
new ResolutionTaskHolder<D, F>(context, new MyPriorityProvider<D>(context), tracing);
|
||||||
variants.add(Pair.create(receiverType.getMemberScope(), NO_RECEIVER));
|
TaskPrioritizerContext<D, F> taskPrioritizerContext =
|
||||||
ReceiverValue value = ((PackageType) receiverType).getReceiverValue();
|
new TaskPrioritizerContext<D, F>(name, result, context, context.scope, callableDescriptorCollectors);
|
||||||
if (value.exists()) {
|
|
||||||
variants.add(Pair.create(context.scope, value));
|
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 {
|
else {
|
||||||
variants.add(Pair.create(context.scope, explicitReceiver));
|
doComputeTasks(explicitReceiver, taskPrioritizerContext);
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.getTasks();
|
return result.getTasks();
|
||||||
@@ -401,5 +396,9 @@ public class TaskPrioritizer {
|
|||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.callableDescriptorCollectors = callableDescriptorCollectors;
|
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
|
// 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
|
val element = if (this is JetExpression) JetPsiUtil.safeDeparenthesize(this, false) else this
|
||||||
return when (element) {
|
return when (element) {
|
||||||
is JetSimpleNameExpression -> element
|
is JetSimpleNameExpression -> element
|
||||||
is JetCallElement -> element.getCalleeExpression()
|
is JetCallElement -> element.getCalleeExpression()
|
||||||
is JetQualifiedExpression -> element.getSelectorExpression()?.getCalleeExpressionIfAny()
|
is JetQualifiedExpression -> element.getSelectorExpression().getCalleeExpressionIfAny()
|
||||||
is JetOperationExpression -> element.getOperationReference()
|
is JetOperationExpression -> element.getOperationReference()
|
||||||
else -> null
|
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
|
@Override
|
||||||
public JetTypeInfo visitRootPackageExpression(@NotNull JetRootPackageExpression expression, ExpressionTypingContext context) {
|
public JetTypeInfo visitRootPackageExpression(@NotNull JetRootPackageExpression expression, ExpressionTypingContext context) {
|
||||||
if (JetPsiUtil.isLHSOfDot(expression)) {
|
if (!JetPsiUtil.isLHSOfDot(expression)) {
|
||||||
return DataFlowUtils.checkType(JetModuleUtil.getRootPackageType(expression), expression, context, context.dataFlowInfo);
|
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);
|
return JetTypeInfo.create(null, context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-5
@@ -231,11 +231,6 @@ public class ExpressionTypingUtils {
|
|||||||
) {
|
) {
|
||||||
JetType type = receiverArgument.getType();
|
JetType type = receiverArgument.getType();
|
||||||
|
|
||||||
if (type instanceof PackageType) {
|
|
||||||
// This fake class ruins standard algorithms
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkReceiverResolution(receiverArgument, type, callableDescriptor)) return true;
|
if (checkReceiverResolution(receiverArgument, type, callableDescriptor)) return true;
|
||||||
if (type.isNullable()) {
|
if (type.isNullable()) {
|
||||||
JetType notNullableType = TypeUtils.makeNotNullable(type);
|
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<!> }
|
val f = { <!NO_CLASS_OBJECT!>System<!> }
|
||||||
|
|
||||||
fun main(args : Array<String>) {
|
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<!> = null
|
||||||
<!NO_CLASS_OBJECT!>System<!>!!
|
<!NO_CLASS_OBJECT!>System<!>!!
|
||||||
java.lang.<!NO_CLASS_OBJECT!>System<!> = null
|
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");
|
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")
|
@TestMetadata("incompleteVal.kt")
|
||||||
public void testIncompleteVal() throws Exception {
|
public void testIncompleteVal() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/incompleteCode/diagnosticWithSyntaxError/incompleteVal.kt");
|
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);
|
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")
|
@TestMetadata("incompleteConstructorInvocation.kt")
|
||||||
public void testIncompleteConstructorInvocation() throws Exception {
|
public void testIncompleteConstructorInvocation() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/resolve/incompleteConstructorInvocation.kt");
|
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");
|
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")
|
@TestMetadata("constructorFromClass.kt")
|
||||||
public void testConstructorFromClass() throws Exception {
|
public void testConstructorFromClass() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/testsWithStdLib/callableReference/function/constructorFromClass.kt");
|
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");
|
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")
|
@TestMetadata("classObjectAsStaticInitializer.kt")
|
||||||
public void testClassObjectAsStaticInitializer() throws Exception {
|
public void testClassObjectAsStaticInitializer() throws Exception {
|
||||||
doTest("compiler/testData/codegen/box/classes/classObjectAsStaticInitializer.kt");
|
doTest("compiler/testData/codegen/box/classes/classObjectAsStaticInitializer.kt");
|
||||||
|
|||||||
@@ -351,7 +351,6 @@ public class ErrorUtils {
|
|||||||
|
|
||||||
public static boolean containsErrorType(@Nullable JetType type) {
|
public static boolean containsErrorType(@Nullable JetType type) {
|
||||||
if (type == null) return false;
|
if (type == null) return false;
|
||||||
if (type instanceof PackageType) return false;
|
|
||||||
if (type.isError()) return true;
|
if (type.isError()) return true;
|
||||||
for (TypeProjection projection : type.getArguments()) {
|
for (TypeProjection projection : type.getArguments()) {
|
||||||
if (containsErrorType(projection.getType())) return true;
|
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 (type == null) return false;
|
||||||
if (isSpecialType.invoke(type)) return true;
|
if (isSpecialType.invoke(type)) return true;
|
||||||
if (type instanceof PackageType) return false;
|
|
||||||
for (TypeProjection projection : type.getArguments()) {
|
for (TypeProjection projection : type.getArguments()) {
|
||||||
if (containsSpecialType(projection.getType(), isSpecialType)) return true;
|
if (containsSpecialType(projection.getType(), isSpecialType)) return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -724,7 +724,6 @@ public class KotlinBuiltIns {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFunctionType(@NotNull JetType type) {
|
public boolean isFunctionType(@NotNull JetType type) {
|
||||||
if (type instanceof PackageType) return false;
|
|
||||||
if (isExactFunctionType(type)) return true;
|
if (isExactFunctionType(type)) return true;
|
||||||
|
|
||||||
for (JetType superType : type.getConstructor().getSupertypes()) {
|
for (JetType superType : type.getConstructor().getSupertypes()) {
|
||||||
@@ -735,7 +734,6 @@ public class KotlinBuiltIns {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExtensionFunctionType(@NotNull JetType type) {
|
public boolean isExtensionFunctionType(@NotNull JetType type) {
|
||||||
if (type instanceof PackageType) return false;
|
|
||||||
if (isExactExtensionFunctionType(type)) return true;
|
if (isExactExtensionFunctionType(type)) return true;
|
||||||
|
|
||||||
for (JetType superType : type.getConstructor().getSupertypes()) {
|
for (JetType superType : type.getConstructor().getSupertypes()) {
|
||||||
@@ -833,21 +831,19 @@ public class KotlinBuiltIns {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isNothingOrNullableNothing(@NotNull JetType type) {
|
public boolean isNothingOrNullableNothing(@NotNull JetType type) {
|
||||||
return !(type instanceof PackageType)
|
return type.getConstructor() == getNothing().getTypeConstructor();
|
||||||
&& type.getConstructor() == getNothing().getTypeConstructor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAnyOrNullableAny(@NotNull JetType type) {
|
public boolean isAnyOrNullableAny(@NotNull JetType type) {
|
||||||
return !(type instanceof PackageType) &&
|
return type.getConstructor() == getAny().getTypeConstructor();
|
||||||
type.getConstructor() == getAny().getTypeConstructor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnit(@NotNull JetType type) {
|
public boolean isUnit(@NotNull JetType type) {
|
||||||
return !(type instanceof PackageType) && type.equals(getUnitType());
|
return type.equals(getUnitType());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isString(@Nullable JetType type) {
|
public boolean isString(@Nullable JetType type) {
|
||||||
return !(type instanceof PackageType) && getStringType().equals(type);
|
return getStringType().equals(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCloneable(@NotNull ClassDescriptor descriptor) {
|
public boolean isCloneable(@NotNull ClassDescriptor descriptor) {
|
||||||
|
|||||||
@@ -279,9 +279,6 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
|||||||
}
|
}
|
||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
if (type instanceof PackageType) {
|
|
||||||
return type.toString();
|
|
||||||
}
|
|
||||||
if (type instanceof LazyType && debugMode) {
|
if (type instanceof LazyType && debugMode) {
|
||||||
return type.toString();
|
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.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
|
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.ExpressionReceiver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.QualifierReceiver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.PackageType;
|
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -58,32 +58,32 @@ public final class TipsManager {
|
|||||||
if (receiverExpression != null && inPositionForCompletionWithReceiver) {
|
if (receiverExpression != null && inPositionForCompletionWithReceiver) {
|
||||||
// Process as call expression
|
// Process as call expression
|
||||||
JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, 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);
|
JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
||||||
|
|
||||||
if (expressionType != null && resolutionScope != null && !expressionType.isError()) {
|
if (expressionType != null && resolutionScope != null && !expressionType.isError()) {
|
||||||
if (!(expressionType instanceof PackageType)) {
|
ExpressionReceiver receiverValue = new ExpressionReceiver(receiverExpression, expressionType);
|
||||||
ExpressionReceiver receiverValue = new ExpressionReceiver(receiverExpression, expressionType);
|
Set<DeclarationDescriptor> descriptors = new HashSet<DeclarationDescriptor>();
|
||||||
Set<DeclarationDescriptor> descriptors = new HashSet<DeclarationDescriptor>();
|
|
||||||
|
|
||||||
DataFlowInfo info = context.get(BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW, expression);
|
DataFlowInfo info = context.get(BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW, expression);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
info = DataFlowInfo.EMPTY;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return includeExternalCallableExtensions(
|
List<JetType> variantsForExplicitReceiver = AutoCastUtils.getAutoCastVariants(receiverValue, context, info);
|
||||||
excludePrivateDescriptors(expressionType.getMemberScope().getAllDescriptors()),
|
|
||||||
resolutionScope, new ExpressionReceiver(receiverExpression, expressionType));
|
for (JetType variant : variantsForExplicitReceiver) {
|
||||||
|
descriptors.addAll(includeExternalCallableExtensions(
|
||||||
|
excludePrivateDescriptors(variant.getMemberScope().getAllDescriptors()),
|
||||||
|
resolutionScope, receiverValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
return descriptors;
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
@@ -197,11 +197,9 @@ public final class TipsManager {
|
|||||||
@NotNull final ReceiverValue receiverValue
|
@NotNull final ReceiverValue receiverValue
|
||||||
) {
|
) {
|
||||||
// It's impossible to add extension function for package
|
// It's impossible to add extension function for package
|
||||||
JetType receiverType = receiverValue.getType();
|
if (receiverValue instanceof QualifierReceiver) {
|
||||||
if (receiverType instanceof PackageType) {
|
|
||||||
return new HashSet<DeclarationDescriptor>(descriptors);
|
return new HashSet<DeclarationDescriptor>(descriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||||
|
|
||||||
descriptorsSet.addAll(
|
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.plugin.JetBundle
|
||||||
import org.jetbrains.jet.lang.psi.JetValueArgument
|
import org.jetbrains.jet.lang.psi.JetValueArgument
|
||||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
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.JetPsiUnparsingUtils
|
||||||
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
||||||
import com.intellij.codeInsight.hint.HintManager
|
import com.intellij.codeInsight.hint.HintManager
|
||||||
@@ -91,15 +90,13 @@ public open class ReplaceWithInfixFunctionCallIntention : JetSelfTargetingIntent
|
|||||||
val functionLiteralArguments = element.getFunctionLiteralArguments()
|
val functionLiteralArguments = element.getFunctionLiteralArguments()
|
||||||
val bindingContext = AnalyzerFacadeWithCache.getContextForElement(parent)
|
val bindingContext = AnalyzerFacadeWithCache.getContextForElement(parent)
|
||||||
val receiverType = bindingContext[BindingContext.EXPRESSION_TYPE, receiver]
|
val receiverType = bindingContext[BindingContext.EXPRESSION_TYPE, receiver]
|
||||||
when {
|
if (receiverType == null) {
|
||||||
receiverType == null -> {
|
if (bindingContext[BindingContext.QUALIFIER_RECEIVER, receiver] != null) {
|
||||||
intentionFailed(editor, "resolution.failed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
receiverType is PackageType -> {
|
|
||||||
intentionFailed(editor, "package.call")
|
intentionFailed(editor, "package.call")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
intentionFailed(editor, "resolution.failed")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rightHandTextStringBuilder.append(
|
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.OverrideResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.java.jetAsJava.KotlinLightMethod;
|
import org.jetbrains.jet.lang.resolve.java.jetAsJava.KotlinLightMethod;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
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.lang.types.lang.KotlinBuiltIns;
|
||||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
@@ -432,9 +430,7 @@ public class JetRefactoringUtil {
|
|||||||
JetExpression expression = (JetExpression)element;
|
JetExpression expression = (JetExpression)element;
|
||||||
BindingContext bindingContext = AnalyzerFacadeWithCache.getContextForElement(expression);
|
BindingContext bindingContext = AnalyzerFacadeWithCache.getContextForElement(expression);
|
||||||
JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
|
JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
|
||||||
if (expressionType == null || !(expressionType instanceof PackageType) &&
|
if (expressionType == null || !KotlinBuiltIns.getInstance().isUnit(expressionType)) {
|
||||||
!JetTypeChecker.DEFAULT.equalTypes(KotlinBuiltIns.
|
|
||||||
getInstance().getUnitType(), expressionType)) {
|
|
||||||
expressions.add(expression);
|
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.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
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.TypeUtils;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
@@ -139,7 +138,8 @@ public class KotlinIntroduceVariableHandler extends KotlinIntroduceHandlerBase {
|
|||||||
noTypeInference = true;
|
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"));
|
showErrorHint(project, editor, JetRefactoringBundle.message("cannot.refactor.package.expression"));
|
||||||
return;
|
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 testEnumMember() = doTest(1, "A", null, '\n')
|
||||||
fun testEnumMember1() = doTest(1, "A", null, '\n')
|
fun testEnumMember1() = doTest(1, "A", null, '\n')
|
||||||
fun testClassFromClassObject() = doTest(1, "Some", null, '\n')
|
fun testClassFromClassObject() = doTest(1, "Some", null, '\n')
|
||||||
|
fun testClassFromClassObjectInPackage() = doTest(1, "Some", null, '\n')
|
||||||
|
|
||||||
fun testParameterType() = doTest(1, "StringBuilder", " (java.lang)", '\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");
|
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")
|
@TestMetadata("InheritedFunctions.kt")
|
||||||
public void testInheritedFunctions() throws Exception {
|
public void testInheritedFunctions() throws Exception {
|
||||||
doTest("idea/testData/parameterInfo/functionParameterInfo/InheritedFunctions.kt");
|
doTest("idea/testData/parameterInfo/functionParameterInfo/InheritedFunctions.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user