SimplesClosure test fixed.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
package org.jetbrains.jet.lang.descriptors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class VariableAsFunctionDescriptor extends FunctionDescriptorImpl {
|
||||
public static VariableAsFunctionDescriptor create(@NotNull VariableDescriptor variableDescriptor) {
|
||||
JetType outType = variableDescriptor.getOutType();
|
||||
assert outType != null;
|
||||
assert JetStandardClasses.isFunctionType(outType);
|
||||
VariableAsFunctionDescriptor result = new VariableAsFunctionDescriptor(variableDescriptor);
|
||||
result.initialize(JetStandardClasses.getReceiverType(outType), Collections.<TypeParameterDescriptor>emptyList(), JetStandardClasses.getValueParameters(result, outType), JetStandardClasses.getReturnType(outType));
|
||||
return result;
|
||||
}
|
||||
|
||||
private final VariableDescriptor variableDescriptor;
|
||||
|
||||
private VariableAsFunctionDescriptor(VariableDescriptor variableDescriptor) {
|
||||
super(variableDescriptor.getContainingDeclaration(), Collections.<Annotation>emptyList(), variableDescriptor.getName());
|
||||
// super(variableDescriptor.getContainingDeclaration(), Collections.<Annotation>emptyList(), variableDescriptor.getName());
|
||||
this.variableDescriptor = variableDescriptor;
|
||||
}
|
||||
|
||||
public VariableDescriptor getVariableDescriptor() {
|
||||
return variableDescriptor;
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
||||
|
||||
@Override
|
||||
public void recordDeclarationResolution(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor) {
|
||||
safePut(descriptorToDeclarations, descriptor.getOriginal(), declaration);
|
||||
safePut(descriptorToDeclarations, getOriginal(descriptor), declaration);
|
||||
descriptor.accept(new DeclarationDescriptorVisitor<Void, PsiElement>() {
|
||||
@Override
|
||||
public Void visitConstructorDescriptor(ConstructorDescriptor constructorDescriptor, PsiElement declaration) {
|
||||
@@ -121,7 +121,7 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
||||
}
|
||||
|
||||
public Void visitDeclarationDescriptor(DeclarationDescriptor descriptor, PsiElement declaration) {
|
||||
safePut(declarationsToDescriptors, declaration, descriptor.getOriginal());
|
||||
safePut(declarationsToDescriptors, declaration, getOriginal(descriptor));
|
||||
return null;
|
||||
}
|
||||
}, declaration);
|
||||
@@ -129,8 +129,8 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
||||
|
||||
@Override
|
||||
public void recordValueParameterAsPropertyResolution(@NotNull JetParameter declaration, @NotNull PropertyDescriptor descriptor) {
|
||||
safePut(primaryConstructorParameterDeclarationsToPropertyDescriptors, declaration, (PropertyDescriptor) descriptor.getOriginal());
|
||||
safePut(descriptorToDeclarations, descriptor.getOriginal(), declaration);
|
||||
safePut(primaryConstructorParameterDeclarationsToPropertyDescriptors, declaration, (PropertyDescriptor) getOriginal(descriptor));
|
||||
safePut(descriptorToDeclarations, getOriginal(descriptor), declaration);
|
||||
}
|
||||
|
||||
private <K, V> void safePut(Map<K, V> map, K key, V value) {
|
||||
@@ -246,12 +246,20 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
||||
if (declarationDescriptor == null) {
|
||||
return labelResolutionResults.get(referenceExpression);
|
||||
}
|
||||
return descriptorToDeclarations.get(declarationDescriptor.getOriginal());
|
||||
return descriptorToDeclarations.get(getOriginal(declarationDescriptor));
|
||||
}
|
||||
|
||||
private DeclarationDescriptor getOriginal(DeclarationDescriptor declarationDescriptor) {
|
||||
if (declarationDescriptor instanceof VariableAsFunctionDescriptor) {
|
||||
VariableAsFunctionDescriptor descriptor = (VariableAsFunctionDescriptor) declarationDescriptor;
|
||||
return descriptor.getVariableDescriptor().getOriginal();
|
||||
}
|
||||
return declarationDescriptor.getOriginal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getDeclarationPsiElement(@NotNull DeclarationDescriptor descriptor) {
|
||||
return descriptorToDeclarations.get(descriptor.getOriginal());
|
||||
return descriptorToDeclarations.get(getOriginal(descriptor));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -511,7 +511,7 @@ public class ClassDescriptorResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JetType getVariableType(@NotNull final JetScope scope, @NotNull JetProperty property, boolean allowDeferred) {
|
||||
private JetType getVariableType(@NotNull final JetScope scope, @NotNull final JetProperty property, boolean allowDeferred) {
|
||||
// TODO : receiver?
|
||||
JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
|
||||
|
||||
@@ -525,7 +525,8 @@ public class ClassDescriptorResolver {
|
||||
LazyValue<JetType> lazyValue = new LazyValue<JetType>() {
|
||||
@Override
|
||||
protected JetType compute() {
|
||||
return semanticServices.getTypeInferrerServices(trace, JetFlowInformationProvider.THROW_EXCEPTION).safeGetType(scope, initializer, false, JetTypeInferrer.NO_EXPECTED_TYPE);
|
||||
JetFlowInformationProvider flowInformationProvider = computeFlowData(property, initializer);
|
||||
return semanticServices.getTypeInferrerServices(trace, flowInformationProvider).safeGetType(scope, initializer, false, JetTypeInferrer.NO_EXPECTED_TYPE);
|
||||
}
|
||||
};
|
||||
if (allowDeferred) {
|
||||
|
||||
@@ -36,6 +36,9 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
@Nullable
|
||||
private JetType thisType;
|
||||
|
||||
private boolean variablesAsFunctionsAdded;
|
||||
private List<VariableDescriptor> variableDescriptors;
|
||||
|
||||
public WritableScopeImpl(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner, @NotNull ErrorHandler errorHandler) {
|
||||
super(scope, errorHandler);
|
||||
this.ownerDeclarationDescriptor = owner;
|
||||
@@ -122,6 +125,14 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
return variableClassOrNamespaceDescriptors;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<VariableDescriptor> getVariableDescriptors() {
|
||||
if (variableDescriptors == null) {
|
||||
variableDescriptors = Lists.newArrayList();
|
||||
}
|
||||
return variableDescriptors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor) {
|
||||
Map<String, DeclarationDescriptor> variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors();
|
||||
@@ -132,6 +143,8 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
// TODO : Should this always happen?
|
||||
variableClassOrNamespaceDescriptors.put(variableDescriptor.getName(), variableDescriptor);
|
||||
allDescriptors.add(variableDescriptor);
|
||||
|
||||
getVariableDescriptors().add(variableDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -174,6 +187,8 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
@Override
|
||||
@NotNull
|
||||
public FunctionGroup getFunctionGroup(@NotNull String name) {
|
||||
addVariablesAsFunctions();
|
||||
|
||||
FunctionGroup functionGroup = getFunctionGroups().get(name);
|
||||
FunctionGroup constructors = null;
|
||||
ClassifierDescriptor classifier = getClassifier(name);
|
||||
@@ -212,6 +227,17 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
return super.getFunctionGroup(name);
|
||||
}
|
||||
|
||||
private void addVariablesAsFunctions() {
|
||||
if (variablesAsFunctionsAdded) return;
|
||||
variablesAsFunctionsAdded = true;
|
||||
for (VariableDescriptor variableDescriptor : getVariableDescriptors()) {
|
||||
JetType outType = variableDescriptor.getOutType();
|
||||
if (outType != null && JetStandardClasses.isFunctionType(outType)) {
|
||||
addFunctionDescriptor(VariableAsFunctionDescriptor.create(variableDescriptor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTypeParameterDescriptor(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
|
||||
String name = typeParameterDescriptor.getName();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
@@ -133,6 +135,9 @@ public class JetStandardClasses {
|
||||
private static final ClassDescriptor[] FUNCTION = new ClassDescriptor[FUNCTION_COUNT];
|
||||
private static final ClassDescriptor[] RECEIVER_FUNCTION = new ClassDescriptor[FUNCTION_COUNT];
|
||||
|
||||
private static final Set<TypeConstructor> FUNCTION_TYPE_CONSTRUCTORS = Sets.newHashSet();
|
||||
private static final Set<TypeConstructor> RECEIVER_FUNCTION_TYPE_CONSTRUCTORS = Sets.newHashSet();
|
||||
|
||||
static {
|
||||
for (int i = 0; i < FUNCTION_COUNT; i++) {
|
||||
ClassDescriptorImpl function = new ClassDescriptorImpl(
|
||||
@@ -143,6 +148,7 @@ public class JetStandardClasses {
|
||||
false,
|
||||
createTypeParameters(i, function),
|
||||
Collections.singleton(getAnyType()), STUB, FunctionGroup.EMPTY, null);
|
||||
FUNCTION_TYPE_CONSTRUCTORS.add(FUNCTION[i].getTypeConstructor());
|
||||
|
||||
ClassDescriptorImpl receiverFunction = new ClassDescriptorImpl(
|
||||
STANDARD_CLASSES_NAMESPACE,
|
||||
@@ -157,6 +163,7 @@ public class JetStandardClasses {
|
||||
false,
|
||||
parameters,
|
||||
Collections.singleton(getAnyType()), STUB, FunctionGroup.EMPTY, null);
|
||||
RECEIVER_FUNCTION_TYPE_CONSTRUCTORS.add(RECEIVER_FUNCTION[i].getTypeConstructor());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,4 +345,40 @@ public class JetStandardClasses {
|
||||
private static TypeProjection defaultProjection(JetType returnType) {
|
||||
return new TypeProjection(Variance.INVARIANT, returnType);
|
||||
}
|
||||
|
||||
public static boolean isFunctionType(@NotNull JetType type) {
|
||||
return FUNCTION_TYPE_CONSTRUCTORS.contains(type.getConstructor()) || RECEIVER_FUNCTION_TYPE_CONSTRUCTORS.contains(type.getConstructor());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JetType getReceiverType(@NotNull JetType type) {
|
||||
assert isFunctionType(type) : type;
|
||||
if (RECEIVER_FUNCTION_TYPE_CONSTRUCTORS.contains(type.getConstructor())) {
|
||||
return type.getArguments().get(0).getType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<ValueParameterDescriptor> getValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull JetType type) {
|
||||
assert isFunctionType(type);
|
||||
List<TypeProjection> arguments = type.getArguments();
|
||||
int first = RECEIVER_FUNCTION_TYPE_CONSTRUCTORS.contains(type.getConstructor()) ? 1 : 0;
|
||||
int last = arguments.size() - 2;
|
||||
List<ValueParameterDescriptor> valueParameters = Lists.newArrayList();
|
||||
for (int i = first; i <= last; i++) {
|
||||
JetType parameterType = arguments.get(i).getType();
|
||||
ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl(functionDescriptor, i, Collections.<Annotation>emptyList(), "p" + i, null, parameterType, false, false);
|
||||
valueParameters.add(valueParameterDescriptor);
|
||||
}
|
||||
return valueParameters;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetType getReturnType(@NotNull JetType type) {
|
||||
assert isFunctionType(type);
|
||||
List<TypeProjection> arguments = type.getArguments();
|
||||
return arguments.get(arguments.size() - 1).getType();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,3 +36,15 @@ l1:
|
||||
error:
|
||||
<ERROR>
|
||||
=====================
|
||||
== a ==
|
||||
val a = Array<Int>
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
r(Array)
|
||||
r(Array<Int>)
|
||||
l1:
|
||||
<END>
|
||||
error:
|
||||
<ERROR>
|
||||
=====================
|
||||
|
||||
@@ -55,3 +55,56 @@ l1:
|
||||
error:
|
||||
<ERROR>
|
||||
=====================
|
||||
== x ==
|
||||
var x = 1
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
r(1)
|
||||
l1:
|
||||
<END>
|
||||
error:
|
||||
<ERROR>
|
||||
=====================
|
||||
== y ==
|
||||
val y = true && false
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
r(true)
|
||||
jf(l2)
|
||||
r(false)
|
||||
l2:
|
||||
r(true && false)
|
||||
l1:
|
||||
<END>
|
||||
error:
|
||||
<ERROR>
|
||||
=====================
|
||||
== z ==
|
||||
val z = false && true
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
r(false)
|
||||
jf(l2)
|
||||
r(true)
|
||||
l2:
|
||||
r(false && true)
|
||||
l1:
|
||||
<END>
|
||||
error:
|
||||
<ERROR>
|
||||
=====================
|
||||
== t ==
|
||||
val t = Test()
|
||||
---------------------
|
||||
l0:
|
||||
<START>
|
||||
r(Test)
|
||||
r(Test())
|
||||
l1:
|
||||
<END>
|
||||
error:
|
||||
<ERROR>
|
||||
=====================
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace a {
|
||||
val foo = <error>bar()</error>
|
||||
val foo = bar()
|
||||
|
||||
fun bar() = foo
|
||||
fun bar() = <error>foo</error>
|
||||
}
|
||||
|
||||
namespace b {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
fun invoker(~gen~gen : {() : Int}) : Int {
|
||||
return `gen`gen() // Says it cannot resolve 'gen' here
|
||||
}
|
||||
@@ -8,10 +8,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
@@ -186,6 +183,10 @@ public class ExpectedResolveData {
|
||||
|
||||
|
||||
DeclarationDescriptor actualDescriptor = bindingContext.resolveReferenceExpression(reference);
|
||||
if (actualDescriptor instanceof VariableAsFunctionDescriptor) {
|
||||
VariableAsFunctionDescriptor descriptor = (VariableAsFunctionDescriptor) actualDescriptor;
|
||||
actualDescriptor = descriptor.getVariableDescriptor();
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
"Reference `" + name + "`" + renderReferenceInContext(reference) + " is resolved into " + actualName + ".",
|
||||
|
||||
Reference in New Issue
Block a user