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:
@@ -1988,7 +1988,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
|
||||
@Override
|
||||
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) {
|
||||
return generateThisOrOuter((ClassDescriptor) descriptor);
|
||||
}
|
||||
|
||||
-5
@@ -51,11 +51,6 @@ public class JavaClassMembersScope implements JetScope {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassifierDescriptor getClassifier(@NotNull String name) {
|
||||
ClassifierDescriptor classifierDescriptor = classifiers.get(name);
|
||||
|
||||
@@ -109,6 +109,7 @@ public interface JetNodeTypes {
|
||||
JetNodeType LABEL_QUALIFIER = new JetNodeType("LABEL_QUALIFIER", JetContainerNode.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_WITH_TYPE = new JetNodeType("BINARY_WITH_TYPE", JetBinaryExpressionWithTypeRHS.class);
|
||||
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 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 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 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 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");
|
||||
|
||||
@@ -49,6 +49,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
LPAR, // tuple
|
||||
|
||||
THIS_KEYWORD, // this
|
||||
SUPER_KEYWORD, // super
|
||||
|
||||
IF_KEYWORD, // if
|
||||
WHEN_KEYWORD, // when
|
||||
@@ -464,7 +465,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
/*
|
||||
* atomicExpression
|
||||
* : tupleLiteral // or parenthesized element
|
||||
* : "this" getEntryPoint? ("<" type ">")?
|
||||
* : "this" label?
|
||||
* : "super" ("<" type ">")? label?
|
||||
* : objectLiteral
|
||||
* : jump
|
||||
* : if
|
||||
@@ -490,6 +492,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
else if (at(THIS_KEYWORD)) {
|
||||
parseThisExpression();
|
||||
}
|
||||
else if (at(SUPER_KEYWORD)) {
|
||||
parseSuperExpression();
|
||||
}
|
||||
else if (at(OBJECT_KEYWORD)) {
|
||||
parseObjectLiteral();
|
||||
}
|
||||
@@ -1593,7 +1598,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
/*
|
||||
* "this" getEntryPoint? ("<" type ">")?
|
||||
* "this" label?
|
||||
*/
|
||||
private void parseThisExpression() {
|
||||
assert _at(THIS_KEYWORD);
|
||||
@@ -1605,8 +1610,22 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
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)) {
|
||||
// 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();
|
||||
|
||||
myBuilder.disableNewlines();
|
||||
@@ -1623,7 +1642,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
}
|
||||
myBuilder.restoreNewlinesState();
|
||||
}
|
||||
mark.done(THIS_EXPRESSION);
|
||||
parseLabel();
|
||||
|
||||
mark.done(SUPER_EXPRESSION);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+20
@@ -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.Nullable;
|
||||
import org.jetbrains.jet.lang.parsing.JetExpressionParsing;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
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) {
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class JetThisExpression extends JetLabelQualifiedExpression {
|
||||
public class JetThisExpression extends JetLabelQualifiedInstanceExpression {
|
||||
|
||||
public JetThisExpression(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
@@ -23,23 +21,4 @@ public class JetThisExpression extends JetLabelQualifiedExpression {
|
||||
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D 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
|
||||
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);
|
||||
JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier();
|
||||
if (superTypeQualifier != null) {
|
||||
|
||||
@@ -280,6 +280,10 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
|
||||
return visitLabelQualifiedExpression(expression, data);
|
||||
}
|
||||
|
||||
public R visitSuperExpression(JetSuperExpression expression, D data) {
|
||||
return visitLabelQualifiedExpression(expression, data);
|
||||
}
|
||||
|
||||
public R visitParenthesizedExpression(JetParenthesizedExpression expression, D data) {
|
||||
return visitExpression(expression, data);
|
||||
}
|
||||
@@ -419,4 +423,5 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
|
||||
public R visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry, D data) {
|
||||
return visitStringTemplateEntry(entry, data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -278,6 +278,10 @@ public class JetVisitorVoid extends PsiElementVisitor {
|
||||
visitLabelQualifiedExpression(expression);
|
||||
}
|
||||
|
||||
public void visitSuperExpression(JetSuperExpression expression) {
|
||||
visitLabelQualifiedExpression(expression);
|
||||
}
|
||||
|
||||
public void visitParenthesizedExpression(JetParenthesizedExpression expression) {
|
||||
visitExpression(expression);
|
||||
}
|
||||
|
||||
@@ -65,11 +65,6 @@ public abstract class AbstractScopeAdapter implements JetScope {
|
||||
return getWorkerScope().getPropertyByFieldReference(fieldName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
|
||||
return getWorkerScope().getDeclarationDescriptorForUnqualifiedThis();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
|
||||
@@ -234,7 +234,7 @@ public class TypeResolver {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ClassifierDescriptor resolveClass(JetScope scope, JetUserType userType) {
|
||||
private ClassifierDescriptor resolveClass(JetScope scope, JetUserType userType) {
|
||||
ClassifierDescriptor classifierDescriptor = resolveClassWithoutErrorReporting(scope, userType);
|
||||
|
||||
if (classifierDescriptor == null) {
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public class DataFlowValueFactory {
|
||||
}
|
||||
else if (expression instanceof JetThisExpression) {
|
||||
JetThisExpression thisExpression = (JetThisExpression) expression;
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, thisExpression.getThisReference());
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, thisExpression.getInstanceReference());
|
||||
if (declarationDescriptor instanceof CallableDescriptor) {
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -109,21 +108,6 @@ public class ChainedScope implements JetScope {
|
||||
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
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
|
||||
@@ -17,7 +17,7 @@ public interface JetScope {
|
||||
@NotNull
|
||||
@Override
|
||||
public DeclarationDescriptor getContainingDeclaration() {
|
||||
throw new UnsupportedOperationException();
|
||||
throw new UnsupportedOperationException("Don't take containing declaration of the EMPTY scope");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,9 +51,6 @@ public interface JetScope {
|
||||
@Nullable
|
||||
PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName);
|
||||
|
||||
@Nullable
|
||||
DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis();
|
||||
|
||||
@NotNull
|
||||
Collection<DeclarationDescriptor> getAllDescriptors();
|
||||
|
||||
|
||||
@@ -51,11 +51,6 @@ public abstract class JetScopeImpl implements JetScope {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
|
||||
@@ -109,12 +109,6 @@ public class SubstitutingScope implements JetScope {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
|
||||
return workerScope.getDeclarationDescriptorForUnqualifiedThis();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
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.Nullable;
|
||||
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.util.CommonSuppliers;
|
||||
|
||||
@@ -51,14 +53,6 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
return ownerDeclarationDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
|
||||
if (DescriptorUtils.definesItsOwnThis(ownerDeclarationDescriptor)) {
|
||||
return ownerDeclarationDescriptor;
|
||||
}
|
||||
return super.getDeclarationDescriptorForUnqualifiedThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importScope(@NotNull JetScope imported) {
|
||||
super.importScope(imported);
|
||||
|
||||
@@ -64,11 +64,6 @@ public class ErrorUtils {
|
||||
return null; // TODO : review
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeclarationDescriptor getDeclarationDescriptorForUnqualifiedThis() {
|
||||
return ERROR_CLASS; // TODO : review
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
|
||||
+86
-45
@@ -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.scopes.JetScope;
|
||||
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.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ThisReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
@@ -277,62 +279,101 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
@Override
|
||||
public JetType visitThisExpression(JetThisExpression expression, ExpressionTypingContext context) {
|
||||
JetType result = null;
|
||||
ReceiverDescriptor thisReceiver = null;
|
||||
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);
|
||||
}
|
||||
}
|
||||
ReceiverDescriptor thisReceiver = resolveToReceiver(expression, context, false);
|
||||
|
||||
if (thisReceiver != null) {
|
||||
if (!thisReceiver.exists()) {
|
||||
context.trace.report(NO_THIS.on(expression));
|
||||
}
|
||||
else {
|
||||
JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier();
|
||||
if (superTypeQualifier != null) {
|
||||
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);
|
||||
}
|
||||
result = thisReceiver.getType();
|
||||
context.trace.record(BindingContext.EXPRESSION_TYPE, expression.getInstanceReference(), result);
|
||||
}
|
||||
}
|
||||
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
|
||||
public JetType visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context) {
|
||||
return context.getServices().getBlockReturnedType(context.scope, expression, CoercionStrategy.NO_COERCION, context);
|
||||
|
||||
+1
@@ -65,6 +65,7 @@ import java.util.Map;
|
||||
public final Map<JetPattern, List<VariableDescriptor>> patternsToBoundVariableLists;
|
||||
public final LabelResolver labelResolver;
|
||||
|
||||
// true for positions on the lhs of a '.', i.e. allows namespace results and 'super'
|
||||
public final boolean namespacesAllowed;
|
||||
|
||||
private CallResolver callResolver;
|
||||
|
||||
@@ -106,10 +106,9 @@ public class LabelResolver {
|
||||
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);
|
||||
int size = declarationsByLabel.size();
|
||||
final JetSimpleNameExpression targetLabel = expression.getTargetLabel();
|
||||
assert targetLabel != null;
|
||||
if (size == 1) {
|
||||
DeclarationDescriptor declarationDescriptor = declarationsByLabel.iterator().next();
|
||||
@@ -127,7 +126,7 @@ public class LabelResolver {
|
||||
PsiElement element = context.trace.get(DESCRIPTOR_TO_DECLARATION, declarationDescriptor);
|
||||
assert element != null;
|
||||
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) {
|
||||
JetElement element = resolveNamedLabel(labelName, targetLabel, false, context);
|
||||
@@ -137,7 +136,7 @@ public class LabelResolver {
|
||||
thisReceiver = ((FunctionDescriptor) declarationDescriptor).getReceiverParameter();
|
||||
if (thisReceiver.exists()) {
|
||||
context.trace.record(LABEL_TARGET, targetLabel, element);
|
||||
context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptor);
|
||||
context.trace.record(REFERENCE_TARGET, thisReference, declarationDescriptor);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -168,6 +168,7 @@ LONG_TEMPLATE_ENTRY_END=\}
|
||||
"trait" { return JetTokens.TRAIT_KEYWORD ;}
|
||||
"throw" { return JetTokens.THROW_KEYWORD ;}
|
||||
"false" { return JetTokens.FALSE_KEYWORD ;}
|
||||
"super" { return JetTokens.SUPER_KEYWORD ;}
|
||||
"when" { return JetTokens.WHEN_KEYWORD ;}
|
||||
"true" { return JetTokens.TRUE_KEYWORD ;}
|
||||
"type" { return JetTokens.TYPE_KEYWORD ;}
|
||||
|
||||
@@ -36,6 +36,7 @@ public interface JetTokens {
|
||||
JetKeywordToken TYPE_KEYWORD = JetKeywordToken.keyword("type");
|
||||
JetKeywordToken CLASS_KEYWORD = JetKeywordToken.keyword("class");
|
||||
JetKeywordToken THIS_KEYWORD = JetKeywordToken.keyword("this");
|
||||
JetKeywordToken SUPER_KEYWORD = JetKeywordToken.keyword("super");
|
||||
JetKeywordToken VAL_KEYWORD = JetKeywordToken.keyword("val");
|
||||
JetKeywordToken VAR_KEYWORD = JetKeywordToken.keyword("var");
|
||||
JetKeywordToken FUN_KEYWORD = JetKeywordToken.keyword("fun");
|
||||
@@ -145,7 +146,7 @@ public interface JetTokens {
|
||||
JetKeywordToken REF_KEYWORD = JetKeywordToken.softKeyword("ref");
|
||||
|
||||
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,
|
||||
TRUE_KEYWORD, FALSE_KEYWORD, IS_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
@@ -19,7 +19,7 @@ internal class Example<X, T : Comparable<X>>(protected val x : Foo<X, T>, y : So
|
||||
class
|
||||
: modifiers ("class" | "trait") SimpleName
|
||||
typeParameters?
|
||||
modifiers ("(" primaryConstructorParameter{","} ")")?
|
||||
modifiers ("(" functionParameter{","} ")")?
|
||||
(":" annotations delegationSpecifier{","})?
|
||||
typeConstraints
|
||||
(classBody? | enumClassBody)
|
||||
|
||||
@@ -16,7 +16,7 @@ h3. Precedence
|
||||
| |Elvis|{{?:}} |
|
||||
| |Named checks|{{in}}, {{\!in}}, {{is}}, {{\!is}} |
|
||||
| |Comparison|{{<}}, {{>}}, {{<=}}, {{>=}} |
|
||||
| |Equality|{{==}}, {{\!==}}, {{===}}, {{\!===}} |
|
||||
| |Equality|{{==}}, {{\!==}}|
|
||||
| |Conjunction|{{&&}}|
|
||||
| |Disjunction|{{\|\|}}|
|
||||
| |Arrow|{{\->}}|
|
||||
@@ -113,7 +113,8 @@ atomicExpression
|
||||
: literalConstant
|
||||
: functionLiteral
|
||||
: tupleLiteral
|
||||
: "this" label? ("<" type ">")?
|
||||
: "this" label?
|
||||
: "super" ("<" type ">")? label?
|
||||
: if
|
||||
: when
|
||||
: try
|
||||
@@ -184,7 +185,7 @@ comparisonOperation
|
||||
;
|
||||
|
||||
equalityOperation
|
||||
: "!=" : "==" : "===" : "!=="
|
||||
: "!=" : "=="
|
||||
;
|
||||
|
||||
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()
|
||||
}
|
||||
@@ -53,8 +53,8 @@ fun foo() {
|
||||
this@a
|
||||
this@@
|
||||
|
||||
this<A>
|
||||
this@<A>
|
||||
this@a<A>
|
||||
this@@<A>
|
||||
super<A>
|
||||
super<A>@
|
||||
super<A>@a
|
||||
super<A>@@
|
||||
}
|
||||
@@ -412,9 +412,9 @@ JetFile: Labels.jet
|
||||
LABEL_REFERENCE
|
||||
PsiElement(ATAT)('@@')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
THIS_EXPRESSION
|
||||
SUPER_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(this)('this')
|
||||
PsiElement(super)('super')
|
||||
PsiElement(LT)('<')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
@@ -422,43 +422,43 @@ JetFile: Labels.jet
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace('\n ')
|
||||
THIS_EXPRESSION
|
||||
SUPER_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_REFERENCE
|
||||
PsiElement(AT)('@')
|
||||
PsiWhiteSpace('\n ')
|
||||
SUPER_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(super)('super')
|
||||
PsiElement(LT)('<')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace('\n ')
|
||||
THIS_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(this)('this')
|
||||
LABEL_QUALIFIER
|
||||
LABEL_REFERENCE
|
||||
PsiElement(LABEL_IDENTIFIER)('@a')
|
||||
PsiWhiteSpace('\n ')
|
||||
SUPER_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(super)('super')
|
||||
PsiElement(LT)('<')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace('\n ')
|
||||
THIS_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(this)('this')
|
||||
LABEL_QUALIFIER
|
||||
LABEL_REFERENCE
|
||||
PsiElement(ATAT)('@@')
|
||||
PsiElement(LT)('<')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -15,7 +15,7 @@ fun a(
|
||||
a : foo = false,
|
||||
a : foo = null,
|
||||
a : foo = this,
|
||||
a : foo = this<sdf>,
|
||||
a : foo = super<sdf>,
|
||||
a : foo = (10),
|
||||
a : foo = (10, "A", 0xf),
|
||||
a : foo = Foo(bar),
|
||||
|
||||
@@ -280,9 +280,9 @@ JetFile: SimpleExpressions.jet
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
THIS_EXPRESSION
|
||||
SUPER_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(this)('this')
|
||||
PsiElement(super)('super')
|
||||
PsiElement(LT)('<')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// KT-156 Fix the this<Super> syntax
|
||||
fun foo() {
|
||||
super.foo();
|
||||
super<Int>.foo();
|
||||
super<>.foo();
|
||||
super<Int>@label.foo();
|
||||
}
|
||||
@@ -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)('}')
|
||||
@@ -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 {
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user