Attributes

This commit is contained in:
Andrey Breslav
2010-12-15 19:50:21 +03:00
parent 2453e6a0dd
commit 86fcba88d0
8 changed files with 654 additions and 8 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ type
;
userType
: (SimpleName ".")* simpleUserType{"."}
: /*(SimpleName ".")* */ simpleUserType{"."}
;
simpleUserType
@@ -32,6 +32,12 @@ public interface JetNodeTypes {
JetNodeType IMPORTED = new JetNodeType("IMPORTED");
JetNodeType NAMESPACE_BODY = new JetNodeType("NAMESPACE_BODY");
JetNodeType MODIFIER_LIST = new JetNodeType("MODIFIER_LIST");
JetNodeType ATTRIBUTE_ANNOTATION = new JetNodeType("ATTRIBUTE_ANNOTATION");
JetNodeType ATTRIBUTE = new JetNodeType("ATTRIBUTE");
JetNodeType USER_TYPE = new JetNodeType("USER_TYPE");
JetNodeType TYPE_ARGUMENT_LIST = new JetNodeType("TYPE_ARGUMENT_LIST");
JetNodeType VALUE_ARGUMENT_LIST = new JetNodeType("VALUE_ARGUMENT_LIST");
JetNodeType VALUE_ARGUMENT = new JetNodeType("VALUE_ARGUMENT");
IElementType NAMESPACE_NAME = new JetNodeType("NAMESPACE_NAME");
@@ -207,22 +207,17 @@ public class JetParsing {
/*
* modifier
* : "abstract"
* : "virtual"
* : "enum"
* : "open"
* : "attribute"
* : "override"
* : "virtual"
* : "abstract"
* : "private"
* : "protected"
* : "public"
* : "internal"
* : "in"
* : "out"
* : "lazy"
* : "ref"
*/
private boolean parseModifierSoftKeyword() {
if (!at(IDENTIFIER)) return false;
@@ -236,11 +231,16 @@ public class JetParsing {
return false;
}
/*
* (modifier | attribute)*
*/
private void parseModifierList() {
PsiBuilder.Marker list = mark();
boolean empty = true;
while (true) {
if (MODIFIER_KEYWORDS.contains(tt())) {
while (!eof()) {
if (at(LBRACKET)) {
parseAttributeAnnotation();
} else if (MODIFIER_KEYWORDS.contains(tt())) {
advance();
}
else {
@@ -255,6 +255,143 @@ public class JetParsing {
}
}
/*
* attributeAnnotation
* : "[" attribute{","} "]"
* ;
*/
private void parseAttributeAnnotation() {
assert at(LBRACKET);
PsiBuilder.Marker annotation = mark();
advance(); // LBRACKET
while (true) {
if (at(IDENTIFIER)) {
parseAttribute();
if (!at(COMMA)) break;
advance(); // COMMA
}
else {
error("Expecting a comma-separated list of attributes");
break;
}
}
expect(RBRACKET, "Expecting ']' to close an attribute annotation");
annotation.done(ATTRIBUTE_ANNOTATION);
}
/*
* attribute
* // : SimpleName{"."} valueArguments?
* [for recovery: userType valueArguments?]
* ;
*/
private void parseAttribute() {
PsiBuilder.Marker attribute = mark();
parseUserType();
if (at(LPAR)) parseValueArgumentList();
attribute.done(ATTRIBUTE);
}
/*
* userType
* : simpleUserType{"."}
* ;
*
* simpleUserType
* : SimpleName ("<" (optionalProjection type){","} ">")?
* ;
*/
private void parseUserType() {
PsiBuilder.Marker userType = mark();
while (true) {
parseSimpleUserType();
if (!at(DOT)) break;
advance(); // DOT
}
userType.done(USER_TYPE);
}
/*
* simpleUserType
* : SimpleName ("<" (optionalProjection type){","} ">")?
* ;
*/
private void parseSimpleUserType() {
PsiBuilder.Marker type = mark();
expect(IDENTIFIER, "Type name expected", TokenSet.create(LT));
parseTypeArgumentList();
type.done(USER_TYPE);
}
/*
* (optionalProjection type){","}
*/
private void parseTypeArgumentList() {
if (!at(LT)) return;
PsiBuilder.Marker list = mark();
advance(); // LT
while (true) {
parseModifierList();
parseTypeRef();
if (!at(COMMA)) break;
advance(); // COMMA
}
expect(GT, "Expecting a '>'");
list.done(TYPE_ARGUMENT_LIST);
}
/*
* valueArguments
* : "(" (SimpleName "=")? ("out" | "ref")? expression{","} ")"
* ;
*/
private void parseValueArgumentList() {
assert at(LPAR);
PsiBuilder.Marker list = mark();
advance(); // LPAR
if (!at(RPAR)) {
while (true) {
parseValueArgument();
if (!at(COMMA)) break;
advance(); // COMMA
}
}
expect(RPAR, "Expecting ')'");
list.done(VALUE_ARGUMENT_LIST);
}
/*
* (SimpleName "=")? ("out" | "ref")? expression
*/
private void parseValueArgument() {
PsiBuilder.Marker argument = mark();
if (at(IDENTIFIER) && lookahead(1) == EQ) {
advance(); // IDENTIFIER
advance(); // EQ
}
if (at(OUT_KEYWORD) || at(REF_KEYWORD)) advance(); // REF or OUT
parseExpression();
argument.done(VALUE_ARGUMENT);
}
/*
* namespace
* : "namespace" SimpleName{"."} "{"
@@ -351,6 +488,7 @@ public class JetParsing {
private void parseDelegationSpecifierList() {
PsiBuilder.Marker list = mark();
while (true) {
parseDelegationSpecifier();
if (!at(COMMA)) break;
+38
View File
@@ -0,0 +1,38 @@
namespace foo.bar.goo
abstract
virtual
enum
open
attribute
override
virtual
abstract
private
protected
public
internal
lazy [foo<A, B>(a, b),ina,foo.bar.goo.doo<f>.foo<bar, goo>.foo]
[df]
in
[sdfsdf]
out
ref
class Bar<abstract
virtual
enum
open
attribute
override
virtual
abstract
[sdfsd, sdfsd, a.b.f.c]
private
protected
public
internal
lazy
in
out
ref T> {
}
+196
View File
@@ -0,0 +1,196 @@
JetFile: Attributes.jet
NAMESPACE
PsiElement(namespace)('namespace')
PsiWhiteSpace(' ')
NAMESPACE_NAME
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('bar')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('goo')
PsiWhiteSpace('\n\n')
CLASS
MODIFIER_LIST
PsiElement(abstract)('abstract')
PsiWhiteSpace('\n')
PsiElement(virtual)('virtual')
PsiWhiteSpace('\n')
PsiElement(enum)('enum')
PsiWhiteSpace('\n')
PsiElement(open)('open')
PsiWhiteSpace('\n')
PsiElement(attribute)('attribute')
PsiWhiteSpace('\n')
PsiElement(override)('override')
PsiWhiteSpace('\n')
PsiElement(virtual)('virtual')
PsiWhiteSpace('\n')
PsiElement(abstract)('abstract')
PsiWhiteSpace('\n')
PsiElement(private)('private')
PsiWhiteSpace('\n')
PsiElement(protected)('protected')
PsiWhiteSpace('\n')
PsiElement(public)('public')
PsiWhiteSpace('\n')
PsiElement(internal)('internal')
PsiWhiteSpace('\n')
PsiElement(lazy)('lazy')
PsiWhiteSpace(' ')
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
PsiElement(IDENTIFIER)('A')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('B')
PsiElement(GT)('>')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
PsiElement(IDENTIFIER)('a')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
VALUE_ARGUMENT
PsiElement(IDENTIFIER)('b')
PsiElement(RPAR)(')')
PsiElement(COMMA)(',')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('ina')
PsiElement(COMMA)(',')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('bar')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('goo')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('doo')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
PsiElement(IDENTIFIER)('f')
PsiElement(GT)('>')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
PsiElement(IDENTIFIER)('bar')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('goo')
PsiElement(GT)('>')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('df')
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
PsiElement(in)('in')
PsiWhiteSpace('\n')
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('sdfsdf')
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
PsiElement(out)('out')
PsiWhiteSpace('\n')
PsiElement(ref)('ref')
PsiWhiteSpace('\n ')
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('Bar')
TYPE_PARAMETER_LIST
PsiElement(LT)('<')
TYPE_PARAMETER
MODIFIER_LIST
PsiElement(abstract)('abstract')
PsiWhiteSpace('\n')
PsiElement(virtual)('virtual')
PsiWhiteSpace('\n')
PsiElement(enum)('enum')
PsiWhiteSpace('\n')
PsiElement(open)('open')
PsiWhiteSpace('\n')
PsiElement(attribute)('attribute')
PsiWhiteSpace('\n')
PsiElement(override)('override')
PsiWhiteSpace('\n')
PsiElement(virtual)('virtual')
PsiWhiteSpace('\n')
PsiElement(abstract)('abstract')
PsiWhiteSpace('\n')
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('sdfsd')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('sdfsd')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('f')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('c')
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
PsiElement(private)('private')
PsiWhiteSpace('\n')
PsiElement(protected)('protected')
PsiWhiteSpace('\n')
PsiElement(public)('public')
PsiWhiteSpace('\n')
PsiElement(internal)('internal')
PsiWhiteSpace('\n')
PsiElement(lazy)('lazy')
PsiWhiteSpace('\n')
PsiElement(in)('in')
PsiWhiteSpace('\n')
PsiElement(out)('out')
PsiWhiteSpace('\n')
PsiElement(ref)('ref')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('T')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
+40
View File
@@ -0,0 +1,40 @@
namespace foo.bar.goo
abstract
virtual
enum
open
attribute
override
virtual
abstract
[]
private
protected
public
internal
lazy [foo<A, B>(a, b), ina,foo.bar.goo.doo<f>.foo<bar, goo>.foo]
[df]
in
[sdfsdf,]
[s,fd d]
out
ref
class Bar<abstract
virtual
enum
open
attribute
override
virtual
abstract
[sdfsd, sdfsd, a.b.f.c]
private
protected
public
internal
lazy
in
out
ref T> {
}
+226
View File
@@ -0,0 +1,226 @@
JetFile: Attributes_ERR.jet
NAMESPACE
PsiElement(namespace)('namespace')
PsiWhiteSpace(' ')
NAMESPACE_NAME
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('bar')
PsiElement(DOT)('.')
PsiElement(IDENTIFIER)('goo')
PsiWhiteSpace('\n\n')
MODIFIER_LIST
PsiElement(abstract)('abstract')
PsiWhiteSpace('\n')
PsiElement(virtual)('virtual')
PsiWhiteSpace('\n')
PsiElement(enum)('enum')
PsiWhiteSpace('\n')
PsiElement(open)('open')
PsiWhiteSpace('\n')
PsiElement(attribute)('attribute')
PsiWhiteSpace('\n')
PsiElement(override)('override')
PsiWhiteSpace('\n')
PsiElement(virtual)('virtual')
PsiWhiteSpace('\n')
PsiElement(abstract)('abstract')
PsiWhiteSpace('\n')
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
PsiErrorElement:Expecting a comma-separated list of attributes
<empty list>
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
PsiElement(private)('private')
PsiWhiteSpace('\n')
PsiElement(protected)('protected')
PsiWhiteSpace('\n')
PsiElement(public)('public')
PsiWhiteSpace('\n')
PsiElement(internal)('internal')
PsiWhiteSpace('\n')
PsiElement(lazy)('lazy')
PsiWhiteSpace(' ')
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
PsiElement(IDENTIFIER)('A')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('B')
PsiElement(GT)('>')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
PsiElement(IDENTIFIER)('a')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
VALUE_ARGUMENT
PsiElement(IDENTIFIER)('b')
PsiElement(RPAR)(')')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('ina')
PsiElement(COMMA)(',')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('bar')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('goo')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('doo')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
PsiElement(IDENTIFIER)('f')
PsiElement(GT)('>')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
PsiElement(IDENTIFIER)('bar')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('goo')
PsiElement(GT)('>')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('df')
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
PsiElement(in)('in')
PsiWhiteSpace('\n')
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('sdfsdf')
PsiElement(COMMA)(',')
PsiErrorElement:Expecting a comma-separated list of attributes
<empty list>
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('s')
PsiElement(COMMA)(',')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('fd')
PsiErrorElement:Expecting ']' to close an attribute annotation
<empty list>
PsiWhiteSpace(' ')
PsiErrorElement:Expecting namespace or top level declaration
PsiElement(IDENTIFIER)('d')
PsiErrorElement:Expecting namespace or top level declaration
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
CLASS
MODIFIER_LIST
PsiElement(out)('out')
PsiWhiteSpace('\n')
PsiElement(ref)('ref')
PsiWhiteSpace('\n ')
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('Bar')
TYPE_PARAMETER_LIST
PsiElement(LT)('<')
TYPE_PARAMETER
MODIFIER_LIST
PsiElement(abstract)('abstract')
PsiWhiteSpace('\n')
PsiElement(virtual)('virtual')
PsiWhiteSpace('\n')
PsiElement(enum)('enum')
PsiWhiteSpace('\n')
PsiElement(open)('open')
PsiWhiteSpace('\n')
PsiElement(attribute)('attribute')
PsiWhiteSpace('\n')
PsiElement(override)('override')
PsiWhiteSpace('\n')
PsiElement(virtual)('virtual')
PsiWhiteSpace('\n')
PsiElement(abstract)('abstract')
PsiWhiteSpace('\n')
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('sdfsd')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('sdfsd')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('f')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('c')
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
PsiElement(private)('private')
PsiWhiteSpace('\n')
PsiElement(protected)('protected')
PsiWhiteSpace('\n')
PsiElement(public)('public')
PsiWhiteSpace('\n')
PsiElement(internal)('internal')
PsiWhiteSpace('\n')
PsiElement(lazy)('lazy')
PsiWhiteSpace('\n')
PsiElement(in)('in')
PsiWhiteSpace('\n')
PsiElement(out)('out')
PsiWhiteSpace('\n')
PsiElement(ref)('ref')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('T')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -35,4 +35,6 @@ public class JetParsingTest extends ParsingTestCase {
public void testNamespaceBlock_ERR() throws Exception {doTest(true);}
public void testNamespaceBlock() throws Exception {doTest(true);}
public void testSimpleModifiers() throws Exception {doTest(true);}
public void testAttributes() throws Exception {doTest(true);}
public void testAttributes_ERR() throws Exception {doTest(true);}
}