Extensions
This commit is contained in:
@@ -497,32 +497,6 @@ public class JetParsing extends AbstractJetParsing {
|
||||
expect(IDENTIFIER, "Expecting property name", propertyNameFollow);
|
||||
}
|
||||
|
||||
|
||||
// PsiBuilder.Marker receiverTypeAttributes = mark();
|
||||
// parseAttributeList();
|
||||
//
|
||||
// if (at(IDENTIFIER) && propertyNameFollow.contains(lookahead(1))) { // There's no explicit receiver specified
|
||||
// // val [a] name = foo
|
||||
// receiverTypeAttributes.done(RECEIVER_TYPE_ATTRIBUTES);
|
||||
// advance(); // IDENTIFIER
|
||||
// }
|
||||
// else { // There must be an explicit receiver
|
||||
// receiverTypeAttributes.rollbackTo(); // Attributes are a part of the receiver type
|
||||
// if (!TYPE_REF_FIRST.contains(tt())) {
|
||||
// errorUntil("Expecting receiver type or property name", propertyNameFollow);
|
||||
// }
|
||||
// else {
|
||||
// // TODO: if this type is annotated with an attribute, and it is a single identifier,
|
||||
// // TODO: it is NOT an error (fun [a] foo()) -- annotation on receiver
|
||||
// parseTypeRef();
|
||||
// // The property name may appear as the last section of the type
|
||||
// if (at(DOT)) {
|
||||
// advance(); // DOT
|
||||
// expect(IDENTIFIER, "Expecting property name", propertyNameFollow);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if (at(COLON)) {
|
||||
advance(); // COLON
|
||||
parseTypeRef();
|
||||
@@ -618,32 +592,6 @@ public class JetParsing extends AbstractJetParsing {
|
||||
expect(IDENTIFIER, "Expecting function name", functionNameFollow);
|
||||
}
|
||||
|
||||
// PsiBuilder.Marker receiverTypeAttributes = mark();
|
||||
//
|
||||
// parseAttributeList();
|
||||
//
|
||||
// if (at(IDENTIFIER) && lookahead(1) == LPAR) { // There's no explicit receiver specified
|
||||
// // fun [a] name() = foo
|
||||
// receiverTypeAttributes.done(RECEIVER_TYPE_ATTRIBUTES);
|
||||
// advance(); // IDENTIFIER
|
||||
// }
|
||||
// else { // There must be an explicit receiver
|
||||
// receiverTypeAttributes.rollbackTo(); // Attributes are a part of the receiver type
|
||||
// if (!TYPE_REF_FIRST.contains(tt())) {
|
||||
// errorUntil("Expecting receiver type or property name", TokenSet.create(LPAR, EOL_OR_SEMICOLON));
|
||||
// }
|
||||
// else {
|
||||
// // TODO: if this type is annotated with an attribute, and it is a single identifier,
|
||||
// // TODO: it is NOT an error (fun [a] foo()) -- annotation on receiver
|
||||
// parseTypeRef();
|
||||
// // The property name may appear as the last section of the type
|
||||
// if (at(DOT)) {
|
||||
// advance(); // DOT
|
||||
// expect(IDENTIFIER, "Expecting property name", TokenSet.create(LPAR));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
TokenSet valueParametersFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON, RPAR);
|
||||
|
||||
parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow));
|
||||
@@ -768,7 +716,25 @@ public class JetParsing extends AbstractJetParsing {
|
||||
* ;
|
||||
*/
|
||||
private JetNodeType parseExtension() {
|
||||
advance(); // TODO
|
||||
assert at(EXTENSION_KEYWORD);
|
||||
|
||||
advance(); // EXTENSION_KEYWORD
|
||||
|
||||
consumeIf(IDENTIFIER);
|
||||
|
||||
parseTypeParameterList(TokenSet.create(FOR_KEYWORD, LBRACE));
|
||||
|
||||
expect(FOR_KEYWORD, "Expecting 'for' to specify the type that is being extended", TYPE_REF_FIRST);
|
||||
|
||||
parseTypeRef();
|
||||
|
||||
if (at(LBRACE)) {
|
||||
parseClassBody();
|
||||
}
|
||||
else {
|
||||
consumeIf(SEMICOLON);
|
||||
}
|
||||
|
||||
return EXTENSION;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
extension for bar
|
||||
extension foo for bar
|
||||
extension <foo> for bar
|
||||
extension foo<A> for bar
|
||||
extension foo<A> for {() : ()}
|
||||
|
||||
extension for bar;
|
||||
extension foo for bar;
|
||||
extension <foo> for bar;
|
||||
extension foo<A> for bar;
|
||||
extension foo<A> for {() : ()};
|
||||
|
||||
extension for bar {}
|
||||
extension foo for bar {}
|
||||
extension <foo> for bar {}
|
||||
extension foo<A> for bar {}
|
||||
extension foo<A> for {() : ()} {}
|
||||
@@ -0,0 +1,272 @@
|
||||
JetFile: Extensions.jet
|
||||
NAMESPACE
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
<empty list>
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
<empty list>
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
FUNCTION_TYPE
|
||||
PsiElement(LBRACE)('{')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
TUPLE_TYPE
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
<empty list>
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
<empty list>
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
FUNCTION_TYPE
|
||||
PsiElement(LBRACE)('{')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
TUPLE_TYPE
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiElement(SEMICOLON)(';')
|
||||
PsiWhiteSpace('\n\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
<empty list>
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS_BODY
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
<empty list>
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS_BODY
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS_BODY
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS_BODY
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
FUNCTION_TYPE
|
||||
PsiElement(LBRACE)('{')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
TUPLE_TYPE
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS_BODY
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -0,0 +1,5 @@
|
||||
extension for
|
||||
extension foo bar
|
||||
extension <foo for bar
|
||||
extension foo<A> for
|
||||
extension foo<A> for {() : ()} {}
|
||||
@@ -0,0 +1,86 @@
|
||||
JetFile: Extensions_ERR.jet
|
||||
NAMESPACE
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
<empty list>
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace('\n')
|
||||
TYPE_REFERENCE
|
||||
PsiErrorElement:Type expected
|
||||
<empty list>
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
<empty list>
|
||||
PsiErrorElement:Expecting 'for' to specify the type that is being extended
|
||||
<empty list>
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiErrorElement:Missing '>'
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace('\n')
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace('\n')
|
||||
TYPE_REFERENCE
|
||||
PsiErrorElement:Type expected
|
||||
<empty list>
|
||||
EXTENSION
|
||||
PsiElement(extension)('extension')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
TYPE_PARAMETER_LIST
|
||||
PsiElement(LT)('<')
|
||||
TYPE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
FUNCTION_TYPE
|
||||
PsiElement(LBRACE)('{')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
TUPLE_TYPE
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace(' ')
|
||||
CLASS_BODY
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -50,4 +50,6 @@ public class JetParsingTest extends ParsingTestCase {
|
||||
public void testProperties_ERR() throws Exception {doTest(true);}
|
||||
public void testFunctions() throws Exception {doTest(true);}
|
||||
public void testFunctions_ERR() throws Exception {doTest(true);}
|
||||
public void testExtensions() throws Exception {doTest(true);}
|
||||
public void testExtensions_ERR() throws Exception {doTest(true);}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user