Merge remote branch 'origin/master'

This commit is contained in:
Dmitry Jemerov
2011-05-30 16:29:39 +04:00
16 changed files with 142 additions and 39 deletions
@@ -72,10 +72,12 @@ public class JetControlFlowProcessor {
} }
@Nullable @Nullable
private JetElement resolveLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression) { private JetElement resolveLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved) {
Stack<JetElement> stack = labeledElements.get(labelName); Stack<JetElement> stack = labeledElements.get(labelName);
if (stack == null || stack.isEmpty()) { if (stack == null || stack.isEmpty()) {
trace.getErrorHandler().unresolvedReference(labelExpression); if (reportUnresolved) {
trace.getErrorHandler().unresolvedReference(labelExpression);
}
return null; return null;
} }
else if (stack.size() > 1) { else if (stack.size() > 1) {
@@ -119,6 +121,12 @@ public class JetControlFlowProcessor {
@Override @Override
public void visitThisExpression(JetThisExpression expression) { public void visitThisExpression(JetThisExpression expression) {
JetSimpleNameExpression targetLabel = expression.getTargetLabel();
if (targetLabel != null) {
String labelName = expression.getLabelName();
assert labelName != null;
resolveLabel(labelName, targetLabel, false);
}
builder.read(expression); builder.read(expression);
} }
@@ -416,7 +424,7 @@ public class JetControlFlowProcessor {
if (labelName != null) { if (labelName != null) {
JetSimpleNameExpression targetLabel = expression.getTargetLabel(); JetSimpleNameExpression targetLabel = expression.getTargetLabel();
assert targetLabel != null; assert targetLabel != null;
loop = resolveLabel(labelName, targetLabel); loop = resolveLabel(labelName, targetLabel, true);
if (!isLoop(loop)) { if (!isLoop(loop)) {
trace.getErrorHandler().genericError(expression.getNode(), "The label '" + targetLabel.getText() + "' does not denote a loop"); trace.getErrorHandler().genericError(expression.getNode(), "The label '" + targetLabel.getText() + "' does not denote a loop");
loop = null; loop = null;
@@ -448,7 +456,7 @@ public class JetControlFlowProcessor {
if (labelElement != null) { if (labelElement != null) {
String labelName = expression.getLabelName(); String labelName = expression.getLabelName();
assert labelName != null; assert labelName != null;
subroutine = resolveLabel(labelName, labelElement); subroutine = resolveLabel(labelName, labelElement, true);
} }
else { else {
subroutine = builder.getCurrentSubroutine(); subroutine = builder.getCurrentSubroutine();
@@ -27,7 +27,7 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
@Override @Override
@Deprecated @Deprecated
public FunctionDescriptor initialize(@Nullable JetType receiverType, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @NotNull JetType unsubstitutedReturnType) { public FunctionDescriptorImpl initialize(@Nullable JetType receiverType, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @Nullable JetType unsubstitutedReturnType) {
assert receiverType == null; assert receiverType == null;
return super.initialize(null, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType); return super.initialize(null, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType);
} }
@@ -40,7 +40,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
this.original = original; this.original = original;
} }
public FunctionDescriptor initialize( public FunctionDescriptorImpl initialize(
@Nullable JetType receiverType, @Nullable JetType receiverType,
@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
@@ -52,6 +52,10 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
return this; return this;
} }
public void setReturnType(JetType unsubstitutedReturnType) {
this.unsubstitutedReturnType = unsubstitutedReturnType;
}
@Override @Override
public JetType getReceiverType() { public JetType getReceiverType() {
return receiverType; return receiverType;
@@ -9,12 +9,19 @@ import java.util.List;
/** /**
* @author abreslav * @author abreslav
*/ */
public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorImpl implements FunctionDescriptor { public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorImpl implements FunctionDescriptor, MemberDescriptor {
private final boolean hasBody; private final boolean hasBody;
private final MemberModifiers modifiers;
protected PropertyAccessorDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Annotation> annotations, @NotNull String name, boolean hasBody) { protected PropertyAccessorDescriptor(
@NotNull MemberModifiers modifiers,
@NotNull PropertyDescriptor correspondingProperty,
@NotNull List<Annotation> annotations,
@NotNull String name,
boolean hasBody) {
super(correspondingProperty.getContainingDeclaration(), annotations, name); super(correspondingProperty.getContainingDeclaration(), annotations, name);
this.modifiers = modifiers;
this.hasBody = hasBody; this.hasBody = hasBody;
} }
@@ -39,4 +46,10 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
public List<TypeParameterDescriptor> getTypeParameters() { public List<TypeParameterDescriptor> getTypeParameters() {
return Collections.emptyList(); return Collections.emptyList();
} }
@NotNull
@Override
public MemberModifiers getModifiers() {
return modifiers;
}
} }
@@ -16,8 +16,8 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
private final Set<PropertyGetterDescriptor> overriddenGetters = Sets.newHashSet(); private final Set<PropertyGetterDescriptor> overriddenGetters = Sets.newHashSet();
private JetType returnType; private JetType returnType;
public PropertyGetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Annotation> annotations, @Nullable JetType returnType, boolean hasBody) { public PropertyGetterDescriptor(@NotNull MemberModifiers modifiers, @NotNull PropertyDescriptor correspondingProperty, @NotNull List<Annotation> annotations, @Nullable JetType returnType, boolean hasBody) {
super(correspondingProperty, annotations, "get-" + correspondingProperty.getName(), hasBody); super(modifiers, correspondingProperty, annotations, "get-" + correspondingProperty.getName(), hasBody);
this.returnType = returnType == null ? correspondingProperty.getOutType() : returnType; this.returnType = returnType == null ? correspondingProperty.getOutType() : returnType;
} }
@@ -17,8 +17,8 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
private MutableValueParameterDescriptor parameter; private MutableValueParameterDescriptor parameter;
private final Set<PropertySetterDescriptor> overriddenSetters = Sets.newHashSet(); private final Set<PropertySetterDescriptor> overriddenSetters = Sets.newHashSet();
public PropertySetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<Annotation> annotations, boolean hasBody) { public PropertySetterDescriptor(@NotNull MemberModifiers modifiers, @NotNull PropertyDescriptor correspondingProperty, @NotNull List<Annotation> annotations, boolean hasBody) {
super(correspondingProperty, annotations, "set-" + correspondingProperty.getName(), hasBody); super(modifiers, correspondingProperty, annotations, "set-" + correspondingProperty.getName(), hasBody);
} }
public void initialize(@NotNull MutableValueParameterDescriptor parameter) { public void initialize(@NotNull MutableValueParameterDescriptor parameter) {
@@ -256,10 +256,10 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
else if (propertyDescriptor.isVar() && setter == null) { else if (propertyDescriptor.isVar() && setter == null) {
return true; return true;
} }
else if (setter != null && !setter.hasBody()) { else if (setter != null && !setter.hasBody() && !setter.getModifiers().isAbstract()) {
return true; return true;
} }
else if (!getter.hasBody()) { else if (!getter.hasBody() && !getter.getModifiers().isAbstract()) {
return true; return true;
} }
return backingFieldRequired.contains(propertyDescriptor); return backingFieldRequired.contains(propertyDescriptor);
@@ -248,7 +248,7 @@ public class ClassDescriptorResolver {
} }
@NotNull @NotNull
private MutableValueParameterDescriptor resolveValueParameterDescriptor(DeclarationDescriptor declarationDescriptor, JetParameter valueParameter, int index, JetType type) { public MutableValueParameterDescriptor resolveValueParameterDescriptor(DeclarationDescriptor declarationDescriptor, JetParameter valueParameter, int index, JetType type) {
MutableValueParameterDescriptor valueParameterDescriptor = new ValueParameterDescriptorImpl( MutableValueParameterDescriptor valueParameterDescriptor = new ValueParameterDescriptorImpl(
declarationDescriptor, declarationDescriptor,
index, index,
@@ -343,7 +343,7 @@ public class ClassDescriptorResolver {
@NotNull @NotNull
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, WritableScope scope, JetProperty property) { public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, WritableScope scope, JetProperty property) {
JetType type = getType(scope, property, false); // For a local variable the type must not be deferred JetType type = getVariableType(scope, property, false); // For a local variable the type must not be deferred
VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor( VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
containingDeclaration, containingDeclaration,
@@ -380,7 +380,7 @@ public class ClassDescriptorResolver {
JetModifierList modifierList = property.getModifierList(); JetModifierList modifierList = property.getModifierList();
boolean isVar = property.isVar(); boolean isVar = property.isVar();
JetType type = getType(scopeWithTypeParameters, property, true); JetType type = getVariableType(scopeWithTypeParameters, property, true);
PropertyDescriptor propertyDescriptor = new PropertyDescriptor( PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
containingDeclaration, containingDeclaration,
@@ -402,7 +402,7 @@ public class ClassDescriptorResolver {
} }
@NotNull @NotNull
private JetType getType(@NotNull final JetScope scope, @NotNull JetProperty property, boolean allowDeferred) { private JetType getVariableType(@NotNull final JetScope scope, @NotNull JetProperty property, boolean allowDeferred) {
// TODO : receiver? // TODO : receiver?
JetTypeReference propertyTypeRef = property.getPropertyTypeRef(); JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
@@ -453,7 +453,9 @@ public class ClassDescriptorResolver {
List<Annotation> annotations = AnnotationResolver.INSTANCE.resolveAnnotations(setter.getModifierList()); List<Annotation> annotations = AnnotationResolver.INSTANCE.resolveAnnotations(setter.getModifierList());
JetParameter parameter = setter.getParameter(); JetParameter parameter = setter.getParameter();
setterDescriptor = new PropertySetterDescriptor(propertyDescriptor, annotations, setter.getBodyExpression() != null); setterDescriptor = new PropertySetterDescriptor(
resolveModifiers(setter.getModifierList(), DEFAULT_MODIFIERS), // TODO : default modifiers differ in different contexts
propertyDescriptor, annotations, setter.getBodyExpression() != null);
if (parameter != null) { if (parameter != null) {
if (parameter.isRef()) { if (parameter.isRef()) {
trace.getErrorHandler().genericError(parameter.getRefNode(), "Setter parameters can not be 'ref'"); trace.getErrorHandler().genericError(parameter.getRefNode(), "Setter parameters can not be 'ref'");
@@ -504,7 +506,9 @@ public class ClassDescriptorResolver {
returnType = typeResolver.resolveType(scope, returnTypeReference); returnType = typeResolver.resolveType(scope, returnTypeReference);
} }
getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, annotations, returnType, getter.getBodyExpression() != null); getterDescriptor = new PropertyGetterDescriptor(
resolveModifiers(getter.getModifierList(), DEFAULT_MODIFIERS), // TODO : default modifiers differ in different contexts
propertyDescriptor, annotations, returnType, getter.getBodyExpression() != null);
trace.recordDeclarationResolution(getter, getterDescriptor); trace.recordDeclarationResolution(getter, getterDescriptor);
} }
return getterDescriptor; return getterDescriptor;
@@ -3,7 +3,7 @@ package org.jetbrains.jet.lang.resolve;
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.*;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.JetType;
import java.util.Collection; import java.util.Collection;
@@ -1,6 +1,7 @@
package org.jetbrains.jet.lang.types; package org.jetbrains.jet.lang.types;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
@@ -735,10 +736,6 @@ public class JetTypeInferrer {
return; return;
} }
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(scope.getContainingDeclaration(), Collections.<Annotation>emptyList(), "<anonymous>");
JetTypeReference returnTypeRef = expression.getReturnTypeRef();
JetTypeReference receiverTypeRef = expression.getReceiverTypeRef(); JetTypeReference receiverTypeRef = expression.getReceiverTypeRef();
final JetType receiverType; final JetType receiverType;
if (receiverTypeRef != null) { if (receiverTypeRef != null) {
@@ -747,31 +744,44 @@ public class JetTypeInferrer {
receiverType = scope.getThisType(); receiverType = scope.getThisType();
} }
List<JetElement> body = expression.getBody(); FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(
final Map<String, VariableDescriptor> parameterDescriptors = new HashMap<String, VariableDescriptor>(); scope.getContainingDeclaration(), Collections.<Annotation>emptyList(), "<anonymous>");
List<JetType> parameterTypes = new ArrayList<JetType>(); List<JetType> parameterTypes = new ArrayList<JetType>();
for (JetParameter parameter : expression.getParameters()) { List<ValueParameterDescriptor> valueParameterDescriptors = Lists.newArrayList();
List<JetParameter> parameters = expression.getParameters();
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
JetParameter parameter = parameters.get(i);
JetTypeReference typeReference = parameter.getTypeReference(); JetTypeReference typeReference = parameter.getTypeReference();
if (typeReference == null) { if (typeReference == null) {
throw new UnsupportedOperationException("Type inference for parameters is not implemented yet"); throw new UnsupportedOperationException("Type inference for parameters is not implemented yet");
} }
VariableDescriptor variableDescriptor = classDescriptorResolver.resolveLocalVariableDescriptor(functionDescriptor, scope, parameter); JetType type = typeResolver.resolveType(scope, typeReference);
parameterDescriptors.put(parameter.getName(), variableDescriptor); ValueParameterDescriptor valueParameterDescriptor = classDescriptorResolver.resolveValueParameterDescriptor(functionDescriptor, parameter, i, type);
parameterTypes.add(variableDescriptor.getOutType()); parameterTypes.add(valueParameterDescriptor.getOutType());
valueParameterDescriptors.add(valueParameterDescriptor);
} }
JetType effectiveReceiverType = receiverTypeRef == null ? null : receiverType;
functionDescriptor.initialize(effectiveReceiverType, Collections.<TypeParameterDescriptor>emptyList(), valueParameterDescriptors, null);
trace.recordDeclarationResolution(expression, functionDescriptor);
JetTypeReference returnTypeRef = expression.getReturnTypeRef();
JetType returnType; JetType returnType;
if (returnTypeRef != null) { if (returnTypeRef != null) {
returnType = typeResolver.resolveType(scope, returnTypeRef); returnType = typeResolver.resolveType(scope, returnTypeRef);
} else { } else {
WritableScope writableScope = new WritableScopeImpl(scope, functionDescriptor, trace.getErrorHandler()); WritableScope writableScope = new WritableScopeImpl(scope, functionDescriptor, trace.getErrorHandler());
for (VariableDescriptor variableDescriptor : parameterDescriptors.values()) { for (VariableDescriptor variableDescriptor : valueParameterDescriptors) {
writableScope.addVariableDescriptor(variableDescriptor); writableScope.addVariableDescriptor(variableDescriptor);
} }
writableScope.setThisType(receiverType); writableScope.setThisType(receiverType);
returnType = getBlockReturnedType(writableScope, body); returnType = getBlockReturnedType(writableScope, expression.getBody());
} }
JetType effectiveReceiverType = receiverTypeRef == null ? null : receiverType;
JetType safeReturnType = returnType == null ? ErrorUtils.createErrorType("<return type>") : returnType; JetType safeReturnType = returnType == null ? ErrorUtils.createErrorType("<return type>") : returnType;
functionDescriptor.setReturnType(safeReturnType);
result = JetStandardClasses.getFunctionType(Collections.<Annotation>emptyList(), effectiveReceiverType, parameterTypes, safeReturnType); result = JetStandardClasses.getFunctionType(Collections.<Annotation>emptyList(), effectiveReceiverType, parameterTypes, safeReturnType);
} }
@@ -928,7 +938,6 @@ public class JetTypeInferrer {
@Override @Override
public void visitThisExpression(JetThisExpression expression) { public void visitThisExpression(JetThisExpression expression) {
// TODO : qualified this, e.g. this@Foo<Bar>
JetType thisType = null; JetType thisType = null;
String labelName = expression.getLabelName(); String labelName = expression.getLabelName();
if (labelName != null) { if (labelName != null) {
@@ -941,15 +950,39 @@ public class JetTypeInferrer {
if (declarationDescriptor instanceof ClassDescriptor) { if (declarationDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
thisType = classDescriptor.getDefaultType(); thisType = classDescriptor.getDefaultType();
trace.recordReferenceResolution(targetLabel, classDescriptor); }
trace.recordReferenceResolution(expression.getThisReference(), classDescriptor); else if (declarationDescriptor instanceof FunctionDescriptor) {
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
thisType = functionDescriptor.getReceiverType();
} }
else { else {
throw new UnsupportedOperationException(); // TODO throw new UnsupportedOperationException(); // TODO
} }
trace.recordReferenceResolution(targetLabel, declarationDescriptor);
trace.recordReferenceResolution(expression.getThisReference(), declarationDescriptor);
} }
else if (size == 0) { else if (size == 0) {
trace.getErrorHandler().unresolvedReference(targetLabel); // This uses the info written by the control flow processor
PsiElement psiElement = trace.getBindingContext().resolveToDeclarationPsiElement(targetLabel);
if (psiElement instanceof JetFunctionLiteralExpression) {
DeclarationDescriptor declarationDescriptor = trace.getBindingContext().getDeclarationDescriptor(psiElement);
if (declarationDescriptor instanceof FunctionDescriptor) {
thisType = ((FunctionDescriptor) declarationDescriptor).getReceiverType();
if (thisType == null) {
thisType = JetStandardClasses.getNothingType();
}
else {
trace.recordReferenceResolution(targetLabel, declarationDescriptor);
trace.recordReferenceResolution(expression.getThisReference(), declarationDescriptor);
}
}
else {
trace.getErrorHandler().unresolvedReference(targetLabel);
}
}
else {
trace.getErrorHandler().unresolvedReference(targetLabel);
}
} }
else { else {
trace.getErrorHandler().genericError(targetLabel.getNode(), "Ambiguous label"); trace.getErrorHandler().genericError(targetLabel.getNode(), "Ambiguous label");
@@ -34,6 +34,13 @@ public class JetQuickDocumentationProvider implements DocumentationProvider {
if (declarationDescriptor != null) { if (declarationDescriptor != null) {
return render(declarationDescriptor); return render(declarationDescriptor);
} }
PsiElement psiElement = bindingContext.resolveToDeclarationPsiElement(ref);
if (psiElement != null) {
declarationDescriptor = bindingContext.getDeclarationDescriptor(psiElement);
if (declarationDescriptor != null) {
return render(declarationDescriptor);
}
}
return "Unresolved"; return "Unresolved";
} }
+19
View File
@@ -20,3 +20,22 @@ fun foo() : Unit {
<error>this</error> <error>this</error>
this<error>@a</error> this<error>@a</error>
} }
namespace closures {
class A(val a:Int) {
class B() {
val x = this@B : B
val y = this@A : A
val z = this : B
val Int.xx = this : Int
fun Char.xx() {
this : Char
val a = {Double.() => this : Double + this@xx : Char}
val b = @a{Double.() => this@a : Double + this@xx : Char}
val c = @a{() => <error>this@a</error> + this@xx : Char}
return (@a{Double.() => this@a : Double + this@xx : Char})
}
}
}
}
@@ -33,6 +33,12 @@ class Test() {
var <info>v5</info> : Int <info>get</info>() = 1; <info>set</info>(x){$v5 = x} var <info>v5</info> : Int <info>get</info>() = 1; <info>set</info>(x){$v5 = x}
var <info>v6</info> : Int <info>get</info>() = $v6 + 1; <info>set</info>(x){} var <info>v6</info> : Int <info>get</info>() = $v6 + 1; <info>set</info>(x){}
val v7 : Int <info>abstract</info> <info>get</info>
var v8 : Int <info>abstract</info> <info>get</info> <info>abstract</info> <info>set</info>
var <info>v9</info> : Int <info>abstract</info> <info>set</info>
var <info>v10</info> : Int <info>abstract</info> <info>get</info>
} }
<info>open</info> class Super(i : Int) <info>open</info> class Super(i : Int)
@@ -0,0 +1,4 @@
class XXX {
val a : Int abstract get
}
+2
View File
@@ -8,6 +8,8 @@ namespace qualified_this {
~xx~val Int.xx = `xx`this : Int ~xx~val Int.xx = `xx`this : Int
~xx()~fun Int.xx() { ~xx()~fun Int.xx() {
`xx()`this : Int `xx()`this : Int
val a = {Int.() => `xx()`this`xx()`@xx + this}
} }
} }
} }
@@ -12,7 +12,10 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetChangeUtil; import org.jetbrains.jet.lang.psi.JetChangeUtil;
import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.ClassDescriptorResolver;
import org.jetbrains.jet.lang.resolve.JetScope;
import org.jetbrains.jet.lang.resolve.JetScopeAdapter;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.parsing.JetParsingTest; import org.jetbrains.jet.parsing.JetParsingTest;