Extensions

This commit is contained in:
Andrey Breslav
2010-12-20 20:54:20 +03:00
parent 6f241b7f9f
commit ba1cc369f8
6 changed files with 401 additions and 53 deletions
@@ -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;
}
+17
View File
@@ -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 {() : ()} {}
+272
View File
@@ -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)('}')
+5
View File
@@ -0,0 +1,5 @@
extension for
extension foo bar
extension <foo for bar
extension foo<A> for
extension foo<A> for {() : ()} {}
+86
View File
@@ -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);}
}