Skip to content

Commit bdda8f0

Browse files
authored
Merge pull request #578 from HaxeFoundation/ParserErrors575
Parser error #575,, part 1.
2 parents f648e79 + 51ebdc4 commit bdda8f0

File tree

4 files changed

+100
-7
lines changed

4 files changed

+100
-7
lines changed

grammar/haxe.bnf

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ private externAndMaybePrivate1 ::= privateKeyWord? externKeyWord
276276
private externAndMaybePrivate2 ::= externKeyWord privateKeyWord?
277277
private externAndMaybePrivate ::= externAndMaybePrivate2 | externAndMaybePrivate1
278278

279-
typedefDeclaration ::= macroClassList? externOrPrivate? 'typedef' componentName genericParam? '=' functionTypeWrapper ';'?
279+
typedefDeclaration ::= macroClassList? externOrPrivate? 'typedef' componentName genericParam? '=' typeWrapper ';'?
280280
{pin=5 mixin="com.intellij.plugins.haxe.lang.psi.impl.AbstractHaxeTypeDefImpl" implements="com.intellij.plugins.haxe.lang.psi.HaxeClass"}
281281

282282
externClassDeclaration ::= macroClassList? externAndMaybePrivate 'class' componentName genericParam? inheritList? '{' externClassDeclarationBody '}'
@@ -292,7 +292,7 @@ classDeclaration ::= macroClassList? privateKeyWord? 'class' componentName gener
292292
{pin=3 mixin="com.intellij.plugins.haxe.lang.psi.impl.AbstractHaxePsiClass" implements="com.intellij.plugins.haxe.lang.psi.HaxeClass"}
293293

294294
//'from' | 'to'
295-
abstractClassDeclaration ::= macroClassList? privateKeyWord? 'abstract' componentName genericParam? ('(' functionTypeWrapper ')')? ((identifier) type)* '{' classBody '}'
295+
abstractClassDeclaration ::= macroClassList? privateKeyWord? 'abstract' componentName genericParam? ('(' typeWrapper ')')? ((identifier) type)* '{' classBody '}'
296296
{pin=3 mixin="com.intellij.plugins.haxe.lang.psi.impl.AbstractHaxePsiClass" implements="com.intellij.plugins.haxe.lang.psi.HaxeClass"}
297297

298298
classBody ::= classBodyPart*
@@ -374,9 +374,19 @@ arrayLiteral ::= '[' (expressionList ','?)? ']'
374374
{mixin="com.intellij.plugins.haxe.lang.psi.impl.HaxeReferenceImpl" implements="com.intellij.plugins.haxe.lang.psi.HaxeReference"}
375375

376376
private functionTypeWrapper ::= functionTypeOrWrapper functionType*
377-
private functionTypeOrWrapper ::= typeOrAnonymous | '(' functionTypeWrapper ')'
377+
private functionTypeOrWrapper ::= '?'? typeOrAnonymous | '(' functionTypeWrapper ')'
378378
left functionType ::= '->' '?'? typeOrAnonymous
379379

380+
private typeWrapper::= functionTypeWrapper
381+
382+
// EMB: To replace the above four lines. See issue #575. //////////////////////////////////
383+
//functionArgument ::= (typeOrAnonymous | ('(' functionType ')'))
384+
//private functionOptionalArgument ::= '?'? functionArgument
385+
//functionType ::= functionOptionalArgument '->' (functionOptionalArgument '->')* functionArgument {pin=2 recoverWhile="functionTypeRecovery"}
386+
//functionTypeRecovery ::= !('}' | ';' | '>' | '=')
387+
//
388+
//private typeWrapper ::= functionType | typeOrAnonymous
389+
// /////////////////////////////////////////////////////////////////////////////////////////
380390
/*
381391
* Haxe and Java have this backward from each other.
382392
*
@@ -391,13 +401,13 @@ left functionType ::= '->' '?'? typeOrAnonymous
391401
*
392402
*/
393403

394-
typeTag ::= ':' functionTypeWrapper
404+
typeTag ::= ':' typeWrapper
395405
typeParam ::= '<' typeList '>' {mixin="com.intellij.plugins.haxe.lang.psi.impl.HaxeTypeParamPsiMixinImpl" implements="com.intellij.plugins.haxe.lang.psi.HaxeTypeParamPsiMixin"}
396406
typeList ::= typeListPart (',' typeListPart)*
397407
genericParam ::= '<' genericListPart (',' genericListPart)* '>'
398408
genericListPart ::= componentName (':' ('(' typeList ')' | typeListPart))?
399409
{mixin="com.intellij.plugins.haxe.lang.psi.impl.AbstractHaxeNamedComponent" implements="com.intellij.plugins.haxe.lang.psi.HaxeComponent"}
400-
typeListPart ::= functionTypeWrapper
410+
typeListPart ::= typeWrapper
401411
{mixin="com.intellij.plugins.haxe.lang.psi.impl.HaxeTypeListPartPsiMixinImpl" implements="com.intellij.plugins.haxe.lang.psi.HaxeTypeListPartPsiMixin"}
402412
type ::= referenceExpression qualifiedReferenceExpression* typeParam?
403413
{mixin="com.intellij.plugins.haxe.lang.psi.impl.HaxeTypePsiMixinImpl" implements="com.intellij.plugins.haxe.lang.psi.HaxeTypePsiMixin"}
@@ -549,7 +559,7 @@ regularExpressionLiteral ::= REG_EXP
549559
private parenthesizedExpressionOrCall ::= parenthesizedExpression qualifiedReferenceTail?
550560
parenthesizedExpression ::= '(' (typeCheckExpr | expression | statement) ')'
551561

