Resolve for receiver-properties (generic arguments are not supported)

This commit is contained in:
Andrey Breslav
2011-05-20 18:06:59 +04:00
parent 3e0141ada4
commit 0afddb4d9e
4 changed files with 46 additions and 5 deletions
@@ -36,6 +36,7 @@ public class ScopeWithReceiver extends JetScopeImpl {
if (functionReceiverType == null) {
return false;
}
// TODO : in case of inferred type arguments, substitute the receiver type first
return typeChecker.isSubtypeOf(receiverTypeScope.getThisType(), functionReceiverType);
}
});
@@ -50,8 +51,21 @@ public class ScopeWithReceiver extends JetScopeImpl {
@Override
public VariableDescriptor getVariable(@NotNull String name) {
return receiverTypeScope.getVariable(name);
// TODO : extension properties
VariableDescriptor variable = receiverTypeScope.getVariable(name);
if (variable != null) {
return variable;
}
variable = outerScope.getVariable(name);
if (variable instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variable;
JetType receiverType = propertyDescriptor.getReceiverType();
// TODO : in case of type arguments, substitute the receiver type first
if (receiverType != null
&& typeChecker.isSubtypeOf(receiverTypeScope.getThisType(), receiverType)) {
return variable;
}
}
return null;
}
@Override
@@ -583,10 +583,22 @@ public class TopDownAnalyzer {
}
}
private JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, @NotNull PropertyDescriptor propertyDescriptor) {
WritableScopeImpl result = new WritableScopeImpl(outerScope, propertyDescriptor, trace.getErrorHandler());
for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParemeters()) {
result.addTypeParameterDescriptor(typeParameterDescriptor);
}
JetType receiverType = propertyDescriptor.getReceiverType();
if (receiverType != null) {
result.setThisType(receiverType);
}
return result;
}
private void resolvePropertyAccessors(JetProperty property, PropertyDescriptor propertyDescriptor, JetScope declaringScope) {
BindingTraceAdapter fieldAccessTrackingTrace = createFieldTrackingTrace(propertyDescriptor);
WritableScope accessorScope = new WritableScopeImpl(declaringScope, declaringScope.getContainingDeclaration(), trace.getErrorHandler());
WritableScope accessorScope = new WritableScopeImpl(getPropertyDeclarationInnerScope(declaringScope, propertyDescriptor), declaringScope.getContainingDeclaration(), trace.getErrorHandler());
accessorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor);
JetPropertyAccessor getter = property.getGetter();
@@ -628,7 +640,7 @@ public class TopDownAnalyzer {
private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) {
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(property, initializer); // TODO : flow JET-15
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, flowInformationProvider);
JetType type = typeInferrer.getType(scope, initializer, false);
JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, false);
JetType expectedType;
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
@@ -1730,6 +1730,11 @@ public class JetTypeInferrer {
@Override
public void visitProperty(JetProperty property) {
JetTypeReference receiverTypeRef = property.getReceiverTypeRef();
if (receiverTypeRef != null) {
trace.getErrorHandler().genericError(receiverTypeRef.getNode(), "Local receiver-properties are not allowed");
}
JetPropertyAccessor getter = property.getGetter();
if (getter != null) {
trace.getErrorHandler().genericError(getter.getNode(), "Local variables are not allowed to have getters");
+11 -1
View File
@@ -18,4 +18,14 @@ fun <~T~T, ~E~E> `T`T.foo(x : `E`E, y : `A`A) : `T`T {
1
}
~-~fun <T> T.minus(t : T) : Int = 1
~-~fun <T> T.minus(t : T) : Int = 1
fun test() {
val y = 1.`abs`abs
}
~abs~val Int.abs : Int
get() = if (this`:std::Int` > 0) this else -this`:std::Int`;
val <~TT~T> `TT`T.foo : `TT`T
fun Int.foo() = this`:std::Int`