SimplesClosure test fixed.

This commit is contained in:
Andrey Breslav
2011-06-20 16:18:49 +04:00
parent b4ded8702c
commit 760b643df9
10 changed files with 194 additions and 14 deletions
@@ -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 + ".",