552-
typeCheckExpr ::= expression ':' functionTypeWrapper
562+
typeCheckExpr ::= expression ':' typeWrapper
553563
{mixin="com.intellij.plugins.haxe.lang.psi.impl.HaxeClassReferenceImpl" implements="com.intellij.plugins.haxe.lang.psi.HaxeReference"}
554564

555565
private newExpressionOrCall ::= newExpression qualifiedReferenceTail?
@@ -588,7 +598,7 @@ superExpression ::= 'super'
588598
newExpression ::= 'new' type '(' (expression (',' expression)*)? ')'
589599
{pin=2 recoverWhile="expression_recover" mixin="com.intellij.plugins.haxe.lang.psi.impl.HaxeReferenceImpl" implements="com.intellij.plugins.haxe.lang.psi.HaxeReference"}
590600

591-
castExpression ::= 'cast' (('(' expression ',' functionTypeWrapper ')') | expression)
601+
castExpression ::= 'cast' (('(' expression ',' typeWrapper ')') | expression)
592602
{mixin="com.intellij.plugins.haxe.lang.psi.impl.HaxeClassReferenceImpl" implements="com.intellij.plugins.haxe.lang.psi.HaxeReference"}
593603

594604
inheritList ::= inherit (','? inherit)*
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class Test {
2+
static function main() {
3+
var a:?Int->Void;
4+
var b:Int->?Float->Void;
5+
}
6+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
Haxe File
2+
CLASS_DECLARATION
3+
PsiJavaToken:class('class')
4+
COMPONENT_NAME
5+
IDENTIFIER
6+
PsiJavaToken:ID('Test')
7+
PsiJavaToken:{('{')
8+
CLASS_BODY
9+
FUNCTION_DECLARATION_WITH_ATTRIBUTES
10+
DECLARATION_ATTRIBUTE
11+
PsiJavaToken:static('static')
12+
PsiJavaToken:function('function')
13+
COMPONENT_NAME
14+
IDENTIFIER
15+
PsiJavaToken:ID('main')
16+
PsiJavaToken:(('(')
17+
PARAMETER_LIST
18+
<empty list>
19+
PsiJavaToken:)(')')
20+
BLOCK_STATEMENT
21+
PsiJavaToken:{('{')
22+
LOCAL_VAR_DECLARATION
23+
PsiJavaToken:var('var')
24+
LOCAL_VAR_DECLARATION_PART
25+
COMPONENT_NAME
26+
IDENTIFIER
27+
PsiJavaToken:ID('a')
28+
TYPE_TAG
29+
PsiJavaToken::(':')
30+
PsiJavaToken:?('?')
31+
FUNCTION_TYPE
32+
TYPE_OR_ANONYMOUS
33+
TYPE
34+
REFERENCE_EXPRESSION
35+
IDENTIFIER
36+
PsiJavaToken:ID('Int')
37+
PsiJavaToken:->('->')
38+
TYPE_OR_ANONYMOUS
39+
TYPE
40+
REFERENCE_EXPRESSION
41+
IDENTIFIER
42+
PsiJavaToken:ID('Void')
43+
PsiJavaToken:;(';')
44+
LOCAL_VAR_DECLARATION
45+
PsiJavaToken:var('var')
46+
LOCAL_VAR_DECLARATION_PART
47+
COMPONENT_NAME
48+
IDENTIFIER
49+
PsiJavaToken:ID('b')
50+
TYPE_TAG
51+
PsiJavaToken::(':')
52+
FUNCTION_TYPE
53+
FUNCTION_TYPE
54+
TYPE_OR_ANONYMOUS
55+
TYPE
56+
REFERENCE_EXPRESSION
57+
IDENTIFIER
58+
PsiJavaToken:ID('Int')
59+
PsiJavaToken:->('->')
60+
PsiJavaToken:?('?')
61+
TYPE_OR_ANONYMOUS
62+
TYPE
63+
REFERENCE_EXPRESSION
64+
IDENTIFIER
65+
PsiJavaToken:ID('Float')
66+
PsiJavaToken:->('->')
67+
TYPE_OR_ANONYMOUS
68+
TYPE
69+
REFERENCE_EXPRESSION
70+
IDENTIFIER
71+
PsiJavaToken:ID('Void')
72+
PsiJavaToken:;(';')
73+
PsiJavaToken:}('}')
74+
PsiJavaToken:}('}')

testSrc/com/intellij/plugins/haxe/lang/parser/expressions/ExpressionTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ public void testTypeCheck() throws Throwable {
8686
public void testIssue544() throws Throwable {
8787
doTest(true);
8888
}
89+
public void testOptionalVarOnFunctionType() throws Throwable {
90+
doTest(true);
91+
}
8992

9093
public void testShiftRightAssign() throws Throwable {
9194
doTest(true);

0 commit comments

Comments
 (0)