Local declarations

This commit is contained in:
Andrey Breslav
2010-12-29 18:08:47 +03:00
parent 88b5c26fe3
commit 01297cc926
12 changed files with 321 additions and 61 deletions
+1 -19
View File
@@ -294,14 +294,6 @@
<inspection_tool class="TypeParameterExtendsObject" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UNCHECKED_WARNING" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UNUSED_IMPORT" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UNUSED_SYMBOL" enabled="false" level="WARNING" enabled_by_default="false">
<option name="LOCAL_VARIABLE" value="true" />
<option name="FIELD" value="true" />
<option name="METHOD" value="true" />
<option name="CLASS" value="true" />
<option name="PARAMETER" value="true" />
<option name="REPORT_PARAMETER_FOR_PUBLIC_METHODS" value="true" />
</inspection_tool>
<inspection_tool class="UnnecessaryBoxing" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryConditionalExpression" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryContinue" enabled="false" level="WARNING" enabled_by_default="false" />
@@ -317,17 +309,7 @@
<inspection_tool class="UnnecessaryTemporaryOnConversionToString" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryUnboxing" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnresolvedPropertyKey" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="UnusedAssignment" enabled="false" level="WARNING" enabled_by_default="false">
<option name="REPORT_PREFIX_EXPRESSIONS" value="false" />
<option name="REPORT_POSTFIX_EXPRESSIONS" value="true" />
<option name="REPORT_REDUNDANT_INITIALIZER" value="true" />
</inspection_tool>
<inspection_tool class="UnusedDeclaration" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ADD_MAINS_TO_ENTRIES" value="true" />
<option name="ADD_APPLET_TO_ENTRIES" value="true" />
<option name="ADD_SERVLET_TO_ENTRIES" value="true" />
<option name="ADD_NONJAVA_TO_ENTRIES" value="true" />
</inspection_tool>
<inspection_tool class="UnusedImport" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnusedLabel" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedMessageFormatParameter" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedParameters" enabled="false" level="WARNING" enabled_by_default="false" />
+3
View File
@@ -3,6 +3,9 @@
<component name="DependencyValidationManager">
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</component>
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="IdProvider" IDEtalkID="71A301FF1940049D6D82F12C40F1E1D5" />
<component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY" />
+3 -3
View File
@@ -3,7 +3,6 @@ expression
: literalConstant
: functionLiteral
: tupleLiteral
: "null"
: "this" ("<" type ">")?
: expressionWithPrecedences
: match
@@ -25,6 +24,7 @@ literalConstant
: IntegerLiteral
: HexadecimalLiteral
: CharacterLiteral
: "null"
;
declaration
@@ -83,14 +83,14 @@ binaryOperation // Decreasing precedence
: ".."
: SimpleName
: "?:"
: "in" : "is" : "!in" : "!is" : "as"
: "in" : "is" : "!in" : "!is" : "as" : ":"
: "<" : ">" : ">=" : "<="
: "!=" : "==" : "===" : "!=="
// No | & ^ ~
: "&&"
: "||"
: "match"
: "->"
: ":"
: assignmentOperator
;
+5
View File
@@ -12,6 +12,7 @@ pattern
: tuplePattern
: bindingPattern // we allow non-linear patterns
: decomposerPattern // labeled components are allowed
: arrowPattern
;
constantPattern
@@ -29,4 +30,8 @@ bindingPattern
decomposerPattern
: userType tuplePattern?
;
arrowPattern
: pattern "->" pattern
;
@@ -102,9 +102,20 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
return true;
}
}
if (expectation == IDENTIFIER && token instanceof JetKeywordToken) {
JetKeywordToken keywordToken = (JetKeywordToken) token;
if (keywordToken.isSoft()) {
myBuilder.remapCurrentToken(IDENTIFIER);
return true;
}
}
return false;
}
protected boolean atSet(IElementType... tokens) {
return atSet(TokenSet.create(tokens));
}
protected boolean atSet(final TokenSet set) {
IElementType token = tt();
if (set.contains(token)) return true;
@@ -1,6 +1,7 @@
package org.jetbrains.jet.lang.parsing;
import com.intellij.lang.PsiBuilder;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.jet.JetNodeType;
@@ -106,19 +107,21 @@ public class JetExpressionParsing extends AbstractJetParsing {
else if (at(NULL_KEYWORD)) {
parseOneTokenExpression(NULL);
}
else if (atSet(TokenSet.create(
CLASS_KEYWORD,
EXTENSION_KEYWORD,
FUN_KEYWORD,
VAL_KEYWORD,
VAR_KEYWORD,
TYPE_KEYWORD))) {
// modifiers
// attributes
// TODO
else if (atSet(CLASS_KEYWORD, EXTENSION_KEYWORD, FUN_KEYWORD, VAL_KEYWORD,
VAR_KEYWORD, TYPE_KEYWORD, DECOMPOSER_KEYWORD)) {
parseLocalDeclaration();
}
else if (at(LBRACKET)) {
if (!parseLocalDeclaration()) {
PsiBuilder.Marker attributes = mark();
myJetParsing.parseAttributeList();
attributes.error("Attributes are only allowed on declarations");
}
}
else if (at(IDENTIFIER)) {
advance(); // TODO
if (!parseLocalDeclaration()) {
expect(IDENTIFIER, "[Internal error: should never occur]"); // TODO
}
}
else if (at(LBRACE)) {
// TODO
@@ -131,6 +134,47 @@ public class JetExpressionParsing extends AbstractJetParsing {
// TODO: Binary operations
}
private boolean parseLocalDeclaration() {
PsiBuilder.Marker decls = mark();
JetParsing.EnumDetector enumDetector = new JetParsing.EnumDetector();
myJetParsing.parseModifierList(enumDetector);
JetNodeType declType = parseLocalDeclarationRest(enumDetector.isEnum());
if (declType != null) {
decls.done(declType);
return true;
} else {
decls.rollbackTo();
return false;
}
}
private JetNodeType parseLocalDeclarationRest(boolean isEnum) {
IElementType keywordToken = tt();
JetNodeType declType = null;
if (keywordToken == CLASS_KEYWORD) {
declType = myJetParsing.parseClass(isEnum);
}
else if (keywordToken == EXTENSION_KEYWORD) {
declType = myJetParsing.parseExtension();
}
else if (keywordToken == FUN_KEYWORD) {
declType = myJetParsing.parseFunction();
}
else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) {
declType = myJetParsing.parseProperty();
}
else if (keywordToken == TYPE_KEYWORD) {
declType = myJetParsing.parseTypeDef();
}
else if (keywordToken == DECOMPOSER_KEYWORD) {
declType = myJetParsing.parseDecomposer();
}
return declType;
}
/*
* doWhile
* : "do" expression "while" "(" expression ")"
@@ -213,7 +213,7 @@ public class JetParsing extends AbstractJetParsing {
* : modifiers "decomposer" (type ".")? SimpleName? "(" (attributes SimpleName){","}? ")" // Public properties only
* ;
*/
private JetNodeType parseDecomposer() {
public JetNodeType parseDecomposer() {
assert at(DECOMPOSER_KEYWORD);
advance(); // DECOMPOSER_KEYWORD
@@ -274,7 +274,7 @@ public class JetParsing extends AbstractJetParsing {
/*
* (modifier | attribute)*
*/
private void parseModifierList() {
public void parseModifierList() {
parseModifierList(null);
}
@@ -283,7 +283,7 @@ public class JetParsing extends AbstractJetParsing {
*
* Feeds modifiers (not attributes) into the passed consumer, if it is not null
*/
private void parseModifierList(Consumer<IElementType> tokenConsumer) {
public void parseModifierList(Consumer<IElementType> tokenConsumer) {
PsiBuilder.Marker list = mark();
boolean empty = true;
while (!eof()) {
@@ -391,7 +391,7 @@ public class JetParsing extends AbstractJetParsing {
* (classBody? | enumClassBody)
* ;
*/
private JetNodeType parseClass(boolean enumClass) {
public JetNodeType parseClass(boolean enumClass) {
assert at(CLASS_KEYWORD);
advance(); // CLASS_KEYWORD
@@ -664,7 +664,7 @@ public class JetParsing extends AbstractJetParsing {
* : modifiers "type" SimpleName typeParameters? "=" type
* ;
*/
private JetNodeType parseTypeDef() {
public JetNodeType parseTypeDef() {
assert at(TYPE_KEYWORD);
advance(); // TYPE_KEYWORD
@@ -688,32 +688,31 @@ public class JetParsing extends AbstractJetParsing {
* (getter? setter? | setter? getter?) SEMI?
* ;
*/
private JetNodeType parseProperty() {
public JetNodeType parseProperty() {
assert at(VAL_KEYWORD) || at(VAR_KEYWORD);
advance(); // VAL_KEYWORD or VAR_KEYWORD
// TODO: EOL_OR_SEMICOLON is too restrictive here
TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON);
// int lastDot = findLastBefore(TokenSet.create(DOT), propertyNameFollow, true);
// TODO: constant
int lastDot = matchTokenStreamPredicate(new FirstBefore(new TokenStreamPredicate() {
@Override
public boolean matching(boolean topLevel) {
return topLevel
&& at(DOT);
}
}, new TokenStreamPredicate() {
@Override
public boolean matching(boolean topLevel) {
if (lookahead(1) == IDENTIFIER) {
IElementType lookahead2 = lookahead(2);
return lookahead2 != LT && lookahead2 != DOT;
}
return false;
}
}));
int lastDot = matchTokenStreamPredicate(new FirstBefore(
new TokenStreamPredicate() {
@Override
public boolean matching(boolean topLevel) {
return topLevel
&& at(DOT);
}
}, new TokenStreamPredicate() {
@Override
public boolean matching(boolean topLevel) {
if (lookahead(1) == IDENTIFIER) {
IElementType lookahead2 = lookahead(2);
return lookahead2 != LT && lookahead2 != DOT;
}
return false;
}
}));
if (lastDot == -1) {
parseAttributeList();
@@ -806,7 +805,7 @@ public class JetParsing extends AbstractJetParsing {
* : attributes SimpleName typeParameters? functionParameters (":" type)? functionBody?
* ;
*/
private JetNodeType parseFunction() {
public JetNodeType parseFunction() {
assert at(FUN_KEYWORD);
advance(); // FUN_KEYWORD
@@ -892,7 +891,7 @@ public class JetParsing extends AbstractJetParsing {
* : modifiers "extension" SimpleName? typeParameters? "for" type classBody? // properties cannot be lazy, cannot have backing fields
* ;
*/
private JetNodeType parseExtension() {
public JetNodeType parseExtension() {
assert at(EXTENSION_KEYWORD);
advance(); // EXTENSION_KEYWORD
@@ -975,7 +974,7 @@ public class JetParsing extends AbstractJetParsing {
* : attributeAnnotation*
* ;
*/
private void parseAttributeList() {
public void parseAttributeList() {
while (at(LBRACKET)) parseAttributeAnnotation();
}
@@ -1382,7 +1381,7 @@ public class JetParsing extends AbstractJetParsing {
return new JetParsing(new TruncatedSemanticWhitespaceAwarePsiBuilder(myBuilder, eofPosition));
}
private static class EnumDetector implements Consumer<IElementType> {
/*package*/ static class EnumDetector implements Consumer<IElementType> {
private boolean myEnum = false;
+16
View File
@@ -0,0 +1,16 @@
fun foo() {
lazy
1
[a] abstract class foof {}
abstract [a] class foof {}
lazy val foo = 5
[a] var foo = 4
type f = {T.() : ()}
virtual extension foo for bar {
}
decomposer T.foo(bar)
}
+158
View File
@@ -0,0 +1,158 @@
JetFile: LocalDeclarations.jet
NAMESPACE
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
TYPE_PARAMETER_LIST
<empty list>
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
PsiElement(IDENTIFIER)('lazy')
PsiWhiteSpace('\n ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n ')
CLASS
MODIFIER_LIST
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(abstract)('abstract')
PsiWhiteSpace(' ')
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foof')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
CLASS_BODY
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n ')
CLASS
MODIFIER_LIST
PsiElement(abstract)('abstract')
PsiWhiteSpace(' ')
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foof')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
CLASS_BODY
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
PROPERTY
MODIFIER_LIST
PsiElement(lazy)('lazy')
PsiWhiteSpace(' ')
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('5')
PsiWhiteSpace('\n ')
PROPERTY
MODIFIER_LIST
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
PsiElement(var)('var')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('4')
PsiWhiteSpace('\n ')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
FUNCTION_TYPE
PsiElement(LBRACE)('{')
RECEIVER_TYPE
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('T')
PsiElement(DOT)('.')
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
MODIFIER_LIST
PsiElement(virtual)('virtual')
PsiWhiteSpace(' ')
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)('{')
PsiWhiteSpace('\n\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
DECOMPOSER
PsiElement(decomposer)('decomposer')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('T')
PsiElement(DOT)('.')
USER_TYPE
PsiElement(IDENTIFIER)('foo')
DECOMPOSER_PROPERTY_LIST
PsiElement(LPAR)('(')
PsiElement(IDENTIFIER)('bar')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -0,0 +1,5 @@
fun foo() {
[a]
1
[a]
}
@@ -0,0 +1,35 @@
JetFile: LocalDeclarations_ERR.jet
NAMESPACE
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
TYPE_PARAMETER_LIST
<empty list>
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
PsiErrorElement:Attributes are only allowed on declarations
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n ')
PsiErrorElement:Attributes are only allowed on declarations
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -47,6 +47,8 @@ public class JetParsingTest extends ParsingTestCase {
public void testImports() throws Exception {doTest(true);}
public void testImports_ERR() throws Exception {doTest(true);}
public void testImportSoftKW() throws Exception {doTest(true);}
public void testLocalDeclarations() throws Exception {doTest(true);}
public void testLocalDeclarations_ERR() throws Exception {doTest(true);}
public void testNamespaceBlock_ERR() throws Exception {doTest(true);}
public void testNamespaceBlock() throws Exception {doTest(true);}
public void testProperties() throws Exception {doTest(true);}