KT-156 Fix the this<Super> syntax

In progress: super<List> must work, but currently it does not, only super<List<Foo>> works, where Foo is ignored.
This commit is contained in:
Andrey Breslav
2011-10-19 19:24:46 +04:00
parent 84951d2585
commit 79ee5cd606
38 changed files with 742 additions and 486 deletions
@@ -1988,7 +1988,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override @Override
public StackValue visitThisExpression(JetThisExpression expression, StackValue receiver) { public StackValue visitThisExpression(JetThisExpression expression, StackValue receiver) {
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getThisReference()); final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getInstanceReference());
if (descriptor instanceof ClassDescriptor) { if (descriptor instanceof ClassDescriptor) {
return generateThisOrOuter((ClassDescriptor) descriptor); return generateThisOrOuter((ClassDescriptor) descriptor);
} }
@@ -51,11 +51,6 @@ public class JavaClassMembersScope implements JetScope {
return null; return null;
} }
@Override
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
throw new UnsupportedOperationException();
}
@Override @Override
public ClassifierDescriptor getClassifier(@NotNull String name) { public ClassifierDescriptor getClassifier(@NotNull String name) {
ClassifierDescriptor classifierDescriptor = classifiers.get(name); ClassifierDescriptor classifierDescriptor = classifiers.get(name);
@@ -109,6 +109,7 @@ public interface JetNodeTypes {
JetNodeType LABEL_QUALIFIER = new JetNodeType("LABEL_QUALIFIER", JetContainerNode.class); JetNodeType LABEL_QUALIFIER = new JetNodeType("LABEL_QUALIFIER", JetContainerNode.class);
JetNodeType THIS_EXPRESSION = new JetNodeType("THIS_EXPRESSION", JetThisExpression.class); JetNodeType THIS_EXPRESSION = new JetNodeType("THIS_EXPRESSION", JetThisExpression.class);
JetNodeType SUPER_EXPRESSION = new JetNodeType("SUPER_EXPRESSION", JetSuperExpression.class);
JetNodeType BINARY_EXPRESSION = new JetNodeType("BINARY_EXPRESSION", JetBinaryExpression.class); JetNodeType BINARY_EXPRESSION = new JetNodeType("BINARY_EXPRESSION", JetBinaryExpression.class);
JetNodeType BINARY_WITH_TYPE = new JetNodeType("BINARY_WITH_TYPE", JetBinaryExpressionWithTypeRHS.class); JetNodeType BINARY_WITH_TYPE = new JetNodeType("BINARY_WITH_TYPE", JetBinaryExpressionWithTypeRHS.class);
JetNodeType BINARY_WITH_PATTERN = new JetNodeType("BINARY_WITH_PATTERN", JetIsExpression.class); // TODO: JetNodeType BINARY_WITH_PATTERN = new JetNodeType("BINARY_WITH_PATTERN", JetIsExpression.class); // TODO:
@@ -159,11 +159,14 @@ public interface Errors {
SimpleDiagnosticFactory EQUALS_MISSING = SimpleDiagnosticFactory.create(ERROR, "No method 'equals(Any?) : Boolean' available"); SimpleDiagnosticFactory EQUALS_MISSING = SimpleDiagnosticFactory.create(ERROR, "No method 'equals(Any?) : Boolean' available");
SimpleDiagnosticFactory ASSIGNMENT_IN_EXPRESSION_CONTEXT = SimpleDiagnosticFactory.create(ERROR, "Assignments are not expressions, and only expressions are allowed in this context"); SimpleDiagnosticFactory ASSIGNMENT_IN_EXPRESSION_CONTEXT = SimpleDiagnosticFactory.create(ERROR, "Assignments are not expressions, and only expressions are allowed in this context");
SimpleDiagnosticFactory NAMESPACE_IS_NOT_AN_EXPRESSION = SimpleDiagnosticFactory.create(ERROR, "'namespace' is not an expression"); SimpleDiagnosticFactory NAMESPACE_IS_NOT_AN_EXPRESSION = SimpleDiagnosticFactory.create(ERROR, "'namespace' is not an expression, it can only be used on the left-hand side of a dot ('.')");
ParameterizedDiagnosticFactory1<String> SUPER_IS_NOT_AN_EXPRESSION = ParameterizedDiagnosticFactory1.create(ERROR, "{0} is not an expression, it can only be used on the left-hand side of a dot ('.')");
SimpleDiagnosticFactory DECLARATION_IN_ILLEGAL_CONTEXT = SimpleDiagnosticFactory.create(ERROR, "Declarations are not allowed in this position"); SimpleDiagnosticFactory DECLARATION_IN_ILLEGAL_CONTEXT = SimpleDiagnosticFactory.create(ERROR, "Declarations are not allowed in this position");
SimpleDiagnosticFactory REF_SETTER_PARAMETER = SimpleDiagnosticFactory.create(ERROR, "Setter parameters can not be 'ref'"); SimpleDiagnosticFactory REF_SETTER_PARAMETER = SimpleDiagnosticFactory.create(ERROR, "Setter parameters can not be 'ref'");
SimpleDiagnosticFactory SETTER_PARAMETER_WITH_DEFAULT_VALUE = SimpleDiagnosticFactory.create(ERROR, "Setter parameters can not have default values"); SimpleDiagnosticFactory SETTER_PARAMETER_WITH_DEFAULT_VALUE = SimpleDiagnosticFactory.create(ERROR, "Setter parameters can not have default values");
SimpleDiagnosticFactory NO_THIS = SimpleDiagnosticFactory.create(ERROR, "'this' is not defined in this context"); SimpleDiagnosticFactory NO_THIS = SimpleDiagnosticFactory.create(ERROR, "'this' is not defined in this context");
SimpleDiagnosticFactory SUPER_NOT_AVAILABLE = SimpleDiagnosticFactory.create(ERROR, "No supertypes are accessible in this context");
SimpleDiagnosticFactory AMBIGUOUS_SUPER = SimpleDiagnosticFactory.create(ERROR, "Many supertypes available, please specify the one you mean in angle brackets, e.g. 'super<Foo>'");
SimpleDiagnosticFactory NOT_A_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "Not a supertype"); SimpleDiagnosticFactory NOT_A_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "Not a supertype");
SimpleDiagnosticFactory NO_WHEN_ENTRIES = SimpleDiagnosticFactory.create(ERROR, "Entries are required for when-expression"); // TODO : Scope, and maybe this should not be an error SimpleDiagnosticFactory NO_WHEN_ENTRIES = SimpleDiagnosticFactory.create(ERROR, "Entries are required for when-expression"); // TODO : Scope, and maybe this should not be an error
SimplePsiElementOnlyDiagnosticFactory<JetBinaryExpressionWithTypeRHS> USELESS_CAST_STATIC_ASSERT_IS_FINE = SimplePsiElementOnlyDiagnosticFactory.create(WARNING, "No cast needed, use ':' instead"); SimplePsiElementOnlyDiagnosticFactory<JetBinaryExpressionWithTypeRHS> USELESS_CAST_STATIC_ASSERT_IS_FINE = SimplePsiElementOnlyDiagnosticFactory.create(WARNING, "No cast needed, use ':' instead");
@@ -49,6 +49,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
LPAR, // tuple LPAR, // tuple
THIS_KEYWORD, // this THIS_KEYWORD, // this
SUPER_KEYWORD, // super
IF_KEYWORD, // if IF_KEYWORD, // if
WHEN_KEYWORD, // when WHEN_KEYWORD, // when
@@ -464,7 +465,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
/* /*
* atomicExpression * atomicExpression
* : tupleLiteral // or parenthesized element * : tupleLiteral // or parenthesized element
* : "this" getEntryPoint? ("<" type ">")? * : "this" label?
* : "super" ("<" type ">")? label?
* : objectLiteral * : objectLiteral
* : jump * : jump
* : if * : if
@@ -490,6 +492,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
else if (at(THIS_KEYWORD)) { else if (at(THIS_KEYWORD)) {
parseThisExpression(); parseThisExpression();
} }
else if (at(SUPER_KEYWORD)) {
parseSuperExpression();
}
else if (at(OBJECT_KEYWORD)) { else if (at(OBJECT_KEYWORD)) {
parseObjectLiteral(); parseObjectLiteral();
} }
@@ -1593,7 +1598,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
} }
/* /*
* "this" getEntryPoint? ("<" type ">")? * "this" label?
*/ */
private void parseThisExpression() { private void parseThisExpression() {
assert _at(THIS_KEYWORD); assert _at(THIS_KEYWORD);
@@ -1605,8 +1610,22 @@ public class JetExpressionParsing extends AbstractJetParsing {
parseLabel(); parseLabel();
mark.done(THIS_EXPRESSION);
}
/*
* "this" ("<" type ">")? label?
*/
private void parseSuperExpression() {
assert _at(SUPER_KEYWORD);
PsiBuilder.Marker mark = mark();
PsiBuilder.Marker superReference = mark();
advance(); // SUPER_KEYWORD
superReference.done(REFERENCE_EXPRESSION);
if (at(LT)) { if (at(LT)) {
// This may be "this < foo" or "this<foo>", thus the backtracking // This may be "super < foo" or "super<foo>", thus the backtracking
PsiBuilder.Marker supertype = mark(); PsiBuilder.Marker supertype = mark();
myBuilder.disableNewlines(); myBuilder.disableNewlines();
@@ -1623,7 +1642,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
} }
myBuilder.restoreNewlinesState(); myBuilder.restoreNewlinesState();
} }
mark.done(THIS_EXPRESSION); parseLabel();
mark.done(SUPER_EXPRESSION);
} }
/* /*
@@ -0,0 +1,20 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetNodeTypes;
/**
* @author abreslav
*/
public abstract class JetLabelQualifiedInstanceExpression extends JetLabelQualifiedExpression {
public JetLabelQualifiedInstanceExpression(@NotNull ASTNode node) {
super(node);
}
@NotNull
public JetReferenceExpression getInstanceReference() {
return (JetReferenceExpression) findChildByType(JetNodeTypes.REFERENCE_EXPRESSION);
}
}
@@ -10,13 +10,14 @@ import com.intellij.psi.tree.TokenSet;
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.parsing.JetExpressionParsing; import org.jetbrains.jet.lang.parsing.JetExpressionParsing;
import org.jetbrains.jet.lexer.JetTokens;
import static org.jetbrains.jet.lexer.JetTokens.*;
/** /**
* @author max * @author max
*/ */
public class JetSimpleNameExpression extends JetReferenceExpression { public class JetSimpleNameExpression extends JetReferenceExpression {
public static final TokenSet REFERENCE_TOKENS = TokenSet.orSet(JetTokens.LABELS, TokenSet.create(JetTokens.IDENTIFIER, JetTokens.FIELD_IDENTIFIER, JetTokens.THIS_KEYWORD)); public static final TokenSet REFERENCE_TOKENS = TokenSet.orSet(LABELS, TokenSet.create(IDENTIFIER, FIELD_IDENTIFIER, THIS_KEYWORD, SUPER_KEYWORD));
public JetSimpleNameExpression(@NotNull ASTNode node) { public JetSimpleNameExpression(@NotNull ASTNode node) {
super(node); super(node);
@@ -0,0 +1,39 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
/**
* @author max
*/
public class JetSuperExpression extends JetLabelQualifiedInstanceExpression {
public JetSuperExpression(@NotNull ASTNode node) {
super(node);
}
@Override
public void accept(@NotNull JetVisitorVoid visitor) {
visitor.visitSuperExpression(this);
}
@Override
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
return visitor.visitSuperExpression(this, data);
}
/**
* class A : B, C {
* override fun foo() {
* super<B>.foo()
* super<C>.foo()
* }
* }
*/
@Nullable
public JetTypeReference getSuperTypeQualifier() {
return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE);
}
}
@@ -2,13 +2,11 @@ package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
/** /**
* @author max * @author max
*/ */
public class JetThisExpression extends JetLabelQualifiedExpression { public class JetThisExpression extends JetLabelQualifiedInstanceExpression {
public JetThisExpression(@NotNull ASTNode node) { public JetThisExpression(@NotNull ASTNode node) {
super(node); super(node);
@@ -23,23 +21,4 @@ public class JetThisExpression extends JetLabelQualifiedExpression {
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) { public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
return visitor.visitThisExpression(this, data); return visitor.visitThisExpression(this, data);
} }
/**
* class A : B, C {
* override fun foo() {
* this<B>.foo()
* this<C>.foo()
* }
* }
*/
@Nullable
public JetTypeReference getSuperTypeQualifier() {
return (JetTypeReference) findChildByType(JetNodeTypes.TYPE_REFERENCE);
}
@NotNull
public JetReferenceExpression getThisReference() {
return (JetReferenceExpression) findChildByType(JetNodeTypes.REFERENCE_EXPRESSION);
}
} }
@@ -511,7 +511,15 @@ public class JetTreeVisitor<D> extends JetVisitor<Void, D> {
@Override @Override
public Void visitThisExpression(JetThisExpression expression, D data) { public Void visitThisExpression(JetThisExpression expression, D data) {
JetReferenceExpression thisReference = expression.getThisReference(); JetReferenceExpression thisReference = expression.getInstanceReference();
thisReference.accept(this, data);
visitLabelQualifiedExpression(expression, data);
return null;
}
@Override
public Void visitSuperExpression(JetSuperExpression expression, D data) {
JetReferenceExpression thisReference = expression.getInstanceReference();
thisReference.accept(this, data); thisReference.accept(this, data);
JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier(); JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier();
if (superTypeQualifier != null) { if (superTypeQualifier != null) {
@@ -280,6 +280,10 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
return visitLabelQualifiedExpression(expression, data); return visitLabelQualifiedExpression(expression, data);
} }
public R visitSuperExpression(JetSuperExpression expression, D data) {
return visitLabelQualifiedExpression(expression, data);
}
public R visitParenthesizedExpression(JetParenthesizedExpression expression, D data) { public R visitParenthesizedExpression(JetParenthesizedExpression expression, D data) {
return visitExpression(expression, data); return visitExpression(expression, data);
} }
@@ -419,4 +423,5 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
public R visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry, D data) { public R visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry, D data) {
return visitStringTemplateEntry(entry, data); return visitStringTemplateEntry(entry, data);
} }
} }
@@ -278,6 +278,10 @@ public class JetVisitorVoid extends PsiElementVisitor {
visitLabelQualifiedExpression(expression); visitLabelQualifiedExpression(expression);
} }
public void visitSuperExpression(JetSuperExpression expression) {
visitLabelQualifiedExpression(expression);
}
public void visitParenthesizedExpression(JetParenthesizedExpression expression) { public void visitParenthesizedExpression(JetParenthesizedExpression expression) {
visitExpression(expression); visitExpression(expression);
} }
@@ -65,11 +65,6 @@ public abstract class AbstractScopeAdapter implements JetScope {
return getWorkerScope().getPropertyByFieldReference(fieldName); return getWorkerScope().getPropertyByFieldReference(fieldName);
} }
@Override
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
return getWorkerScope().getDeclarationDescriptorForUnqualifiedThis();
}
@NotNull @NotNull
@Override @Override
public Collection<DeclarationDescriptor> getAllDescriptors() { public Collection<DeclarationDescriptor> getAllDescriptors() {
@@ -234,7 +234,7 @@ public class TypeResolver {
} }
@Nullable @Nullable
public ClassifierDescriptor resolveClass(JetScope scope, JetUserType userType) { private ClassifierDescriptor resolveClass(JetScope scope, JetUserType userType) {
ClassifierDescriptor classifierDescriptor = resolveClassWithoutErrorReporting(scope, userType); ClassifierDescriptor classifierDescriptor = resolveClassWithoutErrorReporting(scope, userType);
if (classifierDescriptor == null) { if (classifierDescriptor == null) {
@@ -86,7 +86,7 @@ public class DataFlowValueFactory {
} }
else if (expression instanceof JetThisExpression) { else if (expression instanceof JetThisExpression) {
JetThisExpression thisExpression = (JetThisExpression) expression; JetThisExpression thisExpression = (JetThisExpression) expression;
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, thisExpression.getThisReference()); DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, thisExpression.getInstanceReference());
if (declarationDescriptor instanceof CallableDescriptor) { if (declarationDescriptor instanceof CallableDescriptor) {
return Pair.create((Object) ((CallableDescriptor) declarationDescriptor).getReceiverParameter(), true); return Pair.create((Object) ((CallableDescriptor) declarationDescriptor).getReceiverParameter(), true);
} }
@@ -3,7 +3,6 @@ package org.jetbrains.jet.lang.resolve.scopes;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import java.util.Collection; import java.util.Collection;
@@ -109,21 +108,6 @@ public class ChainedScope implements JetScope {
return null; return null;
} }
@Override
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
if (DescriptorUtils.definesItsOwnThis(getContainingDeclaration())) {
return getContainingDeclaration();
}
for (JetScope jetScope : scopeChain) {
DeclarationDescriptor containingDeclaration = jetScope.getContainingDeclaration();
if (DescriptorUtils.definesItsOwnThis(containingDeclaration)) {
return containingDeclaration;
}
}
return null;
}
@NotNull @NotNull
@Override @Override
public Collection<DeclarationDescriptor> getAllDescriptors() { public Collection<DeclarationDescriptor> getAllDescriptors() {
@@ -17,7 +17,7 @@ public interface JetScope {
@NotNull @NotNull
@Override @Override
public DeclarationDescriptor getContainingDeclaration() { public DeclarationDescriptor getContainingDeclaration() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException("Don't take containing declaration of the EMPTY scope");
} }
@Override @Override
@@ -51,9 +51,6 @@ public interface JetScope {
@Nullable @Nullable
PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName); PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName);
@Nullable
DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis();
@NotNull @NotNull
Collection<DeclarationDescriptor> getAllDescriptors(); Collection<DeclarationDescriptor> getAllDescriptors();
@@ -51,11 +51,6 @@ public abstract class JetScopeImpl implements JetScope {
return null; return null;
} }
@Override
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
return null;
}
@NotNull @NotNull
@Override @Override
public Collection<DeclarationDescriptor> getAllDescriptors() { public Collection<DeclarationDescriptor> getAllDescriptors() {
@@ -109,12 +109,6 @@ public class SubstitutingScope implements JetScope {
throw new UnsupportedOperationException(); // TODO throw new UnsupportedOperationException(); // TODO
} }
@Override
@Nullable
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
return workerScope.getDeclarationDescriptorForUnqualifiedThis();
}
@NotNull @NotNull
@Override @Override
public Collection<DeclarationDescriptor> getAllDescriptors() { public Collection<DeclarationDescriptor> getAllDescriptors() {
@@ -1,10 +1,12 @@
package org.jetbrains.jet.lang.resolve.scopes; package org.jetbrains.jet.lang.resolve.scopes;
import com.google.common.collect.*; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
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.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.util.CommonSuppliers; import org.jetbrains.jet.util.CommonSuppliers;
@@ -51,14 +53,6 @@ public class WritableScopeImpl extends WritableScopeWithImports {
return ownerDeclarationDescriptor; return ownerDeclarationDescriptor;
} }
@Override
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
if (DescriptorUtils.definesItsOwnThis(ownerDeclarationDescriptor)) {
return ownerDeclarationDescriptor;
}
return super.getDeclarationDescriptorForUnqualifiedThis();
}
@Override @Override
public void importScope(@NotNull JetScope imported) { public void importScope(@NotNull JetScope imported) {
super.importScope(imported); super.importScope(imported);
@@ -64,11 +64,6 @@ public class ErrorUtils {
return null; // TODO : review return null; // TODO : review
} }
@Override
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
return ERROR_CLASS; // TODO : review
}
@NotNull @NotNull
@Override @Override
public Collection<DeclarationDescriptor> getAllDescriptors() { public Collection<DeclarationDescriptor> getAllDescriptors() {
@@ -15,8 +15,10 @@ import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
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.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ThisReceiverDescriptor;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
@@ -277,62 +279,101 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@Override @Override
public JetType visitThisExpression(JetThisExpression expression, ExpressionTypingContext context) { public JetType visitThisExpression(JetThisExpression expression, ExpressionTypingContext context) {
JetType result = null; JetType result = null;
ReceiverDescriptor thisReceiver = null; ReceiverDescriptor thisReceiver = resolveToReceiver(expression, context, false);
String labelName = expression.getLabelName();
if (labelName != null) {
thisReceiver = context.labelResolver.resolveThisLabel(expression, context, thisReceiver, labelName);
}
else {
thisReceiver = context.scope.getImplicitReceiver();
DeclarationDescriptor declarationDescriptorForUnqualifiedThis = context.scope.getDeclarationDescriptorForUnqualifiedThis();
if (declarationDescriptorForUnqualifiedThis != null) {
context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptorForUnqualifiedThis);
}
}
if (thisReceiver != null) { if (thisReceiver != null) {
if (!thisReceiver.exists()) { if (!thisReceiver.exists()) {
context.trace.report(NO_THIS.on(expression)); context.trace.report(NO_THIS.on(expression));
} }
else { else {
JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier(); result = thisReceiver.getType();
if (superTypeQualifier != null) { context.trace.record(BindingContext.EXPRESSION_TYPE, expression.getInstanceReference(), result);
JetTypeElement superTypeElement = superTypeQualifier.getTypeElement();
// Errors are reported by the parser
if (superTypeElement instanceof JetUserType) {
JetUserType typeElement = (JetUserType) superTypeElement;
ClassifierDescriptor classifierCandidate = context.getTypeResolver().resolveClass(context.scope, typeElement);
if (classifierCandidate instanceof ClassDescriptor) {
ClassDescriptor superclass = (ClassDescriptor) classifierCandidate;
JetType thisType = thisReceiver.getType();
Collection<? extends JetType> supertypes = thisType.getConstructor().getSupertypes();
TypeSubstitutor substitutor = TypeSubstitutor.create(thisType);
for (JetType declaredSupertype : supertypes) {
if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) {
result = substitutor.safeSubstitute(declaredSupertype, Variance.INVARIANT);
break;
}
}
if (result == null) {
context.trace.report(NOT_A_SUPERTYPE.on(superTypeElement));
}
}
}
}
else {
result = thisReceiver.getType();
}
if (result != null) {
context.trace.record(BindingContext.EXPRESSION_TYPE, expression.getThisReference(), result);
}
} }
} }
return DataFlowUtils.checkType(result, expression, context); return DataFlowUtils.checkType(result, expression, context);
} }
@Override
public JetType visitSuperExpression(JetSuperExpression expression, ExpressionTypingContext context) {
if (!context.namespacesAllowed) {
context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(expression, expression.getText()));
return null;
}
JetType result = null;
ReceiverDescriptor thisReceiver = resolveToReceiver(expression, context, true);
if (thisReceiver == null) return null;
if (!thisReceiver.exists()) {
context.trace.report(SUPER_NOT_AVAILABLE.on(expression));
}
else {
JetType thisType = thisReceiver.getType();
Collection<? extends JetType> supertypes = thisType.getConstructor().getSupertypes();
TypeSubstitutor substitutor = TypeSubstitutor.create(thisType);
JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier();
if (superTypeQualifier != null) {
JetType supertype = context.getTypeResolver().resolveType(context.scope, superTypeQualifier);
DeclarationDescriptor classifierCandidate = supertype.getConstructor().getDeclarationDescriptor();
if (classifierCandidate instanceof ClassDescriptor) {
ClassDescriptor superclass = (ClassDescriptor) classifierCandidate;
for (JetType declaredSupertype : supertypes) {
if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) {
result = substitutor.safeSubstitute(declaredSupertype, Variance.INVARIANT);
break;
}
}
}
if (result == null && !ErrorUtils.isErrorType(supertype)) {
context.trace.report(NOT_A_SUPERTYPE.on(superTypeQualifier));
}
}
else {
if (supertypes.size() > 1) {
context.trace.report(AMBIGUOUS_SUPER.on(expression));
}
else {
result = substitutor.substitute(supertypes.iterator().next(), Variance.INVARIANT);
}
}
if (result != null) {
context.trace.record(BindingContext.EXPRESSION_TYPE, expression.getInstanceReference(), result);
context.trace.record(BindingContext.REFERENCE_TARGET, expression.getInstanceReference(), result.getConstructor().getDeclarationDescriptor());
}
}
return DataFlowUtils.checkType(result, expression, context);
}
@Nullable
private ReceiverDescriptor resolveToReceiver(JetLabelQualifiedInstanceExpression expression, ExpressionTypingContext context, boolean onlyClassReceivers) {
ReceiverDescriptor thisReceiver = null;
String labelName = expression.getLabelName();
if (labelName != null) {
thisReceiver = context.labelResolver.resolveThisLabel(expression.getInstanceReference(), expression.getTargetLabel(), context, thisReceiver, labelName);
}
else {
if (onlyClassReceivers) {
List<ReceiverDescriptor> receivers = Lists.newArrayList();
context.scope.getImplicitReceiversHierarchy(receivers);
for (ReceiverDescriptor receiver : receivers) {
if (receiver instanceof ClassReceiver) {
thisReceiver = receiver;
break;
}
}
}
else {
thisReceiver = context.scope.getImplicitReceiver();
}
if (thisReceiver instanceof ThisReceiverDescriptor) {
context.trace.record(REFERENCE_TARGET, expression.getInstanceReference(), ((ThisReceiverDescriptor) thisReceiver).getDeclarationDescriptor());
}
}
return thisReceiver;
}
@Override @Override
public JetType visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context) { public JetType visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context) {
return context.getServices().getBlockReturnedType(context.scope, expression, CoercionStrategy.NO_COERCION, context); return context.getServices().getBlockReturnedType(context.scope, expression, CoercionStrategy.NO_COERCION, context);
@@ -65,6 +65,7 @@ import java.util.Map;
public final Map<JetPattern, List<VariableDescriptor>> patternsToBoundVariableLists; public final Map<JetPattern, List<VariableDescriptor>> patternsToBoundVariableLists;
public final LabelResolver labelResolver; public final LabelResolver labelResolver;
// true for positions on the lhs of a '.', i.e. allows namespace results and 'super'
public final boolean namespacesAllowed; public final boolean namespacesAllowed;
private CallResolver callResolver; private CallResolver callResolver;
@@ -106,10 +106,9 @@ public class LabelResolver {
return result; return result;
} }
public ReceiverDescriptor resolveThisLabel(JetThisExpression expression, ExpressionTypingContext context, ReceiverDescriptor thisReceiver, String labelName) { public ReceiverDescriptor resolveThisLabel(JetReferenceExpression thisReference, JetSimpleNameExpression targetLabel, ExpressionTypingContext context, ReceiverDescriptor thisReceiver, String labelName) {
Collection<DeclarationDescriptor> declarationsByLabel = context.scope.getDeclarationsByLabel(labelName); Collection<DeclarationDescriptor> declarationsByLabel = context.scope.getDeclarationsByLabel(labelName);
int size = declarationsByLabel.size(); int size = declarationsByLabel.size();
final JetSimpleNameExpression targetLabel = expression.getTargetLabel();
assert targetLabel != null; assert targetLabel != null;
if (size == 1) { if (size == 1) {
DeclarationDescriptor declarationDescriptor = declarationsByLabel.iterator().next(); DeclarationDescriptor declarationDescriptor = declarationsByLabel.iterator().next();
@@ -127,7 +126,7 @@ public class LabelResolver {
PsiElement element = context.trace.get(DESCRIPTOR_TO_DECLARATION, declarationDescriptor); PsiElement element = context.trace.get(DESCRIPTOR_TO_DECLARATION, declarationDescriptor);
assert element != null; assert element != null;
context.trace.record(LABEL_TARGET, targetLabel, element); context.trace.record(LABEL_TARGET, targetLabel, element);
context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptor); context.trace.record(REFERENCE_TARGET, thisReference, declarationDescriptor);
} }
else if (size == 0) { else if (size == 0) {
JetElement element = resolveNamedLabel(labelName, targetLabel, false, context); JetElement element = resolveNamedLabel(labelName, targetLabel, false, context);
@@ -137,7 +136,7 @@ public class LabelResolver {
thisReceiver = ((FunctionDescriptor) declarationDescriptor).getReceiverParameter(); thisReceiver = ((FunctionDescriptor) declarationDescriptor).getReceiverParameter();
if (thisReceiver.exists()) { if (thisReceiver.exists()) {
context.trace.record(LABEL_TARGET, targetLabel, element); context.trace.record(LABEL_TARGET, targetLabel, element);
context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptor); context.trace.record(REFERENCE_TARGET, thisReference, declarationDescriptor);
} }
} }
else { else {
@@ -168,6 +168,7 @@ LONG_TEMPLATE_ENTRY_END=\}
"trait" { return JetTokens.TRAIT_KEYWORD ;} "trait" { return JetTokens.TRAIT_KEYWORD ;}
"throw" { return JetTokens.THROW_KEYWORD ;} "throw" { return JetTokens.THROW_KEYWORD ;}
"false" { return JetTokens.FALSE_KEYWORD ;} "false" { return JetTokens.FALSE_KEYWORD ;}
"super" { return JetTokens.SUPER_KEYWORD ;}
"when" { return JetTokens.WHEN_KEYWORD ;} "when" { return JetTokens.WHEN_KEYWORD ;}
"true" { return JetTokens.TRUE_KEYWORD ;} "true" { return JetTokens.TRUE_KEYWORD ;}
"type" { return JetTokens.TYPE_KEYWORD ;} "type" { return JetTokens.TYPE_KEYWORD ;}
@@ -36,6 +36,7 @@ public interface JetTokens {
JetKeywordToken TYPE_KEYWORD = JetKeywordToken.keyword("type"); JetKeywordToken TYPE_KEYWORD = JetKeywordToken.keyword("type");
JetKeywordToken CLASS_KEYWORD = JetKeywordToken.keyword("class"); JetKeywordToken CLASS_KEYWORD = JetKeywordToken.keyword("class");
JetKeywordToken THIS_KEYWORD = JetKeywordToken.keyword("this"); JetKeywordToken THIS_KEYWORD = JetKeywordToken.keyword("this");
JetKeywordToken SUPER_KEYWORD = JetKeywordToken.keyword("super");
JetKeywordToken VAL_KEYWORD = JetKeywordToken.keyword("val"); JetKeywordToken VAL_KEYWORD = JetKeywordToken.keyword("val");
JetKeywordToken VAR_KEYWORD = JetKeywordToken.keyword("var"); JetKeywordToken VAR_KEYWORD = JetKeywordToken.keyword("var");
JetKeywordToken FUN_KEYWORD = JetKeywordToken.keyword("fun"); JetKeywordToken FUN_KEYWORD = JetKeywordToken.keyword("fun");
@@ -145,7 +146,7 @@ public interface JetTokens {
JetKeywordToken REF_KEYWORD = JetKeywordToken.softKeyword("ref"); JetKeywordToken REF_KEYWORD = JetKeywordToken.softKeyword("ref");
TokenSet KEYWORDS = TokenSet.create(NAMESPACE_KEYWORD, AS_KEYWORD, TYPE_KEYWORD, CLASS_KEYWORD, TRAIT_KEYWORD, TokenSet KEYWORDS = TokenSet.create(NAMESPACE_KEYWORD, AS_KEYWORD, TYPE_KEYWORD, CLASS_KEYWORD, TRAIT_KEYWORD,
THIS_KEYWORD, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, FOR_KEYWORD, THIS_KEYWORD, SUPER_KEYWORD, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, FOR_KEYWORD,
NULL_KEYWORD, NULL_KEYWORD,
TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD, TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD,
IN_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD, CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD, IN_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD, CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD,
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -19,7 +19,7 @@ internal class Example<X, T : Comparable<X>>(protected val x : Foo<X, T>, y : So
class class
: modifiers ("class" | "trait") SimpleName : modifiers ("class" | "trait") SimpleName
typeParameters? typeParameters?
modifiers ("(" primaryConstructorParameter{","} ")")? modifiers ("(" functionParameter{","} ")")?
(":" annotations delegationSpecifier{","})? (":" annotations delegationSpecifier{","})?
typeConstraints typeConstraints
(classBody? | enumClassBody) (classBody? | enumClassBody)
+4 -3
View File
@@ -16,7 +16,7 @@ h3. Precedence
| |Elvis|{{?:}} | | |Elvis|{{?:}} |
| |Named checks|{{in}}, {{\!in}}, {{is}}, {{\!is}} | | |Named checks|{{in}}, {{\!in}}, {{is}}, {{\!is}} |
| |Comparison|{{<}}, {{>}}, {{<=}}, {{>=}} | | |Comparison|{{<}}, {{>}}, {{<=}}, {{>=}} |
| |Equality|{{==}}, {{\!==}}, {{===}}, {{\!===}} | | |Equality|{{==}}, {{\!==}}|
| |Conjunction|{{&&}}| | |Conjunction|{{&&}}|
| |Disjunction|{{\|\|}}| | |Disjunction|{{\|\|}}|
| |Arrow|{{\->}}| | |Arrow|{{\->}}|
@@ -113,7 +113,8 @@ atomicExpression
: literalConstant : literalConstant
: functionLiteral : functionLiteral
: tupleLiteral : tupleLiteral
: "this" label? ("<" type ">")? : "this" label?
: "super" ("<" type ">")? label?
: if : if
: when : when
: try : try
@@ -184,7 +185,7 @@ comparisonOperation
; ;
equalityOperation equalityOperation
: "!=" : "==" : "===" : "!==" : "!=" : "=="
; ;
assignmentOperator assignmentOperator
@@ -0,0 +1,49 @@
namespace example;
trait T {
fun foo() {}
}
open class C() {
fun bar() {}
}
class A<E>() : C(), T {
fun test() {
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>
<!SUPER_IS_NOT_AN_EXPRESSION!>super<T><!>
<!AMBIGUOUS_SUPER!>super<!>.foo()
super<T>.foo()
super<C>.bar()
super<T>@A.foo()
super<C>@A.bar()
super<<!NOT_A_SUPERTYPE!>E<!>>.bar()
super<<!NOT_A_SUPERTYPE!>E<!>>@A.bar()
super<<!NOT_A_SUPERTYPE!>Int<!>>.foo()
super<>.foo()
super<<!NOT_A_SUPERTYPE!>fun() : Unit<!>>.foo()
super<<!NOT_A_SUPERTYPE!>()<!>>.foo()
super<T><!UNRESOLVED_REFERENCE!>@B<!>.foo()
super<C><!UNRESOLVED_REFERENCE!>@B<!>.bar()
}
class B : T {
fun test() {
super<T>.foo();
super<<!NOT_A_SUPERTYPE!>C<!>>.bar()
super<C>@A.bar()
super<T>@A.foo()
super<T>@B.foo()
super<<!NOT_A_SUPERTYPE!>C<!>>@B.foo()
super.foo()
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>
<!SUPER_IS_NOT_AN_EXPRESSION!>super<T><!>
}
}
}
fun foo() {
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>
super.foo()
super<Nothing>.foo()
}
+4 -4
View File
@@ -53,8 +53,8 @@ fun foo() {
this@a this@a
this@@ this@@
this<A> super<A>
this@<A> super<A>@
this@a<A> super<A>@a
this@@<A> super<A>@@
} }
+18 -18
View File
@@ -412,9 +412,9 @@ JetFile: Labels.jet
LABEL_REFERENCE LABEL_REFERENCE
PsiElement(ATAT)('@@') PsiElement(ATAT)('@@')
PsiWhiteSpace('\n\n ') PsiWhiteSpace('\n\n ')
THIS_EXPRESSION SUPER_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(this)('this') PsiElement(super)('super')
PsiElement(LT)('<') PsiElement(LT)('<')
TYPE_REFERENCE TYPE_REFERENCE
USER_TYPE USER_TYPE
@@ -422,43 +422,43 @@ JetFile: Labels.jet
PsiElement(IDENTIFIER)('A') PsiElement(IDENTIFIER)('A')
PsiElement(GT)('>') PsiElement(GT)('>')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
THIS_EXPRESSION SUPER_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(this)('this') PsiElement(super)('super')
PsiElement(LT)('<')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('A')
PsiElement(GT)('>')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL_REFERENCE LABEL_REFERENCE
PsiElement(AT)('@') PsiElement(AT)('@')
PsiWhiteSpace('\n ')
SUPER_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(super)('super')
PsiElement(LT)('<') PsiElement(LT)('<')
TYPE_REFERENCE TYPE_REFERENCE
USER_TYPE USER_TYPE
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('A') PsiElement(IDENTIFIER)('A')
PsiElement(GT)('>') PsiElement(GT)('>')
PsiWhiteSpace('\n ')
THIS_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(this)('this')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL_REFERENCE LABEL_REFERENCE
PsiElement(LABEL_IDENTIFIER)('@a') PsiElement(LABEL_IDENTIFIER)('@a')
PsiWhiteSpace('\n ')
SUPER_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(super)('super')
PsiElement(LT)('<') PsiElement(LT)('<')
TYPE_REFERENCE TYPE_REFERENCE
USER_TYPE USER_TYPE
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('A') PsiElement(IDENTIFIER)('A')
PsiElement(GT)('>') PsiElement(GT)('>')
PsiWhiteSpace('\n ')
THIS_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(this)('this')
LABEL_QUALIFIER LABEL_QUALIFIER
LABEL_REFERENCE LABEL_REFERENCE
PsiElement(ATAT)('@@') PsiElement(ATAT)('@@')
PsiElement(LT)('<')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('A')
PsiElement(GT)('>')
PsiWhiteSpace('\n') PsiWhiteSpace('\n')
PsiElement(RBRACE)('}') PsiElement(RBRACE)('}')
+1 -1
View File
@@ -15,7 +15,7 @@ fun a(
a : foo = false, a : foo = false,
a : foo = null, a : foo = null,
a : foo = this, a : foo = this,
a : foo = this<sdf>, a : foo = super<sdf>,
a : foo = (10), a : foo = (10),
a : foo = (10, "A", 0xf), a : foo = (10, "A", 0xf),
a : foo = Foo(bar), a : foo = Foo(bar),
+2 -2
View File
@@ -280,9 +280,9 @@ JetFile: SimpleExpressions.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(EQ)('=') PsiElement(EQ)('=')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
THIS_EXPRESSION SUPER_EXPRESSION
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(this)('this') PsiElement(super)('super')
PsiElement(LT)('<') PsiElement(LT)('<')
TYPE_REFERENCE TYPE_REFERENCE
USER_TYPE USER_TYPE
+7
View File
@@ -0,0 +1,7 @@
// KT-156 Fix the this<Super> syntax
fun foo() {
super.foo();
super<Int>.foo();
super<>.foo();
super<Int>@label.foo();
}
+88
View File
@@ -0,0 +1,88 @@
JetFile: Super.jet
PsiComment(EOL_COMMENT)('// KT-156 Fix the this<Super> syntax')
PsiWhiteSpace('\n')
NAMESPACE
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
SUPER_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(super)('super')
PsiElement(DOT)('.')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(SEMICOLON)(';')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
SUPER_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(super)('super')
PsiElement(LT)('<')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiElement(GT)('>')
PsiElement(DOT)('.')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(SEMICOLON)(';')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
SUPER_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(super)('super')
PsiElement(LT)('<')
TYPE_REFERENCE
PsiErrorElement:Type expected
<empty list>
PsiElement(GT)('>')
PsiElement(DOT)('.')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(SEMICOLON)(';')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
SUPER_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(super)('super')
PsiElement(LT)('<')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiElement(GT)('>')
LABEL_QUALIFIER
LABEL_REFERENCE
PsiElement(LABEL_IDENTIFIER)('@label')
PsiElement(DOT)('.')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(SEMICOLON)(';')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
+26
View File
@@ -0,0 +1,26 @@
~T~trait T {
fun foo() {}
}
~C~open class C() {
fun bar() {}
}
~A~class A<E>() : C(), T {
fun test() {
`T`super<T>.foo()
`C`super<C>.bar()
`T`super<T>@A.foo()
`C`super<C>@A.bar()
}
class B : T {
fun test() {
`T`super<T>.foo();
`C`super<C>@A.bar()
`T`super<T>@A.foo()
`T`super<T>@B.foo()
`T`super.foo()
}
}
}
@@ -310,7 +310,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
public void testThis() throws Exception { public void testThis() throws Exception {
assertType("Derived_T<Int>", "this", "Derived_T<Int>"); assertType("Derived_T<Int>", "this", "Derived_T<Int>");
assertType("Derived_T<Int>", "this<Base_T>", "Base_T<Int>"); assertType("Derived_T<Int>", "super<Base_T>", "Base_T<Int>");
} }
public void testLoops() throws Exception { public void testLoops() throws Exception {