JET-126 Put 'where'-clause after the declaration

This commit is contained in:
Andrey Breslav
2011-07-08 22:44:56 +04:00
parent addfc6a421
commit c2435f0f24
13 changed files with 154 additions and 126 deletions
+5 -1
View File
@@ -21,6 +21,7 @@ class
typeParameters?
("wraps" valueParameters? | modifiers valueParameters?)?
(":" annotations delegationSpecifier{","})?
typeConstraints
(classBody? | enumClassBody)
;
@@ -40,7 +41,6 @@ explicitDelegation
typeParameters
: "<" typeParameter{","} ">"
("where" typeConstraint{","})?
;
typeParameter
@@ -51,6 +51,10 @@ typeParameter
bq. See [Generic classes|Generics#Generic classes]
*/
typeConstraints
: ("where" typeConstraint{","})?
;
typeConstraint
: annotations SimpleName ":" type
: annotations "class" "object" SimpleName ":" type
+2
View File
@@ -83,6 +83,7 @@ function
(type "." | annotations/*for receiver type*/)?
SimpleName
typeParameters? valueParameters (":" type)?
typeConstraints
functionBody?
;
@@ -95,6 +96,7 @@ property
: modifiers ("val" | "var")
typeParameters? (type "." | annotations)?
SimpleName (":" type)?
typeConstraints
("=" expression SEMI?)?
(getter? setter? | setter? getter?) SEMI?
;
+1 -1
View File
@@ -9,5 +9,5 @@ enumClassBody
;
enumEntry
: modifiers SimpleName typeParameters? valueParameters? (":" initializer{","})? classBody?
: modifiers SimpleName typeParameters? valueParameters? (":" initializer{","})? typeConstraints classBody?
;
+1 -1
View File
@@ -53,5 +53,5 @@ bq. See [Namespaces]
[undocumented]
typedef
: modifiers "type" SimpleName typeParameters? "=" type
: modifiers "type" SimpleName (typeParameters typeConstraints)? "=" type
;
+2 -2
View File
@@ -36,8 +36,8 @@ pattern
decomposerPattern
: type
// TODO : typeParameters will be consumed by the expression
: elvisExpression typeParameters? "@" tuplePattern
// TODO : typeArguments will be consumed by the expression
: elvisExpression typeArguments? "@" tuplePattern
;
constantPattern
@@ -384,6 +384,7 @@ public class JetParsing extends AbstractJetParsing {
* ("wraps" "(" primaryConstructorParameter{","} ")") |
* (modifiers "(" primaryConstructorParameter{","} ")"))?
* (":" attributes delegationSpecifier{","})?
* typeConstraints
* (classBody? | enumClassBody)
* ;
*/
@@ -392,7 +393,7 @@ public class JetParsing extends AbstractJetParsing {
advance(); // CLASS_KEYWORD
expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET);
parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
if (at(WRAPS_KEYWORD)) {
advance(); // WRAPS_KEYWORD
@@ -414,6 +415,8 @@ public class JetParsing extends AbstractJetParsing {
parseDelegationSpecifierList();
}
parseTypeConstraintsGuarded(typeParametersDeclared);
if (at(LBRACE)) {
if (enumClass) {
parseEnumClassBody();
@@ -473,7 +476,7 @@ public class JetParsing extends AbstractJetParsing {
/*
* enumEntry
* : modifiers SimpleName typeParameters? primaryConstructorParameters? (":" initializer{","})? classBody?
* : modifiers SimpleName typeParameters? primaryConstructorParameters? (":" initializer{","})? typeConstraints classBody?
* ;
*/
private void parseEnumEntry() {
@@ -483,7 +486,7 @@ public class JetParsing extends AbstractJetParsing {
advance(); // IDENTIFIER
nameAsDeclaration.done(OBJECT_DECLARATION_NAME);
parseTypeParameterList(TokenSet.create(COLON, LPAR, SEMICOLON, LBRACE));
boolean typeParametersDeclared = parseTypeParameterList(TokenSet.create(COLON, LPAR, SEMICOLON, LBRACE));
if (at(LPAR)) {
parseValueParameterList(false, TokenSet.create(COLON, SEMICOLON, LBRACE));
@@ -495,6 +498,8 @@ public class JetParsing extends AbstractJetParsing {
parseInitializerList();
}
parseTypeConstraintsGuarded(typeParametersDeclared);
if (at(LBRACE)) {
parseClassBody();
}
@@ -725,7 +730,7 @@ public class JetParsing extends AbstractJetParsing {
/*
* typedef
* : modifiers "type" SimpleName typeParameters? "=" type
* : modifiers "type" SimpleName (typeParameters typeConstraints)? "=" type
* ;
*/
public JetNodeType parseTypeDef() {
@@ -735,7 +740,9 @@ public class JetParsing extends AbstractJetParsing {
expect(IDENTIFIER, "Type name expected", TokenSet.orSet(TokenSet.create(LT, EQ, SEMICOLON), TOPLEVEL_OBJECT_FIRST));
parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
if (parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET)) {
parseTypeConstraints();
}
expect(EQ, "Expecting '='", TokenSet.orSet(TOPLEVEL_OBJECT_FIRST, TokenSet.create(SEMICOLON)));
@@ -751,6 +758,7 @@ public class JetParsing extends AbstractJetParsing {
* : modifiers ("val" | "var")
* typeParameters? (type "." | attributes)?
* SimpleName (":" type)?
* typeConstraints
* ("=" element SEMI?)?
* (getter? setter? | setter? getter?) SEMI?
* ;
@@ -766,9 +774,7 @@ public class JetParsing extends AbstractJetParsing {
errorAndAdvance("Expecting 'val' or 'var'");
}
if (at(LT)) {
parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON));
}
boolean typeParametersDeclared = at(LT) ? parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON)) : false;
TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON);
@@ -794,6 +800,8 @@ public class JetParsing extends AbstractJetParsing {
parseTypeRef();
}
parseTypeConstraintsGuarded(typeParametersDeclared);
if (local) {
if (at(EQ)) {
advance(); // EQ
@@ -900,6 +908,7 @@ public class JetParsing extends AbstractJetParsing {
* (type "." | attributes)?
* SimpleName
* typeParameters? functionParameters (":" type)?
* typeConstraints
* functionBody?
* ;
*/
@@ -934,6 +943,7 @@ public class JetParsing extends AbstractJetParsing {
else {
error.drop();
}
typeParameterListOccurred = true;
}
parseValueParameterList(false, valueParametersFollow);
@@ -944,6 +954,8 @@ public class JetParsing extends AbstractJetParsing {
parseTypeRef();
}
parseTypeConstraintsGuarded(typeParameterListOccurred);
if (at(SEMICOLON)) {
advance(); // SEMICOLON
}
@@ -1088,11 +1100,11 @@ public class JetParsing extends AbstractJetParsing {
/*
* typeParameters
* : ("<" typeParameter{","} ">"
* ("where" typeConstraint{","})?)?
* ;
*/
private void parseTypeParameterList(TokenSet recoverySet) {
private boolean parseTypeParameterList(TokenSet recoverySet) {
PsiBuilder.Marker list = mark();
boolean result = false;
if (at(LT)) {
myBuilder.disableNewlines();
@@ -1108,12 +1120,34 @@ public class JetParsing extends AbstractJetParsing {
expect(GT, "Missing '>'", recoverySet);
myBuilder.restoreNewlinesState();
if (at(WHERE_KEYWORD)) {
parseTypeConstraintList();
}
result = true;
}
list.done(TYPE_PARAMETER_LIST);
return result;
}
/*
* typeConstraints
* : ("where" typeConstraint{","})?
* ;
*/
private void parseTypeConstraintsGuarded(boolean typeParameterListOccurred) {
PsiBuilder.Marker error = mark();
boolean constraints = parseTypeConstraints();
if (constraints && !typeParameterListOccurred) {
error.error("Type constraints are not allowed when no type parameters declared");
}
else {
error.drop();
}
}
private boolean parseTypeConstraints() {
if (at(WHERE_KEYWORD)) {
parseTypeConstraintList();
return true;
}
return false;
}
/*
@@ -2,10 +2,8 @@ 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;
import java.util.Collections;
import java.util.List;
/**
@@ -20,17 +18,6 @@ public class JetTypeParameterList extends JetElement {
return findChildrenByType(JetNodeTypes.TYPE_PARAMETER);
}
@Nullable
public JetTypeConstraintList getTypeConstraintList() {
return (JetTypeConstraintList) findChildByType(JetNodeTypes.TYPE_CONSTRAINT_LIST);
}
@NotNull
public List<JetTypeConstraint> getAdditionalConstraints() {
JetTypeConstraintList list = getTypeConstraintList();
return list != null ? list.getConstraints() : Collections.<JetTypeConstraint>emptyList();
}
@Override
public void accept(JetVisitor visitor) {
visitor.visitTypeParameterList(this);
@@ -21,13 +21,14 @@ public class JetTypeParameterListOwner extends JetNamedDeclaration {
return (JetTypeParameterList) findChildByType(JetNodeTypes.TYPE_PARAMETER_LIST);
}
@Nullable
public JetTypeConstraintList getTypeConstraintList() {
return (JetTypeConstraintList) findChildByType(JetNodeTypes.TYPE_CONSTRAINT_LIST);
}
@NotNull
public List<JetTypeConstraint> getTypeConstaints() {
JetTypeParameterList typeParameterList = getTypeParameterList();
if (typeParameterList == null) {
return Collections.emptyList();
}
JetTypeConstraintList typeConstraintList = typeParameterList.getTypeConstraintList();
JetTypeConstraintList typeConstraintList = getTypeConstraintList();
if (typeConstraintList == null) {
return Collections.emptyList();
}
+4 -4
View File
@@ -14,14 +14,14 @@ class D() {
class object : A(), B () {}
}
class Test1<T : A>
class Test1<T : A>()
where
T : B,
<error>B</error> : T, // error
class object T : A,
class object T : B,
class object <error>B</error> : T
() {
{
fun test(t : T) {
T.foo()
@@ -46,14 +46,14 @@ class Buzz<T> where T : <warning>Bar<<error>Int</error>></warning>, T : <error>n
class X<T : <warning>Foo</warning>>
class Y<<error>T</error> : <warning>Foo</warning>> where T : <warning>Bar<Foo></warning>
fun <T : A>
fun <T : A> test2(t : T)
where
T : B,
<error>B</error> : T,
class object <error>B</error> : T,
class object T : B,
class object T : A
test2(t : T) {
{
T.foo()
T.bar()
t.foo()
@@ -8,6 +8,6 @@ class MyInt() {
}
}
fun toDefault<T: Any> where class object T: Default(t: T) = T.defaultValue()
fun toDefault<T: Any>(t: T) where class object T: Default = T.defaultValue()
fun box(): String = if (toDefault<MyInt>(MyInt()) == 610) "OK" else "fail"
+29 -29
View File
@@ -9,36 +9,36 @@ JetFile: TypeConstraints.jet
TYPE_PARAMETER
PsiElement(IDENTIFIER)('T')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
PsiElement(where)('where')
PsiWhiteSpace(' ')
TYPE_CONSTRAINT_LIST
TYPE_CONSTRAINT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
PsiElement(where)('where')
PsiWhiteSpace(' ')
TYPE_CONSTRAINT_LIST
TYPE_CONSTRAINT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ')
TYPE_CONSTRAINT
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(object)('object')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TYPE_CONSTRAINT
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(object)('object')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
@@ -16,9 +16,9 @@ class List<T> {
}
fun <E, T, R> where
fun <E, T, R> Map<E, T>.map(f : fun (E) : R) : T<R> where
T : Iterable<E>,
class object T : Buildable<E, T> Map<E, T>.map(f : fun (E) : R) : T<R> = {
class object T : Buildable<E, T> = {
val builder = T.newBuilder()
for (e in this) {
builder += f(e)
@@ -211,59 +211,6 @@ JetFile: PolymorphicClassObjects.jet
TYPE_PARAMETER
PsiElement(IDENTIFIER)('R')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
PsiElement(where)('where')
PsiWhiteSpace('\n ')
TYPE_CONSTRAINT_LIST
TYPE_CONSTRAINT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Iterable')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('E')
PsiElement(GT)('>')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
TYPE_CONSTRAINT
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(object)('object')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Buildable')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('E')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
@@ -329,6 +276,59 @@ JetFile: PolymorphicClassObjects.jet
PsiElement(IDENTIFIER)('R')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
PsiElement(where)('where')
PsiWhiteSpace('\n ')
TYPE_CONSTRAINT_LIST
TYPE_CONSTRAINT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Iterable')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('E')
PsiElement(GT)('>')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
TYPE_CONSTRAINT
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(object)('object')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Buildable')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('E')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('T')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
FUNCTION_LITERAL_EXPRESSION