diff --git a/.idea/runConfigurations/Local_IDE.xml b/.idea/runConfigurations/Local_IDE.xml
index de09ed9fa..273c13062 100644
--- a/.idea/runConfigurations/Local_IDE.xml
+++ b/.idea/runConfigurations/Local_IDE.xml
@@ -1,6 +1,6 @@
-
+
@@ -11,11 +11,14 @@
-
+ true
+ true
+ false
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 45ae7904f..bbd4252fc 100644
--- a/build.gradle
+++ b/build.gradle
@@ -31,7 +31,7 @@ allprojects {
apply plugin: 'org.jetbrains.intellij'
intellij {
version = ideaVersion
- plugins = ['copyright', 'java']
+ plugins = ['copyright', 'java', psiViewerPlugin]
downloadSources = Boolean.valueOf(sources)
sameSinceUntilBuild = Boolean.valueOf(isEAP)
}
@@ -57,6 +57,9 @@ allprojects {
systemProperties = [
"erlang.sdk.path": System.getProperty("erlang.sdk.path")
]
+ runIde {
+ jvmArgs '-Xmx2G'
+ }
}
}
diff --git a/gen/org/intellij/erlang/ErlangTypes.java b/gen/org/intellij/erlang/ErlangTypes.java
index 4e2cf686d..08fad331a 100644
--- a/gen/org/intellij/erlang/ErlangTypes.java
+++ b/gen/org/intellij/erlang/ErlangTypes.java
@@ -60,6 +60,7 @@ public interface ErlangTypes {
IElementType ERL_FUN_CLAUSE = new ErlangCompositeElementType("ERL_FUN_CLAUSE");
IElementType ERL_FUN_CLAUSES = new ErlangCompositeElementType("ERL_FUN_CLAUSES");
IElementType ERL_FUN_EXPRESSION = new ErlangCompositeElementType("ERL_FUN_EXPRESSION");
+ IElementType ERL_FUN_REF_EXPRESSION = new ErlangCompositeElementType("ERL_FUN_REF_EXPRESSION");
IElementType ERL_FUN_TYPE = new ErlangCompositeElementType("ERL_FUN_TYPE");
IElementType ERL_FUN_TYPE_100_T = new ErlangCompositeElementType("ERL_FUN_TYPE_100_T");
IElementType ERL_FUN_TYPE_ARGUMENTS = new ErlangCompositeElementType("ERL_FUN_TYPE_ARGUMENTS");
@@ -173,6 +174,7 @@ public interface ErlangTypes {
IElementType ERL_END = new ErlangTokenType("end");
IElementType ERL_FLOAT = new ErlangTokenType("float");
IElementType ERL_FUN = new ErlangTokenType("fun");
+ IElementType ERL_FUNEXPR_FUN = new ErlangTokenType("$$fun_ref_expr");
IElementType ERL_IF = new ErlangTokenType("if");
IElementType ERL_INTEGER = new ErlangTokenType("integer");
IElementType ERL_MATCH = new ErlangTokenType(":=");
@@ -366,6 +368,9 @@ else if (type == ERL_FUN_CLAUSES) {
else if (type == ERL_FUN_EXPRESSION) {
return new ErlangFunExpressionImpl(node);
}
+ else if (type == ERL_FUN_REF_EXPRESSION) {
+ return new ErlangFunRefExpressionImpl(node);
+ }
else if (type == ERL_FUN_TYPE) {
return new ErlangFunTypeImpl(node);
}
diff --git a/gen/org/intellij/erlang/parser/ErlangParser.java b/gen/org/intellij/erlang/parser/ErlangParser.java
index 3301ee9ae..72f2483a1 100644
--- a/gen/org/intellij/erlang/parser/ErlangParser.java
+++ b/gen/org/intellij/erlang/parser/ErlangParser.java
@@ -44,12 +44,12 @@ static boolean parse_root_(IElementType t, PsiBuilder b, int l) {
ERL_ATOM_WITH_ARITY_EXPRESSION, ERL_BEGIN_END_EXPRESSION, ERL_BINARY_EXPRESSION, ERL_CASE_EXPRESSION,
ERL_CATCH_EXPRESSION, ERL_COLON_QUALIFIED_EXPRESSION, ERL_COMP_OP_EXPRESSION, ERL_CONFIG_CALL_EXPRESSION,
ERL_CONFIG_EXPRESSION, ERL_EXPRESSION, ERL_FUNCTION_CALL_EXPRESSION, ERL_FUN_EXPRESSION,
- ERL_GENERIC_FUNCTION_CALL_EXPRESSION, ERL_GLOBAL_FUNCTION_CALL_EXPRESSION, ERL_IF_EXPRESSION, ERL_LC_EXPRESSION,
- ERL_LIST_COMPREHENSION, ERL_LIST_EXPRESSION, ERL_LIST_OP_EXPRESSION, ERL_MAP_EXPRESSION,
- ERL_MAX_EXPRESSION, ERL_MAYBE_EXPRESSION, ERL_MAYBE_MATCH_EXPRESSION, ERL_MULTIPLICATIVE_EXPRESSION,
- ERL_ORELSE_EXPRESSION, ERL_PARENTHESIZED_EXPRESSION, ERL_PREFIX_EXPRESSION, ERL_QUALIFIED_EXPRESSION,
- ERL_RECEIVE_EXPRESSION, ERL_RECORD_EXPRESSION, ERL_SEND_EXPRESSION, ERL_STRING_LITERAL,
- ERL_TRY_EXPRESSION, ERL_TUPLE_EXPRESSION),
+ ERL_FUN_REF_EXPRESSION, ERL_GENERIC_FUNCTION_CALL_EXPRESSION, ERL_GLOBAL_FUNCTION_CALL_EXPRESSION, ERL_IF_EXPRESSION,
+ ERL_LC_EXPRESSION, ERL_LIST_COMPREHENSION, ERL_LIST_EXPRESSION, ERL_LIST_OP_EXPRESSION,
+ ERL_MAP_EXPRESSION, ERL_MAX_EXPRESSION, ERL_MAYBE_EXPRESSION, ERL_MAYBE_MATCH_EXPRESSION,
+ ERL_MULTIPLICATIVE_EXPRESSION, ERL_ORELSE_EXPRESSION, ERL_PARENTHESIZED_EXPRESSION, ERL_PREFIX_EXPRESSION,
+ ERL_QUALIFIED_EXPRESSION, ERL_RECEIVE_EXPRESSION, ERL_RECORD_EXPRESSION, ERL_SEND_EXPRESSION,
+ ERL_STRING_LITERAL, ERL_TRY_EXPRESSION, ERL_TUPLE_EXPRESSION),
};
/* ********************************************************** */
@@ -1646,15 +1646,15 @@ private static boolean config_exprs_1_0(PsiBuilder b, int l) {
}
/* ********************************************************** */
- // fun fun_expression_lambda
+ // '$$fun_ref_expr' fun_ref_expression_body
public static boolean config_fun_expression(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "config_fun_expression")) return false;
- if (!nextTokenIs(b, "", ERL_FUN)) return false;
+ if (!nextTokenIs(b, "", ERL_FUNEXPR_FUN)) return false;
boolean r, p;
- Marker m = enter_section_(b, l, _NONE_, ERL_FUN_EXPRESSION, "");
- r = consumeToken(b, ERL_FUN);
+ Marker m = enter_section_(b, l, _NONE_, ERL_FUN_REF_EXPRESSION, "");
+ r = consumeToken(b, ERL_FUNEXPR_FUN);
p = r; // pin = 1
- r = r && fun_expression_lambda(b, l + 1);
+ r = r && fun_ref_expression_body(b, l + 1);
exit_section_(b, l, m, r, p, null);
return r || p;
}
@@ -2475,75 +2475,102 @@ private static boolean fun_clauses_1_0(PsiBuilder b, int l) {
}
/* ********************************************************** */
- // fun (fun_expression_block | fun_expression_lambda)
+ // fun_clauses end
+ static boolean fun_clauses_end(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fun_clauses_end")) return false;
+ if (!nextTokenIs(b, "", ERL_PAR_LEFT, ERL_VAR)) return false;
+ boolean r, p;
+ Marker m = enter_section_(b, l, _NONE_);
+ r = fun_clauses(b, l + 1);
+ p = r; // pin = 1
+ r = r && consumeToken(b, ERL_END);
+ exit_section_(b, l, m, r, p, null);
+ return r || p;
+ }
+
+ /* ********************************************************** */
+ // fun fun_clauses_end
public static boolean fun_expression(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "fun_expression")) return false;
if (!nextTokenIs(b, "", ERL_FUN)) return false;
- boolean r, p;
+ boolean r;
Marker m = enter_section_(b, l, _NONE_, ERL_FUN_EXPRESSION, "");
r = consumeToken(b, ERL_FUN);
- p = r; // pin = 1
- r = r && fun_expression_1(b, l + 1);
- exit_section_(b, l, m, r, p, null);
- return r || p;
+ r = r && fun_clauses_end(b, l + 1);
+ exit_section_(b, l, m, r, false, null);
+ return r;
}
- // fun_expression_block | fun_expression_lambda
- private static boolean fun_expression_1(PsiBuilder b, int l) {
- if (!recursion_guard_(b, l, "fun_expression_1")) return false;
+ /* ********************************************************** */
+ // fun_name_var
+ public static boolean fun_name(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fun_name")) return false;
+ if (!nextTokenIs(b, ERL_VAR)) return false;
boolean r;
- r = fun_expression_block(b, l + 1);
- if (!r) r = fun_expression_lambda(b, l + 1);
+ Marker m = enter_section_(b);
+ r = fun_name_var(b, l + 1);
+ exit_section_(b, m, ERL_ARGUMENT_DEFINITION, r);
return r;
}
/* ********************************************************** */
- // fun_clauses end
- static boolean fun_expression_block(PsiBuilder b, int l) {
- if (!recursion_guard_(b, l, "fun_expression_block")) return false;
- if (!nextTokenIs(b, "", ERL_PAR_LEFT, ERL_VAR)) return false;
- boolean r, p;
- Marker m = enter_section_(b, l, _NONE_);
- r = fun_clauses(b, l + 1);
- p = r; // pin = 1
- r = r && consumeToken(b, ERL_END);
- exit_section_(b, l, m, r, p, null);
- return r || p;
+ // q_var
+ public static boolean fun_name_var(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fun_name_var")) return false;
+ if (!nextTokenIs(b, ERL_VAR)) return false;
+ boolean r;
+ Marker m = enter_section_(b);
+ r = q_var(b, l + 1);
+ exit_section_(b, m, ERL_MAX_EXPRESSION, r);
+ return r;
+ }
+
+ /* ********************************************************** */
+ // '$$fun_ref_expr' fun_ref_expression_body
+ public static boolean fun_ref_expression(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fun_ref_expression")) return false;
+ if (!nextTokenIs(b, "", ERL_FUNEXPR_FUN)) return false;
+ boolean r;
+ Marker m = enter_section_(b, l, _NONE_, ERL_FUN_REF_EXPRESSION, "");
+ r = consumeToken(b, ERL_FUNEXPR_FUN);
+ r = r && fun_ref_expression_body(b, l + 1);
+ exit_section_(b, l, m, r, false, null);
+ return r;
}
/* ********************************************************** */
// [(module_ref | q_var) ':'] (function_with_arity | function_with_arity_variables)
- static boolean fun_expression_lambda(PsiBuilder b, int l) {
- if (!recursion_guard_(b, l, "fun_expression_lambda")) return false;
+ static boolean fun_ref_expression_body(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fun_ref_expression_body")) return false;
boolean r;
Marker m = enter_section_(b);
- r = fun_expression_lambda_0(b, l + 1);
- r = r && fun_expression_lambda_1(b, l + 1);
+ r = fun_ref_expression_body_0(b, l + 1);
+ r = r && fun_ref_expression_body_1(b, l + 1);
exit_section_(b, m, null, r);
return r;
}
// [(module_ref | q_var) ':']
- private static boolean fun_expression_lambda_0(PsiBuilder b, int l) {
- if (!recursion_guard_(b, l, "fun_expression_lambda_0")) return false;
- fun_expression_lambda_0_0(b, l + 1);
+ private static boolean fun_ref_expression_body_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fun_ref_expression_body_0")) return false;
+ fun_ref_expression_body_0_0(b, l + 1);
return true;
}
// (module_ref | q_var) ':'
- private static boolean fun_expression_lambda_0_0(PsiBuilder b, int l) {
- if (!recursion_guard_(b, l, "fun_expression_lambda_0_0")) return false;
+ private static boolean fun_ref_expression_body_0_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fun_ref_expression_body_0_0")) return false;
boolean r;
Marker m = enter_section_(b);
- r = fun_expression_lambda_0_0_0(b, l + 1);
+ r = fun_ref_expression_body_0_0_0(b, l + 1);
r = r && consumeToken(b, ERL_COLON);
exit_section_(b, m, null, r);
return r;
}
// module_ref | q_var
- private static boolean fun_expression_lambda_0_0_0(PsiBuilder b, int l) {
- if (!recursion_guard_(b, l, "fun_expression_lambda_0_0_0")) return false;
+ private static boolean fun_ref_expression_body_0_0_0(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fun_ref_expression_body_0_0_0")) return false;
boolean r;
r = module_ref(b, l + 1);
if (!r) r = q_var(b, l + 1);
@@ -2551,38 +2578,14 @@ private static boolean fun_expression_lambda_0_0_0(PsiBuilder b, int l) {
}
// function_with_arity | function_with_arity_variables
- private static boolean fun_expression_lambda_1(PsiBuilder b, int l) {
- if (!recursion_guard_(b, l, "fun_expression_lambda_1")) return false;
+ private static boolean fun_ref_expression_body_1(PsiBuilder b, int l) {
+ if (!recursion_guard_(b, l, "fun_ref_expression_body_1")) return false;
boolean r;
r = function_with_arity(b, l + 1);
if (!r) r = function_with_arity_variables(b, l + 1);
return r;
}
- /* ********************************************************** */
- // fun_name_var
- public static boolean fun_name(PsiBuilder b, int l) {
- if (!recursion_guard_(b, l, "fun_name")) return false;
- if (!nextTokenIs(b, ERL_VAR)) return false;
- boolean r;
- Marker m = enter_section_(b);
- r = fun_name_var(b, l + 1);
- exit_section_(b, m, ERL_ARGUMENT_DEFINITION, r);
- return r;
- }
-
- /* ********************************************************** */
- // q_var
- public static boolean fun_name_var(PsiBuilder b, int l) {
- if (!recursion_guard_(b, l, "fun_name_var")) return false;
- if (!nextTokenIs(b, ERL_VAR)) return false;
- boolean r;
- Marker m = enter_section_(b);
- r = q_var(b, l + 1);
- exit_section_(b, m, ERL_MAX_EXPRESSION, r);
- return r;
- }
-
/* ********************************************************** */
// fun_type_arguments top_type_clause
public static boolean fun_type(PsiBuilder b, int l) {
@@ -6317,7 +6320,7 @@ private static boolean qualified_expression_3(PsiBuilder b, int l) {
// | map_comprehension
// | map_construct_expression
// | receive_expression
- // | fun_expression
+ // | fun_expression | fun_ref_expression
// | try_expression
// | maybe_expression
// | binary_expression
@@ -6337,6 +6340,7 @@ public static boolean max_expression(PsiBuilder b, int l) {
if (!r) r = map_construct_expression(b, l + 1);
if (!r) r = receive_expression(b, l + 1);
if (!r) r = fun_expression(b, l + 1);
+ if (!r) r = fun_ref_expression(b, l + 1);
if (!r) r = try_expression(b, l + 1);
if (!r) r = maybe_expression(b, l + 1);
if (!r) r = binary_expression(b, l + 1);
diff --git a/gen/org/intellij/erlang/parser/_ErlangLexer.java b/gen/org/intellij/erlang/parser/_ErlangLexer.java
index 6894e781c..63f6fe11b 100644
--- a/gen/org/intellij/erlang/parser/_ErlangLexer.java
+++ b/gen/org/intellij/erlang/parser/_ErlangLexer.java
@@ -53,11 +53,11 @@ public static int ZZ_CMAP(int ch) {
/* The ZZ_CMAP_A table has 384 entries */
static final char ZZ_CMAP_A[] = zzUnpackCMap(
- "\1\1\10\0\1\1\1\6\2\0\1\4\21\0\2\1\1\3\1\22\1\2\1\41\1\5\1\0\1\33\1\70\1\71"+
- "\1\64\1\63\1\43\1\14\1\15\1\65\10\17\2\11\1\60\1\73\1\62\1\42\1\61\1\67\1"+
- "\20\4\7\1\12\25\7\1\34\1\16\1\36\1\21\1\44\1\40\1\45\1\23\1\53\1\24\1\13\1"+
- "\25\1\50\1\47\1\51\2\10\1\57\1\56\1\26\1\52\2\10\1\27\1\30\1\31\1\54\1\32"+
- "\1\46\1\66\1\55\1\10\1\35\1\72\1\37\42\0\1\1\337\0");
+ "\1\1\10\0\1\1\1\6\2\0\1\4\21\0\2\1\1\3\1\22\1\2\1\41\1\5\1\0\1\33\1\45\1\71"+
+ "\1\66\1\65\1\43\1\14\1\15\1\47\10\17\2\11\1\46\1\73\1\64\1\42\1\63\1\70\1"+
+ "\20\4\7\1\12\25\7\1\34\1\16\1\36\1\21\1\44\1\40\1\50\1\23\1\56\1\24\1\13\1"+
+ "\25\1\53\1\52\1\54\2\10\1\62\1\61\1\26\1\55\2\10\1\27\1\30\1\31\1\57\1\32"+
+ "\1\51\1\67\1\60\1\10\1\35\1\72\1\37\42\0\1\1\337\0");
/**
* Translates DFA states to action switch labels.
@@ -67,23 +67,24 @@ public static int ZZ_CMAP(int ch) {
private static final String ZZ_ACTION_PACKED_0 =
"\2\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7"+
"\1\10\1\7\1\11\1\12\1\1\6\7\1\13\1\14"+
- "\1\15\1\16\1\17\1\20\1\21\1\22\6\7\1\23"+
- "\1\24\1\25\1\26\1\27\1\30\1\7\1\31\1\32"+
+ "\1\15\1\16\1\17\1\20\1\21\1\22\1\23\1\24"+
+ "\1\25\6\7\1\26\1\27\1\30\1\31\1\7\1\32"+
"\1\33\1\34\1\35\1\7\1\1\1\36\1\37\1\5"+
"\1\40\1\0\1\10\1\0\2\7\1\41\1\42\1\43"+
- "\2\0\1\44\14\7\2\20\1\45\1\0\1\46\1\47"+
- "\1\0\3\7\1\50\1\51\1\52\2\7\1\53\1\54"+
- "\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\7"+
- "\1\64\1\65\2\0\1\40\1\66\2\10\1\67\1\70"+
- "\1\7\1\71\2\7\1\72\1\73\1\7\1\74\1\7"+
- "\1\75\1\76\1\77\1\7\1\100\1\101\1\20\1\0"+
- "\1\102\1\103\1\7\1\104\5\7\1\105\1\0\1\106"+
- "\1\7\1\107\1\110\1\111\1\7\1\20\2\7\1\112"+
- "\1\7\1\113\2\7\1\67\1\0\1\114\1\7\1\115"+
- "\2\7\1\116\1\117\2\7\1\120\1\121\1\122";
+ "\2\0\1\44\14\7\2\20\1\45\2\0\1\46\1\47"+
+ "\1\50\1\51\1\52\3\7\1\53\1\54\1\55\2\7"+
+ "\1\56\1\57\1\60\1\61\1\62\1\63\1\7\1\64"+
+ "\1\65\2\0\1\40\1\66\2\10\1\67\1\70\1\7"+
+ "\1\71\2\7\1\72\1\73\1\7\1\74\1\7\1\75"+
+ "\1\7\1\76\1\7\1\77\1\100\1\20\1\0\1\101"+
+ "\1\102\1\7\1\103\5\7\1\104\1\0\1\105\1\7"+
+ "\1\106\1\107\1\110\1\0\1\111\1\7\1\20\2\7"+
+ "\1\112\1\7\1\113\2\7\1\67\1\0\1\114\3\0"+
+ "\1\7\1\115\2\7\1\116\1\117\1\0\1\120\1\0"+
+ "\2\7\1\121\1\122\1\123";
private static int [] zzUnpackAction() {
- int [] result = new int[166];
+ int [] result = new int[174];
int offset = 0;
offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
return result;
@@ -111,27 +112,28 @@ private static int zzUnpackAction(String packed, int offset, int [] result) {
"\0\0\0\74\0\170\0\264\0\360\0\170\0\u012c\0\u0168"+
"\0\u01a4\0\u01e0\0\u021c\0\u0258\0\u0294\0\u02d0\0\u030c\0\u0348"+
"\0\u0384\0\u03c0\0\u03fc\0\u0438\0\u0474\0\170\0\170\0\170"+
- "\0\170\0\u04b0\0\u04ec\0\170\0\u0528\0\u0564\0\u05a0\0\u05dc"+
- "\0\u0618\0\u0654\0\u0690\0\u06cc\0\u0708\0\u0744\0\170\0\u0780"+
- "\0\u07bc\0\u07f8\0\170\0\170\0\u0834\0\170\0\u0870\0\u08ac"+
+ "\0\170\0\u04b0\0\u04ec\0\170\0\170\0\u0528\0\u0564\0\u05a0"+
+ "\0\u05dc\0\u0618\0\u0654\0\u0690\0\u06cc\0\u0708\0\u0744\0\u0780"+
+ "\0\170\0\u07bc\0\u07f8\0\170\0\u0834\0\170\0\u0870\0\u08ac"+
"\0\170\0\u08e8\0\u0924\0\u0960\0\u099c\0\u09d8\0\u0a14\0\u0a50"+
"\0\u0a8c\0\170\0\170\0\u0ac8\0\u02d0\0\u0b04\0\170\0\u0b40"+
"\0\u0b7c\0\u0bb8\0\u0bf4\0\u0c30\0\u0c6c\0\u0ca8\0\u0ce4\0\u0d20"+
- "\0\u0d5c\0\u0d98\0\170\0\170\0\u0dd4\0\170\0\u0e10\0\170"+
- "\0\170\0\u0e4c\0\u0e88\0\u0ec4\0\u0f00\0\u01a4\0\u01a4\0\u0f3c"+
- "\0\u0f78\0\u0fb4\0\170\0\170\0\170\0\170\0\170\0\170"+
+ "\0\u0d5c\0\u0d98\0\170\0\170\0\u0dd4\0\170\0\u0e10\0\u0e4c"+
+ "\0\170\0\170\0\170\0\170\0\170\0\u0e88\0\u0ec4\0\u0f00"+
+ "\0\u01a4\0\u01a4\0\u0f3c\0\u0f78\0\u0fb4\0\170\0\170\0\170"+
"\0\170\0\170\0\170\0\u0ff0\0\170\0\170\0\u08ac\0\u102c"+
"\0\u1068\0\u10a4\0\u099c\0\u10e0\0\u111c\0\u01a4\0\u1158\0\170"+
"\0\u1194\0\u11d0\0\u01a4\0\u01a4\0\u120c\0\u01a4\0\u1248\0\u01a4"+
- "\0\u01a4\0\u01a4\0\u1284\0\u01a4\0\u01a4\0\u12c0\0\u12fc\0\170"+
- "\0\170\0\u1338\0\u1374\0\u13b0\0\u13ec\0\u1428\0\u1464\0\u14a0"+
- "\0\u01a4\0\u14dc\0\u01a4\0\u1518\0\u01a4\0\u01a4\0\u01a4\0\u1554"+
- "\0\u1590\0\u15cc\0\u1608\0\u01a4\0\u1644\0\u01a4\0\u1680\0\u16bc"+
- "\0\u16f8\0\u16f8\0\u01a4\0\u1734\0\u01a4\0\u1770\0\u17ac\0\u01a4"+
- "\0\u01a4\0\u17e8\0\u1824\0\u01a4\0\u01a4\0\u01a4";
+ "\0\u1284\0\u01a4\0\u12c0\0\u01a4\0\u01a4\0\u12fc\0\u1338\0\170"+
+ "\0\170\0\u1374\0\u13b0\0\u13ec\0\u1428\0\u1464\0\u14a0\0\u14dc"+
+ "\0\u01a4\0\u1518\0\u01a4\0\u1554\0\u01a4\0\u01a4\0\u01a4\0\u1590"+
+ "\0\170\0\u15cc\0\u1608\0\u1644\0\u1680\0\u01a4\0\u16bc\0\u01a4"+
+ "\0\u16f8\0\u1734\0\u1770\0\u1770\0\u01a4\0\u17ac\0\u17e8\0\u1824"+
+ "\0\u1860\0\u01a4\0\u189c\0\u18d8\0\u01a4\0\u01a4\0\u1914\0\170"+
+ "\0\u1950\0\u198c\0\u19c8\0\u01a4\0\u01a4\0\u01a4";
private static int [] zzUnpackRowMap() {
- int [] result = new int[166];
+ int [] result = new int[174];
int offset = 0;
offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
return result;
@@ -158,130 +160,157 @@ private static int zzUnpackRowMap(String packed, int offset, int [] result) {
"\1\11\1\12\1\10\1\13\1\14\1\15\1\3\1\12"+
"\2\3\1\16\1\17\1\20\1\21\1\22\1\23\1\11"+
"\1\24\1\11\1\25\1\26\1\27\1\30\1\31\1\3"+
- "\1\32\1\33\1\34\1\10\1\35\1\36\2\11\1\37"+
- "\1\40\1\41\2\11\1\42\1\11\1\43\1\44\1\45"+
+ "\1\32\1\33\1\34\1\10\1\35\1\36\1\37\1\40"+
+ "\1\41\2\11\1\42\1\43\1\44\2\11\1\45\1\11"+
"\1\46\1\47\1\50\1\51\1\52\1\53\1\54\1\55"+
"\1\56\16\57\1\60\14\57\1\61\40\57\75\0\1\4"+
"\4\0\1\4\70\0\1\62\70\0\4\63\1\0\1\64"+
"\1\0\65\63\7\0\5\10\3\0\2\10\2\0\10\10"+
- "\11\0\14\10\6\0\1\10\14\0\5\11\3\0\2\11"+
- "\2\0\10\11\11\0\14\11\6\0\1\11\7\0\1\65"+
- "\6\0\1\66\3\0\1\67\1\0\1\66\63\0\5\11"+
- "\3\0\2\11\2\0\3\11\1\70\4\11\11\0\13\11"+
- "\1\71\6\0\1\11\21\0\1\72\44\0\1\73\27\0"+
- "\1\74\56\0\16\75\1\76\3\75\1\77\51\75\7\0"+
- "\4\11\1\100\3\0\2\11\2\0\3\11\1\101\1\11"+
- "\1\102\2\11\11\0\1\11\1\103\4\11\1\104\5\11"+
- "\6\0\1\105\14\0\5\11\3\0\2\11\2\0\10\11"+
- "\11\0\5\11\1\106\6\11\6\0\1\11\14\0\5\11"+
- "\3\0\2\11\2\0\10\11\11\0\10\11\1\107\3\11"+
- "\6\0\1\11\14\0\5\11\3\0\2\11\2\0\10\11"+
- "\11\0\6\11\1\110\5\11\6\0\1\11\14\0\4\11"+
- "\1\111\3\0\2\11\2\0\10\11\11\0\14\11\6\0"+
- "\1\11\14\0\5\11\3\0\2\11\2\0\4\11\1\112"+
- "\3\11\11\0\14\11\6\0\1\11\40\0\1\113\40\0"+
- "\6\114\1\0\7\114\1\115\55\114\42\0\1\116\15\0"+
- "\1\117\1\120\1\121\2\0\1\122\15\0\5\11\3\0"+
- "\2\11\2\0\2\11\1\123\1\124\4\11\11\0\14\11"+
- "\6\0\1\11\14\0\5\11\3\0\2\11\2\0\10\11"+
- "\11\0\3\11\1\125\10\11\6\0\1\11\14\0\5\11"+
- "\3\0\2\11\2\0\2\11\1\126\5\11\11\0\14\11"+
- "\6\0\1\11\14\0\5\11\3\0\2\11\2\0\2\11"+
- "\1\127\1\11\1\130\3\11\11\0\14\11\6\0\1\11"+
- "\14\0\5\11\3\0\2\11\2\0\10\11\11\0\1\11"+
- "\1\131\12\11\6\0\1\11\14\0\5\11\3\0\2\11"+
- "\2\0\10\11\11\0\1\11\1\132\12\11\6\0\1\11"+
- "\47\0\1\133\15\0\1\134\55\0\1\135\16\0\1\136"+
- "\26\0\1\137\25\0\1\140\17\0\1\141\74\0\1\142"+
- "\52\0\1\143\40\0\5\11\3\0\2\11\2\0\10\11"+
- "\11\0\6\11\1\144\5\11\6\0\1\11\47\0\1\145"+
- "\123\0\1\146\1\0\16\57\1\147\14\57\1\0\40\57"+
- "\5\0\1\57\5\0\1\57\1\0\3\57\1\0\1\150"+
- "\23\57\27\0\4\62\1\0\1\62\1\0\65\62\4\63"+
- "\1\0\1\63\1\0\65\63\4\151\1\0\1\152\1\0"+
- "\65\151\7\0\5\153\3\0\1\153\3\0\10\153\12\0"+
- "\13\153\6\0\1\153\7\0\1\65\6\0\1\154\3\0"+
- "\1\67\1\0\1\154\65\0\1\155\5\0\1\155\63\0"+
- "\5\11\3\0\2\11\2\0\1\11\1\156\6\11\11\0"+
- "\14\11\6\0\1\11\14\0\5\11\3\0\2\11\2\0"+
- "\5\11\1\157\2\11\11\0\14\11\6\0\1\11\22\0"+
- "\1\160\56\0\74\75\7\0\5\11\3\0\2\11\2\0"+
- "\10\11\11\0\4\11\1\161\7\11\6\0\1\11\14\0"+
- "\5\11\3\0\2\11\2\0\10\11\11\0\6\11\1\162"+
- "\5\11\6\0\1\11\14\0\5\11\3\0\2\11\2\0"+
- "\4\11\1\163\3\11\11\0\13\11\1\164\6\0\1\11"+
- "\14\0\5\11\3\0\2\11\2\0\3\11\1\165\4\11"+
- "\11\0\14\11\6\0\1\11\14\0\5\11\3\0\2\11"+
- "\2\0\4\11\1\166\3\11\11\0\14\11\6\0\1\11"+
- "\14\0\5\11\3\0\2\11\2\0\10\11\11\0\6\11"+
- "\1\167\5\11\6\0\1\11\14\0\5\11\3\0\2\11"+
- "\2\0\7\11\1\170\11\0\14\11\6\0\1\11\14\0"+
- "\5\11\3\0\2\11\2\0\3\11\1\171\4\11\11\0"+
- "\14\11\6\0\1\11\14\0\5\11\3\0\2\11\2\0"+
- "\6\11\1\172\1\11\11\0\14\11\6\0\1\11\14\0"+
- "\5\11\3\0\2\11\2\0\10\11\11\0\7\11\1\173"+
- "\2\11\1\174\1\11\6\0\1\11\14\0\5\11\3\0"+
- "\2\11\2\0\10\11\11\0\11\11\1\175\2\11\6\0"+
- "\1\11\6\0\1\114\3\0\2\114\4\0\1\114\1\0"+
- "\2\114\1\176\1\0\1\177\23\114\71\0\1\200\73\0"+
- "\1\201\40\0\5\11\3\0\2\11\2\0\6\11\1\202"+
- "\1\11\11\0\14\11\6\0\1\11\14\0\5\11\3\0"+
- "\2\11\2\0\1\11\1\203\6\11\11\0\14\11\6\0"+
- "\1\11\14\0\4\11\1\204\3\0\2\11\2\0\10\11"+
- "\11\0\14\11\6\0\1\11\14\0\4\11\1\205\3\0"+
- "\2\11\2\0\10\11\11\0\14\11\6\0\1\11\14\0"+
- "\5\11\3\0\2\11\2\0\5\11\1\206\1\207\1\11"+
- "\11\0\14\11\6\0\1\11\14\0\5\11\3\0\2\11"+
- "\2\0\10\11\11\0\11\11\1\210\2\11\6\0\1\11"+
- "\14\0\5\11\3\0\2\11\2\0\4\11\1\211\3\11"+
- "\11\0\14\11\6\0\1\11\14\0\1\57\2\0\1\57"+
- "\3\0\1\57\1\0\2\57\12\0\1\57\1\0\1\57"+
- "\5\0\1\57\27\0\4\151\1\0\1\151\1\0\65\151"+
- "\4\152\1\0\1\152\1\0\65\152\11\0\1\154\3\0"+
- "\1\67\1\0\1\154\65\0\1\155\2\212\3\0\1\155"+
- "\63\0\4\11\1\213\3\0\2\11\2\0\10\11\11\0"+
- "\14\11\6\0\1\11\14\0\5\11\3\0\2\11\2\0"+
- "\10\11\11\0\5\11\1\214\6\11\6\0\1\11\14\0"+
- "\5\11\3\0\2\11\2\0\6\11\1\215\1\11\11\0"+
- "\14\11\6\0\1\11\14\0\5\11\3\0\2\11\2\0"+
- "\1\11\1\216\6\11\11\0\14\11\6\0\1\11\14\0"+
- "\5\11\3\0\2\11\2\0\4\11\1\217\3\11\11\0"+
- "\14\11\6\0\1\11\14\0\4\11\1\220\3\0\2\11"+
- "\2\0\10\11\11\0\14\11\6\0\1\11\24\0\1\221"+
- "\63\0\1\114\2\0\1\114\3\0\1\114\1\0\2\114"+
- "\12\0\1\114\1\0\1\114\5\0\1\114\36\0\4\11"+
- "\1\222\3\0\2\11\2\0\10\11\11\0\14\11\6\0"+
- "\1\11\14\0\5\11\3\0\2\11\2\0\10\11\11\0"+
- "\1\11\1\223\12\11\6\0\1\11\14\0\5\11\3\0"+
- "\2\11\2\0\3\11\1\224\4\11\11\0\14\11\6\0"+
- "\1\11\14\0\5\11\3\0\2\11\2\0\10\11\11\0"+
- "\13\11\1\225\6\0\1\11\14\0\4\11\1\226\3\0"+
- "\2\11\2\0\10\11\11\0\14\11\6\0\1\11\14\0"+
- "\5\11\3\0\2\11\2\0\10\11\11\0\7\11\1\227"+
- "\4\11\6\0\1\11\14\0\5\11\3\0\2\11\2\0"+
- "\1\230\7\11\11\0\14\11\6\0\1\11\16\0\1\231"+
- "\2\0\1\232\2\0\1\231\43\0\1\232\17\0\5\11"+
- "\3\0\2\11\2\0\3\11\1\233\4\11\11\0\14\11"+
- "\6\0\1\11\14\0\5\11\3\0\2\11\2\0\10\11"+
- "\11\0\5\11\1\234\6\11\6\0\1\11\24\0\1\114"+
- "\63\0\5\11\3\0\2\11\2\0\4\11\1\235\3\11"+
- "\11\0\14\11\6\0\1\11\14\0\5\11\3\0\2\11"+
- "\2\0\10\11\11\0\13\11\1\236\6\0\1\11\14\0"+
- "\5\11\3\0\2\11\2\0\5\11\1\237\2\11\11\0"+
- "\14\11\6\0\1\11\14\0\5\11\3\0\2\11\2\0"+
- "\10\11\11\0\3\11\1\240\10\11\6\0\1\11\14\0"+
- "\4\11\1\241\3\0\2\11\2\0\10\11\11\0\14\11"+
- "\6\0\1\11\16\0\1\231\5\0\1\231\63\0\5\11"+
- "\3\0\2\11\2\0\7\11\1\242\11\0\14\11\6\0"+
- "\1\11\14\0\5\11\3\0\2\11\2\0\5\11\1\243"+
- "\2\11\11\0\14\11\6\0\1\11\14\0\4\11\1\244"+
- "\3\0\2\11\2\0\10\11\11\0\14\11\6\0\1\11"+
- "\14\0\4\11\1\245\3\0\2\11\2\0\10\11\11\0"+
- "\14\11\6\0\1\11\14\0\5\11\3\0\2\11\2\0"+
- "\10\11\11\0\6\11\1\246\5\11\6\0\1\11\5\0";
+ "\11\0\1\10\3\0\13\10\4\0\1\10\13\0\5\11"+
+ "\3\0\2\11\2\0\10\11\11\0\1\11\3\0\13\11"+
+ "\4\0\1\11\6\0\1\65\6\0\1\66\3\0\1\67"+
+ "\1\0\1\66\63\0\5\11\3\0\2\11\2\0\3\11"+
+ "\1\70\4\11\11\0\1\11\3\0\12\11\1\71\4\0"+
+ "\1\11\20\0\1\72\46\0\1\73\25\0\1\74\56\0"+
+ "\16\75\1\76\3\75\1\77\51\75\7\0\4\11\1\100"+
+ "\3\0\2\11\2\0\3\11\1\101\1\11\1\102\2\11"+
+ "\11\0\1\11\3\0\1\103\4\11\1\104\5\11\4\0"+
+ "\1\105\13\0\5\11\3\0\2\11\2\0\10\11\11\0"+
+ "\1\11\3\0\4\11\1\106\6\11\4\0\1\11\13\0"+
+ "\5\11\3\0\2\11\2\0\10\11\11\0\1\11\3\0"+
+ "\7\11\1\107\3\11\4\0\1\11\13\0\5\11\3\0"+
+ "\2\11\2\0\10\11\11\0\1\11\3\0\5\11\1\110"+
+ "\5\11\4\0\1\11\13\0\4\11\1\111\3\0\2\11"+
+ "\2\0\10\11\11\0\1\11\3\0\13\11\4\0\1\11"+
+ "\13\0\5\11\3\0\2\11\2\0\4\11\1\112\3\11"+
+ "\11\0\1\11\3\0\13\11\4\0\1\11\37\0\1\113"+
+ "\40\0\6\114\1\0\7\114\1\115\55\114\42\0\1\116"+
+ "\3\0\1\117\1\120\13\0\1\121\1\122\51\0\1\123"+
+ "\3\0\1\124\67\0\1\125\40\0\5\11\3\0\2\11"+
+ "\2\0\2\11\1\126\1\127\4\11\11\0\1\11\3\0"+
+ "\13\11\4\0\1\11\13\0\5\11\3\0\2\11\2\0"+
+ "\10\11\11\0\1\11\3\0\2\11\1\130\10\11\4\0"+
+ "\1\11\13\0\5\11\3\0\2\11\2\0\2\11\1\131"+
+ "\5\11\11\0\1\11\3\0\13\11\4\0\1\11\13\0"+
+ "\5\11\3\0\2\11\2\0\2\11\1\132\1\11\1\133"+
+ "\3\11\11\0\1\11\3\0\13\11\4\0\1\11\13\0"+
+ "\5\11\3\0\2\11\2\0\10\11\11\0\1\11\3\0"+
+ "\1\134\12\11\4\0\1\11\13\0\5\11\3\0\2\11"+
+ "\2\0\10\11\11\0\1\11\3\0\1\135\12\11\4\0"+
+ "\1\11\46\0\1\136\20\0\1\137\24\0\1\140\25\0"+
+ "\1\141\21\0\1\142\74\0\1\143\15\0\5\11\3\0"+
+ "\2\11\2\0\10\11\11\0\1\11\3\0\5\11\1\144"+
+ "\5\11\4\0\1\11\46\0\1\145\123\0\1\146\1\0"+
+ "\16\57\1\147\14\57\1\0\40\57\5\0\1\57\5\0"+
+ "\1\57\1\0\3\57\1\0\1\150\23\57\27\0\4\62"+
+ "\1\0\1\62\1\0\65\62\4\63\1\0\1\63\1\0"+
+ "\65\63\4\151\1\0\1\152\1\0\65\151\7\0\5\153"+
+ "\3\0\1\153\3\0\10\153\15\0\13\153\4\0\1\153"+
+ "\6\0\1\65\6\0\1\154\3\0\1\67\1\0\1\154"+
+ "\65\0\1\155\5\0\1\155\63\0\5\11\3\0\2\11"+
+ "\2\0\1\11\1\156\6\11\11\0\1\11\3\0\13\11"+
+ "\4\0\1\11\13\0\5\11\3\0\2\11\2\0\5\11"+
+ "\1\157\2\11\11\0\1\11\3\0\13\11\4\0\1\11"+
+ "\21\0\1\160\56\0\74\75\7\0\5\11\3\0\2\11"+
+ "\2\0\10\11\11\0\1\11\3\0\3\11\1\161\7\11"+
+ "\4\0\1\11\13\0\5\11\3\0\2\11\2\0\10\11"+
+ "\11\0\1\11\3\0\5\11\1\162\5\11\4\0\1\11"+
+ "\13\0\5\11\3\0\2\11\2\0\4\11\1\163\3\11"+
+ "\11\0\1\11\3\0\12\11\1\164\4\0\1\11\13\0"+
+ "\5\11\3\0\2\11\2\0\3\11\1\165\4\11\11\0"+
+ "\1\11\3\0\13\11\4\0\1\11\13\0\5\11\3\0"+
+ "\2\11\2\0\4\11\1\166\3\11\11\0\1\11\3\0"+
+ "\13\11\4\0\1\11\13\0\5\11\3\0\2\11\2\0"+
+ "\10\11\11\0\1\11\3\0\5\11\1\167\5\11\4\0"+
+ "\1\11\13\0\5\11\3\0\2\11\2\0\7\11\1\170"+
+ "\11\0\1\11\3\0\13\11\4\0\1\11\13\0\5\11"+
+ "\3\0\2\11\2\0\3\11\1\171\4\11\11\0\1\11"+
+ "\3\0\13\11\4\0\1\11\13\0\5\11\3\0\2\11"+
+ "\2\0\6\11\1\172\1\11\11\0\1\11\3\0\13\11"+
+ "\4\0\1\11\13\0\5\11\3\0\2\11\2\0\10\11"+
+ "\11\0\1\11\3\0\6\11\1\173\2\11\1\174\1\11"+
+ "\4\0\1\11\13\0\5\11\3\0\2\11\2\0\10\11"+
+ "\11\0\1\11\3\0\10\11\1\175\2\11\4\0\1\11"+
+ "\5\0\1\114\3\0\2\114\4\0\1\114\1\0\2\114"+
+ "\1\176\1\0\1\177\23\114\71\0\1\200\73\0\1\201"+
+ "\40\0\5\11\3\0\2\11\2\0\6\11\1\202\1\11"+
+ "\11\0\1\11\3\0\13\11\4\0\1\11\13\0\5\11"+
+ "\3\0\2\11\2\0\1\11\1\203\6\11\11\0\1\11"+
+ "\3\0\13\11\4\0\1\11\13\0\4\11\1\204\3\0"+
+ "\2\11\2\0\10\11\11\0\1\11\3\0\13\11\4\0"+
+ "\1\11\13\0\4\11\1\205\3\0\2\11\2\0\10\11"+
+ "\11\0\1\11\3\0\13\11\4\0\1\11\13\0\5\11"+
+ "\3\0\2\11\2\0\5\11\1\206\1\207\1\11\11\0"+
+ "\1\11\3\0\13\11\4\0\1\11\13\0\5\11\3\0"+
+ "\2\11\2\0\10\11\11\0\1\11\3\0\10\11\1\210"+
+ "\2\11\4\0\1\11\13\0\5\11\3\0\2\11\2\0"+
+ "\4\11\1\211\3\11\11\0\1\11\3\0\13\11\4\0"+
+ "\1\11\13\0\1\57\2\0\1\57\3\0\1\57\1\0"+
+ "\2\57\12\0\1\57\1\0\1\57\5\0\1\57\27\0"+
+ "\4\151\1\0\1\151\1\0\65\151\4\152\1\0\1\152"+
+ "\1\0\65\152\11\0\1\154\3\0\1\67\1\0\1\154"+
+ "\65\0\1\155\2\212\3\0\1\155\63\0\4\11\1\213"+
+ "\3\0\2\11\2\0\10\11\11\0\1\11\3\0\13\11"+
+ "\4\0\1\11\13\0\5\11\3\0\2\11\2\0\10\11"+
+ "\11\0\1\11\3\0\4\11\1\214\6\11\4\0\1\11"+
+ "\13\0\5\11\3\0\2\11\2\0\6\11\1\215\1\11"+
+ "\11\0\1\11\3\0\13\11\4\0\1\11\13\0\5\11"+
+ "\3\0\2\11\2\0\1\11\1\216\6\11\11\0\1\11"+
+ "\3\0\13\11\4\0\1\11\13\0\5\11\3\0\2\11"+
+ "\2\0\4\11\1\217\3\11\11\0\1\11\3\0\13\11"+
+ "\4\0\1\11\5\0\1\220\4\0\1\220\5\11\3\0"+
+ "\2\11\2\0\10\11\11\0\1\11\1\221\2\0\13\11"+
+ "\4\0\1\11\13\0\4\11\1\222\3\0\2\11\2\0"+
+ "\10\11\11\0\1\11\3\0\13\11\4\0\1\11\23\0"+
+ "\1\223\63\0\1\114\2\0\1\114\3\0\1\114\1\0"+
+ "\2\114\12\0\1\114\1\0\1\114\5\0\1\114\36\0"+
+ "\4\11\1\224\3\0\2\11\2\0\10\11\11\0\1\11"+
+ "\3\0\13\11\4\0\1\11\13\0\5\11\3\0\2\11"+
+ "\2\0\10\11\11\0\1\11\3\0\1\225\12\11\4\0"+
+ "\1\11\13\0\5\11\3\0\2\11\2\0\3\11\1\226"+
+ "\4\11\11\0\1\11\3\0\13\11\4\0\1\11\13\0"+
+ "\5\11\3\0\2\11\2\0\10\11\11\0\1\11\3\0"+
+ "\12\11\1\227\4\0\1\11\13\0\4\11\1\230\3\0"+
+ "\2\11\2\0\10\11\11\0\1\11\3\0\13\11\4\0"+
+ "\1\11\13\0\5\11\3\0\2\11\2\0\10\11\11\0"+
+ "\1\11\3\0\6\11\1\231\4\11\4\0\1\11\13\0"+
+ "\5\11\3\0\2\11\2\0\1\232\7\11\11\0\1\11"+
+ "\3\0\13\11\4\0\1\11\15\0\1\233\2\0\1\234"+
+ "\2\0\1\233\45\0\1\234\15\0\5\11\3\0\2\11"+
+ "\2\0\3\11\1\235\4\11\11\0\1\11\3\0\13\11"+
+ "\4\0\1\11\5\0\1\220\4\0\1\220\1\236\1\237"+
+ "\1\0\1\236\1\237\7\0\10\237\1\240\10\0\1\236"+
+ "\1\221\2\0\13\237\4\0\1\237\13\0\5\11\3\0"+
+ "\2\11\2\0\10\11\11\0\1\11\3\0\4\11\1\241"+
+ "\6\11\4\0\1\11\23\0\1\114\63\0\5\11\3\0"+
+ "\2\11\2\0\4\11\1\242\3\11\11\0\1\11\3\0"+
+ "\13\11\4\0\1\11\13\0\5\11\3\0\2\11\2\0"+
+ "\10\11\11\0\1\11\3\0\12\11\1\243\4\0\1\11"+
+ "\13\0\5\11\3\0\2\11\2\0\5\11\1\244\2\11"+
+ "\11\0\1\11\3\0\13\11\4\0\1\11\13\0\5\11"+
+ "\3\0\2\11\2\0\10\11\11\0\1\11\3\0\2\11"+
+ "\1\245\10\11\4\0\1\11\13\0\4\11\1\246\3\0"+
+ "\2\11\2\0\10\11\11\0\1\11\3\0\13\11\4\0"+
+ "\1\11\15\0\1\233\5\0\1\233\55\0\1\247\4\0"+
+ "\1\247\5\236\3\0\2\236\2\0\10\236\11\0\1\236"+
+ "\1\221\2\250\13\236\4\0\1\236\5\0\1\251\4\0"+
+ "\1\251\5\237\3\0\2\237\2\0\10\237\11\0\1\237"+
+ "\1\0\2\250\13\237\4\0\1\237\13\0\5\240\3\0"+
+ "\2\240\2\0\10\240\1\251\10\0\1\240\3\0\13\240"+
+ "\4\0\1\240\13\0\5\11\3\0\2\11\2\0\7\11"+
+ "\1\252\11\0\1\11\3\0\13\11\4\0\1\11\13\0"+
+ "\5\11\3\0\2\11\2\0\5\11\1\253\2\11\11\0"+
+ "\1\11\3\0\13\11\4\0\1\11\13\0\4\11\1\254"+
+ "\3\0\2\11\2\0\10\11\11\0\1\11\3\0\13\11"+
+ "\4\0\1\11\5\0\1\247\4\0\1\247\36\0\1\221"+
+ "\2\250\25\0\1\251\4\0\1\251\37\0\2\250\33\0"+
+ "\4\11\1\255\3\0\2\11\2\0\10\11\11\0\1\11"+
+ "\3\0\13\11\4\0\1\11\13\0\5\11\3\0\2\11"+
+ "\2\0\10\11\11\0\1\11\3\0\5\11\1\256\5\11"+
+ "\4\0\1\11\4\0";
private static int [] zzUnpackTrans() {
- int [] result = new int[6240];
+ int [] result = new int[6660];
int offset = 0;
offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
return result;
@@ -319,15 +348,16 @@ private static int zzUnpackTrans(String packed, int offset, int [] result) {
private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
private static final String ZZ_ATTRIBUTE_PACKED_0 =
- "\2\0\1\11\2\1\1\11\17\1\4\11\2\1\1\11"+
- "\12\1\1\11\3\1\2\11\1\1\1\11\2\1\1\11"+
+ "\2\0\1\11\2\1\1\11\17\1\4\11\2\1\2\11"+
+ "\13\1\1\11\2\1\1\11\1\1\1\11\2\1\1\11"+
"\3\1\1\0\1\1\1\0\2\1\2\11\1\1\2\0"+
- "\1\11\13\1\2\11\1\1\1\11\1\0\2\11\1\0"+
- "\10\1\11\11\1\1\2\11\2\0\7\1\1\11\16\1"+
- "\1\0\2\11\10\1\1\0\17\1\1\0\14\1";
+ "\1\11\13\1\2\11\1\1\1\11\2\0\5\11\10\1"+
+ "\6\11\1\1\2\11\2\0\7\1\1\11\16\1\1\0"+
+ "\2\11\10\1\1\0\5\1\1\0\1\11\12\1\1\0"+
+ "\1\1\3\0\6\1\1\0\1\11\1\0\5\1";
private static int [] zzUnpackAttribute() {
- int [] result = new int[166];
+ int [] result = new int[174];
int offset = 0;
offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
return result;
@@ -636,412 +666,423 @@ else if (zzAtEOF) {
{ yybegin(YYINITIAL); return com.intellij.psi.TokenType.BAD_CHARACTER;
}
// fall through
- case 83: break;
+ case 84: break;
case 2:
{ return com.intellij.psi.TokenType.WHITE_SPACE;
}
// fall through
- case 84: break;
+ case 85: break;
case 3:
{ return ERL_RADIX;
}
// fall through
- case 85: break;
+ case 86: break;
case 4:
{ return ERL_OP_EXL;
}
// fall through
- case 86: break;
+ case 87: break;
case 5:
{ return ERL_COMMENT;
}
// fall through
- case 87: break;
+ case 88: break;
case 6:
{ return ERL_VAR;
}
// fall through
- case 88: break;
+ case 89: break;
case 7:
{ return ERL_ATOM_NAME;
}
// fall through
- case 89: break;
+ case 90: break;
case 8:
{ return ERL_INTEGER;
}
// fall through
- case 90: break;
+ case 91: break;
case 9:
{ return ERL_OP_MINUS;
}
// fall through
- case 91: break;
+ case 92: break;
case 10:
{ return ERL_DOT;
}
// fall through
- case 92: break;
+ case 93: break;
case 11:
{ yybegin(IN_QUOTES); return ERL_SINGLE_QUOTE;
}
// fall through
- case 93: break;
+ case 94: break;
case 12:
{ return ERL_BRACKET_LEFT;
}
// fall through
- case 94: break;
+ case 95: break;
case 13:
{ return ERL_CURLY_LEFT;
}
// fall through
- case 95: break;
+ case 96: break;
case 14:
{ return ERL_BRACKET_RIGHT;
}
// fall through
- case 96: break;
+ case 97: break;
case 15:
{ return ERL_CURLY_RIGHT;
}
// fall through
- case 97: break;
+ case 98: break;
case 16:
{ return ERL_CHAR;
}
// fall through
- case 98: break;
+ case 99: break;
case 17:
{ return ERL_OP_EQ;
}
// fall through
- case 99: break;
+ case 100: break;
case 18:
{ return ERL_COMMA;
}
// fall through
- case 100: break;
+ case 101: break;
case 19:
- { return ERL_COLON;
+ { return ERL_PAR_LEFT;
}
// fall through
- case 101: break;
+ case 102: break;
case 20:
- { return ERL_OP_GT;
+ { return ERL_COLON;
}
// fall through
- case 102: break;
+ case 103: break;
case 21:
- { return ERL_OP_LT;
+ { return ERL_OP_AR_DIV;
}
// fall through
- case 103: break;
+ case 104: break;
case 22:
- { return ERL_OP_PLUS;
+ { return ERL_OP_GT;
}
// fall through
- case 104: break;
+ case 105: break;
case 23:
- { return ERL_OP_AR_MUL;
+ { return ERL_OP_LT;
}
// fall through
- case 105: break;
+ case 106: break;
case 24:
- { return ERL_OP_AR_DIV;
+ { return ERL_OP_PLUS;
}
// fall through
- case 106: break;
+ case 107: break;
case 25:
- { return ERL_QMARK;
+ { return ERL_OP_AR_MUL;
}
// fall through
- case 107: break;
+ case 108: break;
case 26:
- { return ERL_PAR_LEFT;
+ { return ERL_QMARK;
}
// fall through
- case 108: break;
+ case 109: break;
case 27:
{ return ERL_PAR_RIGHT;
}
// fall through
- case 109: break;
+ case 110: break;
case 28:
{ return ERL_OP_OR;
}
// fall through
- case 110: break;
+ case 111: break;
case 29:
{ return ERL_SEMI;
}
// fall through
- case 111: break;
+ case 112: break;
case 30:
{ yybegin(YYINITIAL); return ERL_SINGLE_QUOTE;
}
// fall through
- case 112: break;
+ case 113: break;
case 31:
{ return getTokenStart() == 0 ? ERL_SHEBANG : com.intellij.psi.TokenType.ERROR_ELEMENT;
}
// fall through
- case 113: break;
+ case 114: break;
case 32:
{ return ERL_FUNCTION_DOC_COMMENT;
}
// fall through
- case 114: break;
+ case 115: break;
case 33:
{ return ERL_OP_MINUS_MINUS;
}
// fall through
- case 115: break;
+ case 116: break;
case 34:
{ return ERL_ARROW;
}
// fall through
- case 116: break;
+ case 117: break;
case 35:
{ return ERL_DOT_DOT;
}
// fall through
- case 117: break;
+ case 118: break;
case 36:
{ return ERL_STRING;
}
// fall through
- case 118: break;
+ case 119: break;
case 37:
{ return ERL_OP_EQ_EQ;
}
// fall through
- case 119: break;
+ case 120: break;
case 38:
{ return ERL_ASSOC;
}
// fall through
- case 120: break;
+ case 121: break;
case 39:
{ return ERL_OP_EQ_LT;
}
// fall through
- case 121: break;
+ case 122: break;
case 40:
- { return ERL_IF;
+ { return ERL_MATCH;
}
// fall through
- case 122: break;
+ case 123: break;
case 41:
- { return ERL_OF;
+ { return ERL_COLON_COLON;
}
// fall through
- case 123: break;
+ case 124: break;
case 42:
- { return ERL_OR;
+ { return ERL_OP_DIV_EQ;
}
// fall through
- case 124: break;
+ case 125: break;
case 43:
- { return ERL_MATCH;
+ { return ERL_IF;
}
// fall through
- case 125: break;
+ case 126: break;
case 44:
- { return ERL_COLON_COLON;
+ { return ERL_OF;
}
// fall through
- case 126: break;
+ case 127: break;
case 45:
- { return ERL_OP_GT_EQ;
+ { return ERL_OR;
}
// fall through
- case 127: break;
+ case 128: break;
case 46:
- { return ERL_BIN_END;
+ { return ERL_OP_GT_EQ;
}
// fall through
- case 128: break;
+ case 129: break;
case 47:
- { return ERL_OP_LT_MINUS;
+ { return ERL_BIN_END;
}
// fall through
- case 129: break;
+ case 130: break;
case 48:
- { return ERL_OP_LT_EQ;
+ { return ERL_OP_LT_MINUS;
}
// fall through
- case 130: break;
+ case 131: break;
case 49:
- { return ERL_BIN_START;
+ { return ERL_OP_LT_EQ;
}
// fall through
- case 131: break;
+ case 132: break;
case 50:
- { return ERL_OP_PLUS_PLUS;
+ { return ERL_BIN_START;
}
// fall through
- case 132: break;
+ case 133: break;
case 51:
- { return ERL_OP_DIV_EQ;
+ { return ERL_OP_PLUS_PLUS;
}
// fall through
- case 133: break;
+ case 134: break;
case 52:
{ return ERL_OP_MAYBE_EQ;
}
// fall through
- case 134: break;
+ case 135: break;
case 53:
{ return ERL_OR_OR;
}
// fall through
- case 135: break;
+ case 136: break;
case 54:
{ return ERL_MODULE_DOC_COMMENT;
}
// fall through
- case 136: break;
+ case 137: break;
case 55:
{ return ERL_FLOAT;
}
// fall through
- case 137: break;
+ case 138: break;
case 56:
{ return ERL_END;
}
// fall through
- case 138: break;
+ case 139: break;
case 57:
{ return ERL_DOT_DOT_DOT;
}
// fall through
- case 139: break;
+ case 140: break;
case 58:
{ return ERL_BSR;
}
// fall through
- case 140: break;
+ case 141: break;
case 59:
{ return ERL_BSL;
}
// fall through
- case 141: break;
+ case 142: break;
case 60:
{ return ERL_BOR;
}
// fall through
- case 142: break;
+ case 143: break;
case 61:
{ return ERL_DIV;
}
// fall through
- case 143: break;
- case 62:
- { return ERL_FUN;
- }
- // fall through
case 144: break;
- case 63:
+ case 62:
{ return ERL_NOT;
}
// fall through
case 145: break;
- case 64:
+ case 63:
{ return ERL_REM;
}
// fall through
case 146: break;
- case 65:
+ case 64:
{ return ERL_TRY;
}
// fall through
case 147: break;
- case 66:
+ case 65:
{ return ERL_OP_EQ_COL_EQ;
}
// fall through
case 148: break;
- case 67:
+ case 66:
{ return ERL_OP_EQ_DIV_EQ;
}
// fall through
case 149: break;
- case 68:
+ case 67:
{ return ERL_AND;
}
// fall through
case 150: break;
- case 69:
+ case 68:
{ return ERL_XOR;
}
// fall through
case 151: break;
- case 70:
+ case 69:
{ return ERL_ELSE;
}
// fall through
case 152: break;
- case 71:
+ case 70:
{ return ERL_BNOT;
}
// fall through
case 153: break;
- case 72:
+ case 71:
{ return ERL_BAND;
}
// fall through
case 154: break;
- case 73:
+ case 72:
{ return ERL_BXOR;
}
// fall through
case 155: break;
+ case 73:
+ // lookahead expression with fixed base length
+ zzMarkedPos = Character.offsetByCodePoints
+ (zzBufferL/*, zzStartRead, zzEndRead - zzStartRead*/, zzStartRead, 3);
+ { return ERL_FUN;
+ }
+ // fall through
+ case 156: break;
case 74:
{ return ERL_WHEN;
}
// fall through
- case 156: break;
+ case 157: break;
case 75:
{ return ERL_CASE;
}
// fall through
- case 157: break;
+ case 158: break;
case 76:
{ return ERL_BEGIN;
}
// fall through
- case 158: break;
+ case 159: break;
case 77:
{ return ERL_AFTER;
}
// fall through
- case 159: break;
+ case 160: break;
case 78:
{ return ERL_CATCH;
}
// fall through
- case 160: break;
+ case 161: break;
case 79:
{ return ERL_MAYBE;
}
// fall through
- case 161: break;
+ case 162: break;
case 80:
- { return ERL_ORELSE;
+ // lookahead expression with fixed base length
+ zzMarkedPos = Character.offsetByCodePoints
+ (zzBufferL/*, zzStartRead, zzEndRead - zzStartRead*/, zzStartRead, 3);
+ { return ERL_FUNEXPR_FUN;
}
// fall through
- case 162: break;
+ case 163: break;
case 81:
- { return ERL_RECEIVE;
+ { return ERL_ORELSE;
}
// fall through
- case 163: break;
+ case 164: break;
case 82:
+ { return ERL_RECEIVE;
+ }
+ // fall through
+ case 165: break;
+ case 83:
{ return ERL_ANDALSO;
}
// fall through
- case 164: break;
+ case 166: break;
default:
zzScanError(ZZ_NO_MATCH);
}
diff --git a/gen/org/intellij/erlang/psi/ErlangFunExpression.java b/gen/org/intellij/erlang/psi/ErlangFunExpression.java
index 14e2cec30..28c6c94ae 100644
--- a/gen/org/intellij/erlang/psi/ErlangFunExpression.java
+++ b/gen/org/intellij/erlang/psi/ErlangFunExpression.java
@@ -9,24 +9,9 @@
public interface ErlangFunExpression extends ErlangExpression {
- @Nullable
+ @NotNull
ErlangFunClauses getFunClauses();
- @Nullable
- ErlangFunctionWithArity getFunctionWithArity();
-
- @Nullable
- ErlangFunctionWithArityVariables getFunctionWithArityVariables();
-
- @Nullable
- ErlangModuleRef getModuleRef();
-
- @Nullable
- ErlangQVar getQVar();
-
- @Nullable
- PsiElement getColon();
-
@Nullable
PsiElement getEnd();
diff --git a/gen/org/intellij/erlang/psi/ErlangFunRefExpression.java b/gen/org/intellij/erlang/psi/ErlangFunRefExpression.java
new file mode 100644
index 000000000..eaa2a3629
--- /dev/null
+++ b/gen/org/intellij/erlang/psi/ErlangFunRefExpression.java
@@ -0,0 +1,32 @@
+// This is a generated file. Not intended for manual editing.
+package org.intellij.erlang.psi;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.psi.PsiElement;
+
+public interface ErlangFunRefExpression extends ErlangExpression {
+
+ @Nullable
+ ErlangFunctionWithArity getFunctionWithArity();
+
+ @Nullable
+ ErlangFunctionWithArityVariables getFunctionWithArityVariables();
+
+ @Nullable
+ ErlangModuleRef getModuleRef();
+
+ @Nullable
+ ErlangQVar getQVar();
+
+ @Nullable
+ PsiElement getColon();
+
+ @NotNull
+ PsiElement getFunexprFun();
+
+ //WARNING: processDeclarations(...) is skipped
+ //matching processDeclarations(ErlangFunRefExpression, ...)
+ //methods are not found in ErlangPsiImplUtil
+
+}
diff --git a/gen/org/intellij/erlang/psi/ErlangVisitor.java b/gen/org/intellij/erlang/psi/ErlangVisitor.java
index 34b33c217..05ce84fa5 100644
--- a/gen/org/intellij/erlang/psi/ErlangVisitor.java
+++ b/gen/org/intellij/erlang/psi/ErlangVisitor.java
@@ -192,6 +192,10 @@ public void visitFunExpression(@NotNull ErlangFunExpression o) {
visitExpression(o);
}
+ public void visitFunRefExpression(@NotNull ErlangFunRefExpression o) {
+ visitExpression(o);
+ }
+
public void visitFunType(@NotNull ErlangFunType o) {
visitType(o);
}
diff --git a/gen/org/intellij/erlang/psi/impl/ErlangFunExpressionImpl.java b/gen/org/intellij/erlang/psi/impl/ErlangFunExpressionImpl.java
index 43bc73826..8e24e4c49 100644
--- a/gen/org/intellij/erlang/psi/impl/ErlangFunExpressionImpl.java
+++ b/gen/org/intellij/erlang/psi/impl/ErlangFunExpressionImpl.java
@@ -30,39 +30,9 @@ public void accept(@NotNull PsiElementVisitor visitor) {
}
@Override
- @Nullable
+ @NotNull
public ErlangFunClauses getFunClauses() {
- return PsiTreeUtil.getChildOfType(this, ErlangFunClauses.class);
- }
-
- @Override
- @Nullable
- public ErlangFunctionWithArity getFunctionWithArity() {
- return PsiTreeUtil.getChildOfType(this, ErlangFunctionWithArity.class);
- }
-
- @Override
- @Nullable
- public ErlangFunctionWithArityVariables getFunctionWithArityVariables() {
- return PsiTreeUtil.getChildOfType(this, ErlangFunctionWithArityVariables.class);
- }
-
- @Override
- @Nullable
- public ErlangModuleRef getModuleRef() {
- return PsiTreeUtil.getChildOfType(this, ErlangModuleRef.class);
- }
-
- @Override
- @Nullable
- public ErlangQVar getQVar() {
- return PsiTreeUtil.getChildOfType(this, ErlangQVar.class);
- }
-
- @Override
- @Nullable
- public PsiElement getColon() {
- return findChildByType(ERL_COLON);
+ return notNullChild(PsiTreeUtil.getChildOfType(this, ErlangFunClauses.class));
}
@Override
diff --git a/gen/org/intellij/erlang/psi/impl/ErlangFunRefExpressionImpl.java b/gen/org/intellij/erlang/psi/impl/ErlangFunRefExpressionImpl.java
new file mode 100644
index 000000000..633ff3a36
--- /dev/null
+++ b/gen/org/intellij/erlang/psi/impl/ErlangFunRefExpressionImpl.java
@@ -0,0 +1,66 @@
+// This is a generated file. Not intended for manual editing.
+package org.intellij.erlang.psi.impl;
+
+import java.util.List;
+import org.jetbrains.annotations.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import static org.intellij.erlang.ErlangTypes.*;
+import org.intellij.erlang.psi.*;
+
+public class ErlangFunRefExpressionImpl extends ErlangExpressionImpl implements ErlangFunRefExpression {
+
+ public ErlangFunRefExpressionImpl(ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void accept(@NotNull ErlangVisitor visitor) {
+ visitor.visitFunRefExpression(this);
+ }
+
+ @Override
+ public void accept(@NotNull PsiElementVisitor visitor) {
+ if (visitor instanceof ErlangVisitor) accept((ErlangVisitor)visitor);
+ else super.accept(visitor);
+ }
+
+ @Override
+ @Nullable
+ public ErlangFunctionWithArity getFunctionWithArity() {
+ return PsiTreeUtil.getChildOfType(this, ErlangFunctionWithArity.class);
+ }
+
+ @Override
+ @Nullable
+ public ErlangFunctionWithArityVariables getFunctionWithArityVariables() {
+ return PsiTreeUtil.getChildOfType(this, ErlangFunctionWithArityVariables.class);
+ }
+
+ @Override
+ @Nullable
+ public ErlangModuleRef getModuleRef() {
+ return PsiTreeUtil.getChildOfType(this, ErlangModuleRef.class);
+ }
+
+ @Override
+ @Nullable
+ public ErlangQVar getQVar() {
+ return PsiTreeUtil.getChildOfType(this, ErlangQVar.class);
+ }
+
+ @Override
+ @Nullable
+ public PsiElement getColon() {
+ return findChildByType(ERL_COLON);
+ }
+
+ @Override
+ @NotNull
+ public PsiElement getFunexprFun() {
+ return notNullChild(findChildByType(ERL_FUNEXPR_FUN));
+ }
+
+}
diff --git a/gradle.properties b/gradle.properties
index 666c7f0b2..8dfcc79d9 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -4,12 +4,13 @@
version = 0.11
ideaVersion = 223.7571-EAP-CANDIDATE-SNAPSHOT
+psiViewerPlugin = PsiViewer:2022.3
javaVersion = 17
javaTargetVersion = 17
buildNumber = SNAPSHOT
sources = true
isEAP = false
localIdePath =
-org.gradle.jvmargs=-XX:+HeapDumpOnOutOfMemoryError -Xmx1024m -Dfile.encoding=utf-8
+org.gradle.jvmargs=-XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=utf-8
org.gradle.caching = true
org.gradle.vfs.watch = true
diff --git a/grammars/erlang.bnf b/grammars/erlang.bnf
index c3451b4ef..0618f134c 100644
--- a/grammars/erlang.bnf
+++ b/grammars/erlang.bnf
@@ -64,6 +64,8 @@
QMARK = "?"
MATCH = ":="
ASSOC = "=>"
+ FUN = "fun" // parsed as ERL_FUN if followed by a "("
+ FUNEXPR_FUN = "$$fun_ref_expr" // fake token replacing 'fun' in mod:func/arity reference expr
]
extends("assignment_expression|maybe_match_expression|send_expression|orelse_expression|andalso_expression|comp_op_expression|list_op_expression|additive_expression|multiplicative_expression")=fake_binary_expression
@@ -375,7 +377,7 @@ config_argument_list ::= '(' config_exprs? ')' {elementType=argument_list}
config_list_expression ::= '[' config_exprs? ']' {elementType=list_expression}
config_bin_list_expression ::= '<<' config_exprs? '>>' {elementType=binary_expression}
config_tuple_expression ::= '{' config_exprs? '}' {elementType=tuple_expression}
-config_fun_expression ::= fun fun_expression_lambda {elementType=fun_expression pin=1}
+config_fun_expression ::= '$$fun_ref_expr' fun_ref_expression_body {elementType=fun_ref_expression pin=1}
config_map_construct_expression ::= config_map_tuple {elementType=map_expression}
config_map_tuple ::= '#' '{' config_map_assoc_list? '}' {pin=1 elementType=map_tuple}
@@ -438,7 +440,7 @@ max_expression ::=
| map_comprehension
| map_construct_expression
| receive_expression
- | fun_expression
+ | fun_expression | fun_ref_expression
| try_expression
| maybe_expression
| binary_expression
@@ -555,9 +557,16 @@ argument_definition ::= expression
receive_expression ::= receive (after_clause | cr_clauses after_clause? ) end {pin(".*")=1}
private after_clause ::= after after_clause_body {pin=1}
after_clause_body ::= <> clause_body {pin=1}
-fun_expression ::= fun (fun_expression_block | fun_expression_lambda) {pin=1 methods=[processDeclarations]}
-private fun_expression_lambda ::= [(module_ref | q_var) ':'] (function_with_arity | function_with_arity_variables)
-private fun_expression_block ::= fun_clauses end {pin=1}
+
+// An in-place lambda definition: fun Clause1 -> Return1; Clause2 -> Return2; ... end.
+// Can contain optional Q_VAR like `fun Fact(1) -> 1; Fact(X) when X > 1 -> X * Fact(X - 1) end`
+fun_expression ::= fun fun_clauses_end { pin=3 methods=[processDeclarations] }
+private fun_clauses_end ::= fun_clauses end {pin=1}
+
+// A function reference possibly with module name fun Mod:Fun/Arity
+// Using ERL_FUNEXPR_FUN token which is 'fun' renamed to '$$fun_ref_expr' in the lexer
+fun_ref_expression ::= '$$fun_ref_expr' fun_ref_expression_body {pin=2 methods=[processDeclarations]}
+private fun_ref_expression_body ::= [(module_ref | q_var) ':'] (function_with_arity | function_with_arity_variables)
function_with_arity ::= q_atom '/' integer {pin=1 methods=[getReference]}
function_with_arity_variables ::= q_var '/' (integer|q_var) {pin=1}
diff --git a/src/org/intellij/erlang/ErlangDescriptionProvider.java b/src/org/intellij/erlang/ErlangDescriptionProvider.java
index b4df9dd97..01bb7c012 100644
--- a/src/org/intellij/erlang/ErlangDescriptionProvider.java
+++ b/src/org/intellij/erlang/ErlangDescriptionProvider.java
@@ -36,42 +36,57 @@ public class ErlangDescriptionProvider implements ElementDescriptionProvider {
private final static Logger LOG = Logger.getInstance(ErlangDescriptionProvider.class);
@Override
- public String getElementDescription(@NotNull PsiElement o, @NotNull ElementDescriptionLocation location) {
- if (!(o instanceof ErlangCompositeElement)) return null;
- if (location == UsageViewNodeTextLocation.INSTANCE && (o instanceof ErlangNamedElement || o instanceof ErlangQAtom || o instanceof ErlangTypeRef)) {
- return getElementDescription(o, UsageViewShortNameLocation.INSTANCE);
+ public String getElementDescription(@NotNull PsiElement el, @NotNull ElementDescriptionLocation location) {
+ if (!(el instanceof ErlangCompositeElement)) return null;
+
+ if (location == UsageViewNodeTextLocation.INSTANCE
+ && (el instanceof ErlangNamedElement
+ || el instanceof ErlangQAtom
+ || el instanceof ErlangTypeRef)) {
+ return getElementDescription(el, UsageViewShortNameLocation.INSTANCE);
}
- if (location == UsageViewShortNameLocation.INSTANCE ||
- location == UsageViewLongNameLocation.INSTANCE ||
- location instanceof DeleteNameDescriptionLocation
+
+ if (location == UsageViewShortNameLocation.INSTANCE
+ || location == UsageViewLongNameLocation.INSTANCE
+ || location instanceof DeleteNameDescriptionLocation
) {
- if (o instanceof ErlangNamedElement) return ((ErlangNamedElement) o).getName();
- if (o instanceof ErlangQAtom) return ErlangPsiImplUtil.getName((ErlangQAtom)o);
- if (o instanceof ErlangTypeRef) return o.getText();
- if (o instanceof ErlangAttribute) {
- ErlangSpecification spec = ((ErlangAttribute) o).getSpecification();
+ if (el instanceof ErlangNamedElement) return ((ErlangNamedElement) el).getName();
+ if (el instanceof ErlangQAtom) return ErlangPsiImplUtil.getName((ErlangQAtom)el);
+ if (el instanceof ErlangTypeRef) return el.getText();
+ if (el instanceof ErlangAttribute) {
+ ErlangSpecification spec = ((ErlangAttribute) el).getSpecification();
if (spec != null) return spec.getName();
}
}
+
if (location == HighlightUsagesDescriptionLocation.INSTANCE) {
- return getElementDescription(o, UsageViewShortNameLocation.INSTANCE);
+ return getElementDescription(el, UsageViewShortNameLocation.INSTANCE);
}
- if (location == UsageViewTypeLocation.INSTANCE ||
- location == RefactoringDescriptionLocation.WITH_PARENT ||
- location instanceof DeleteTypeDescriptionLocation
+
+ if (location == UsageViewTypeLocation.INSTANCE
+ || location == RefactoringDescriptionLocation.WITH_PARENT
+ || location instanceof DeleteTypeDescriptionLocation
+ || location instanceof UsageViewNodeTextLocation
) {
- if (o instanceof ErlangModule) return "module";
- else if (o instanceof ErlangFunction) return "function";
- else if (o instanceof ErlangRecordDefinition) return "record";
- else if (o instanceof ErlangQVar) return "variable";
- else if (o instanceof ErlangMacrosDefinition) return "macro";
- else if (o instanceof ErlangTypedExpr) return "record field";
- else if (o instanceof ErlangTypeDefinition) return "type";
- else if (o instanceof ErlangAttribute) return "attribute";
- else if (o instanceof ErlangQAtom) return "atom";
- else if (o instanceof ErlangTypeRef) return "type";
+ if (el instanceof ErlangModule) return "module";
+ else if (el instanceof ErlangFunction) return "function";
+ else if (el instanceof ErlangRecordDefinition) return "record";
+ else if (el instanceof ErlangQVar) return "variable";
+ else if (el instanceof ErlangMacrosDefinition) return "macro";
+ else if (el instanceof ErlangTypedExpr) return "record field";
+ else if (el instanceof ErlangTypeDefinition) return "type";
+ else if (el instanceof ErlangAttribute) return "attribute";
+ else if (el instanceof ErlangQAtom
+ || el instanceof ErlangAtom) return "atom";
+ else if (el instanceof ErlangFunctionWithArity) return "function reference with arity";
+ else if (el instanceof ErlangFunExpression) return "inline function definition";
+ else if (el instanceof ErlangFunRefExpression) return "function reference";
+ else if (el instanceof ErlangModuleRef) return "module reference";
+ else if (el instanceof ErlangTypeRef) return "type";
}
- LOG.error("Unexpected element " + o.getText() + ", class: " + o.getClass() + ", location: " + location.getClass());
+
+ LOG.error("ErlangDescriptionProvider: Unexpected element `%s`, class=`%s`, location=`%s`"
+ .formatted(el.getText(), el.getClass(), location.getClass()));
return "";
}
}
diff --git a/src/org/intellij/erlang/editor/ErlangSyntaxHighlighter.java b/src/org/intellij/erlang/editor/ErlangSyntaxHighlighter.java
index 6bf290491..6fe0520ee 100644
--- a/src/org/intellij/erlang/editor/ErlangSyntaxHighlighter.java
+++ b/src/org/intellij/erlang/editor/ErlangSyntaxHighlighter.java
@@ -94,37 +94,13 @@ public Lexer getHighlightingLexer() {
return pack(FUNCTION);
}
- if (
- ERL_AFTER == type ||
- ERL_WHEN == type ||
- ERL_BEGIN == type ||
- ERL_END == type ||
- ERL_OF == type ||
- ERL_CASE == type ||
- ERL_FUN == type ||
- ERL_CATCH == type ||
- ERL_IF == type ||
- ERL_RECEIVE == type ||
- ERL_TRY == type ||
- ERL_ELSE == type ||
- ERL_MAYBE == type ||
- ERL_DOT == type ||
- ERL_ANDALSO == type ||
- ERL_ORELSE == type ||
- ERL_DIV == type ||
- ERL_REM == type ||
- ERL_XOR == type ||
- ERL_BXOR == type ||
- ERL_BOR == type ||
- ERL_BAND == type ||
- ERL_BNOT == type ||
- ERL_AND == type ||
- ERL_OR == type ||
- ERL_NOT == type ||
- ERL_BSL == type ||
- ERL_BSR == type ||
- ERL_OR_OR == type
- ) {
+ if (ERL_AFTER == type || ERL_WHEN == type || ERL_BEGIN == type || ERL_END == type || ERL_OF == type ||
+ ERL_CASE == type || ERL_FUNEXPR_FUN == type || ERL_FUN == type || ERL_CATCH == type || ERL_IF == type ||
+ ERL_RECEIVE == type || ERL_TRY == type || ERL_ELSE == type || ERL_MAYBE == type || ERL_DOT == type ||
+ ERL_ANDALSO == type || ERL_ORELSE == type || ERL_DIV == type || ERL_REM == type || ERL_XOR == type ||
+ ERL_BXOR == type || ERL_BOR == type || ERL_BAND == type || ERL_BNOT == type || ERL_AND == type ||
+ ERL_OR == type || ERL_NOT == type || ERL_BSL == type || ERL_BSR == type || ERL_OR_OR == type)
+ {
return pack(KEYWORD);
}
return TextAttributesKey.EMPTY_ARRAY;
diff --git a/src/org/intellij/erlang/formatter/ErlangFormattingModelBuilder.java b/src/org/intellij/erlang/formatter/ErlangFormattingModelBuilder.java
index e98978085..2a787662e 100644
--- a/src/org/intellij/erlang/formatter/ErlangFormattingModelBuilder.java
+++ b/src/org/intellij/erlang/formatter/ErlangFormattingModelBuilder.java
@@ -43,7 +43,9 @@ public class ErlangFormattingModelBuilder implements FormattingModelBuilder {
}
private static SpacingBuilder createSpacingBuilder(@NotNull CommonCodeStyleSettings settings, @NotNull ErlangCodeStyleSettings erlangSettings) {
+ // Tokens inside ( ) with 0 space before them
TokenSet rules = TokenSet.create(ERL_RULE, ERL_RECORD_DEFINITION, ERL_INCLUDE, ERL_MACROS_DEFINITION, ERL_ATTRIBUTE);
+ // Keywords with 1 space around them
TokenSet keywords = TokenSet.create(
ERL_AFTER, ERL_WHEN, ERL_BEGIN, ERL_END, ERL_OF, ERL_CASE, ERL_CATCH, ERL_ELSE, ERL_IF, ERL_RECEIVE,
ERL_TRY, ERL_MAYBE, ERL_DIV, ERL_REM, ERL_OR, ERL_XOR, ERL_BOR, ERL_BXOR, ERL_BSL, ERL_BSR, ERL_AND, ERL_BAND);
@@ -161,11 +163,13 @@ private static SpacingBuilder createSpacingBuilder(@NotNull CommonCodeStyleSetti
.between(ERL_FUN, ERL_MODULE_REF).spaces(1)
.between(ERL_FUN, ERL_FUNCTION_WITH_ARITY).spaces(1)
.betweenInside(ERL_FUN, ERL_Q_VAR, ERL_FUN_EXPRESSION).spaces(1)
+ .betweenInside(ERL_FUN, ERL_Q_VAR, ERL_FUN_REF_EXPRESSION).spaces(1)
.betweenInside(ERL_FUN, ERL_MODULE_REF, ERL_FUN_EXPRESSION).spaces(1)
+ .betweenInside(ERL_FUN, ERL_MODULE_REF, ERL_FUN_REF_EXPRESSION).spaces(1)
.between(ERL_MODULE_REF, ERL_COLON).none()
.between(ERL_COLON, ERL_FUNCTION_WITH_ARITY).none()
.between(ERL_COLON, ERL_FUNCTION_WITH_ARITY_VARIABLES).none()
- .betweenInside(ERL_Q_VAR, ERL_COLON, ERL_FUN_EXPRESSION).none()
+ .betweenInside(ERL_Q_VAR, ERL_COLON, ERL_FUN_REF_EXPRESSION).none()
.between(ERL_FUN, ERL_FUN_CLAUSES).none()
.before(ERL_END).spaces(1)
diff --git a/src/org/intellij/erlang/parser/Erlang.flex b/src/org/intellij/erlang/parser/Erlang.flex
index cabd45e8f..91f783073 100644
--- a/src/org/intellij/erlang/parser/Erlang.flex
+++ b/src/org/intellij/erlang/parser/Erlang.flex
@@ -71,6 +71,15 @@ EmptyAtom = ''
Variable = (_ {NameChars}) | ({ErlangUppercase} {NameChars})
+// This is forward scanned to ensure that 'fun' keyword begins a lambda or named lambda
+// Can look like `fun() -> ok end` or `fun Hello() -> ok end`
+FunLookahead = ({Whitespace}+ {Variable})? {Whitespace}* \x28
+// This is forward-scanned to ensure that 'fun' keyword begins a `fun mod:func/arity` expression
+// Can look like `fun` followed by `` and then `:` or `/`
+// TODO: Handling `fun 'quotedatom'...` which is implemented using lexer states
+SimpleQuotedAtom = \' {NameChar}* \'
+FunRefLookahead = {Whitespace}+ ({AtomName} | {SimpleQuotedAtom} | {Variable}) {Whitespace}* (\: | \x2f)
+
%state IN_QUOTES
%%
@@ -86,7 +95,8 @@ Variable = (_ {NameChars}) | ({ErlangUppercase} {NameChars})
"end" { return ERL_END; }
"of" { return ERL_OF; }
"case" { return ERL_CASE; }
- "fun" { return ERL_FUN; }
+ "fun" / {FunLookahead} { return ERL_FUN; }
+ "fun" / {FunRefLookahead} { return ERL_FUNEXPR_FUN; }
"try" { return ERL_TRY; }
"catch" { return ERL_CATCH; }
"if" { return ERL_IF; }
diff --git a/src/org/intellij/erlang/parser/ErlangParserUtil.java b/src/org/intellij/erlang/parser/ErlangParserUtil.java
index 707224c67..35ec62003 100644
--- a/src/org/intellij/erlang/parser/ErlangParserUtil.java
+++ b/src/org/intellij/erlang/parser/ErlangParserUtil.java
@@ -128,6 +128,17 @@ private MyBuilder(PsiBuilder builder, ErrorState state, PsiParser parser, boolea
}
}
+ public static boolean consumeFunToken(PsiBuilder builder, int ignoredLevel) {
+ boolean indexing = builder instanceof MyBuilder && ((MyBuilder)builder).indexing;
+
+ if (indexing ? nextTokenIsFast(builder, ErlangTypes.ERL_FUN)
+ : GeneratedParserUtilBase.nextTokenIs(builder, ErlangTypes.ERL_FUN)) {
+ builder.advanceLexer(); // skip the 'fun' token
+ return true;
+ }
+ return false;
+ }
+
@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
public static boolean consumeToken(PsiBuilder builder, IElementType token) {
boolean indexing = builder instanceof MyBuilder && ((MyBuilder)builder).indexing;
diff --git a/src/org/intellij/erlang/refactoring/ErlangInlineVariableHandler.java b/src/org/intellij/erlang/refactoring/ErlangInlineVariableHandler.java
index c753a6d1e..85e29277e 100644
--- a/src/org/intellij/erlang/refactoring/ErlangInlineVariableHandler.java
+++ b/src/org/intellij/erlang/refactoring/ErlangInlineVariableHandler.java
@@ -85,7 +85,8 @@ public void inlineElement(final Project project, Editor editor, PsiElement eleme
replacementNode = expr.replace(rightWithoutParentheses).getNode();
}
}
- else if (expr instanceof ErlangFunExpression) {
+ else if (expr instanceof ErlangFunExpression
+ || expr instanceof ErlangFunRefExpression) {
replacementNode = host.replace(rightWithoutParentheses).getNode();
}
else if (expr instanceof ErlangGenericFunctionCallExpression) {
@@ -103,15 +104,17 @@ else if (expr instanceof ErlangGenericFunctionCallExpression) {
}
assignment.delete();
- }), "Inline variable", null);
+ }), "Inline Variable", null);
}
private static PsiElement substituteFunctionCall(Project project, PsiElement variable, ErlangExpression variableValue) {
- if (!(variableValue instanceof ErlangFunExpression)) return variable.replace(variableValue);
-
- ErlangFunExpression funExpression = (ErlangFunExpression) variableValue;
+ if (variableValue instanceof ErlangFunExpression) {
+ return variable.replace(variableValue);
+ }
- if (null != funExpression.getFunClauses()) return variable.replace(variableValue);
+ if (!(variableValue instanceof ErlangFunRefExpression funExpression)) {
+ return variable.replace(variableValue);
+ }
ErlangFunctionWithArity functionWithArity = funExpression.getFunctionWithArity();
PsiElement function = functionWithArity != null ? functionWithArity.getQAtom() : null;
diff --git a/testData/parser/29.txt b/testData/parser/29.txt
index f3e209b2b..bb4a0cee0 100644
--- a/testData/parser/29.txt
+++ b/testData/parser/29.txt
@@ -13,8 +13,8 @@ ERL_FILE
PsiElement())(')')
ERL_CLAUSE_BODY
PsiElement(->)('->')
- ERL_FUN_EXPRESSION
- PsiElement(fun)('fun')
+ ERL_FUN_REF_EXPRESSION
+ PsiElement($$fun_ref_expr)('fun')
ERL_Q_VAR
PsiElement(var)('M')
PsiElement(:)(':')
diff --git a/testData/parser/51.txt b/testData/parser/51.txt
index b7551e8b1..bbc4b4e6f 100644
--- a/testData/parser/51.txt
+++ b/testData/parser/51.txt
@@ -904,8 +904,8 @@ ERL_FILE
PsiElement(atom_name)('top')
ERL_ARGUMENT_LIST
PsiElement(()('(')
- ERL_FUN_EXPRESSION
- PsiElement(fun)('fun')
+ ERL_FUN_REF_EXPRESSION
+ PsiElement($$fun_ref_expr)('fun')
ERL_FUNCTION_WITH_ARITY
ERL_Q_ATOM
ERL_ATOM
@@ -970,8 +970,8 @@ ERL_FILE
PsiElement(atom_name)('do_inspect')
ERL_ARGUMENT_LIST
PsiElement(()('(')
- ERL_FUN_EXPRESSION
- PsiElement(fun)('fun')
+ ERL_FUN_REF_EXPRESSION
+ PsiElement($$fun_ref_expr)('fun')
ERL_FUNCTION_WITH_ARITY
ERL_Q_ATOM
ERL_ATOM
@@ -1024,8 +1024,8 @@ ERL_FILE
PsiElement(atom_name)('do_transform')
ERL_ARGUMENT_LIST
PsiElement(()('(')
- ERL_FUN_EXPRESSION
- PsiElement(fun)('fun')
+ ERL_FUN_REF_EXPRESSION
+ PsiElement($$fun_ref_expr)('fun')
ERL_FUNCTION_WITH_ARITY
ERL_Q_ATOM
ERL_ATOM
diff --git a/testData/parser/ConfigFun.txt b/testData/parser/ConfigFun.txt
index fabcf3900..4f9b1a97f 100644
--- a/testData/parser/ConfigFun.txt
+++ b/testData/parser/ConfigFun.txt
@@ -47,8 +47,8 @@ ERL_FILE
PsiElement(,)(',')
ERL_TUPLE_EXPRESSION
PsiElement({)('{')
- ERL_FUN_EXPRESSION
- PsiElement(fun)('fun')
+ ERL_FUN_REF_EXPRESSION
+ PsiElement($$fun_ref_expr)('fun')
ERL_MODULE_REF
ERL_Q_ATOM
ERL_ATOM
diff --git a/testData/parser/DialyzerDataflow.txt b/testData/parser/DialyzerDataflow.txt
index 16b3bf356..3698f953c 100644
--- a/testData/parser/DialyzerDataflow.txt
+++ b/testData/parser/DialyzerDataflow.txt
@@ -45978,8 +45978,8 @@ ERL_FILE
PsiElement(atom_name)('any')
ERL_ARGUMENT_LIST
PsiElement(()('(')
- ERL_FUN_EXPRESSION
- PsiElement(fun)('fun')
+ ERL_FUN_REF_EXPRESSION
+ PsiElement($$fun_ref_expr)('fun')
ERL_MODULE_REF
ERL_Q_ATOM
ERL_ATOM
@@ -46023,8 +46023,8 @@ ERL_FILE
PsiElement(atom_name)('any')
ERL_ARGUMENT_LIST
PsiElement(()('(')
- ERL_FUN_EXPRESSION
- PsiElement(fun)('fun')
+ ERL_FUN_REF_EXPRESSION
+ PsiElement($$fun_ref_expr)('fun')
ERL_MODULE_REF
ERL_Q_ATOM
ERL_ATOM
diff --git a/testData/parser/H.txt b/testData/parser/H.txt
index 8f0440e92..aa5e1b42f 100644
--- a/testData/parser/H.txt
+++ b/testData/parser/H.txt
@@ -22028,8 +22028,8 @@ ERL_FILE
PsiElement(atom_name)('any')
ERL_ARGUMENT_LIST
PsiElement(()('(')
- ERL_FUN_EXPRESSION
- PsiElement(fun)('fun')
+ ERL_FUN_REF_EXPRESSION
+ PsiElement($$fun_ref_expr)('fun')
ERL_MODULE_REF
ERL_Q_ATOM
ERL_ATOM
@@ -22073,8 +22073,8 @@ ERL_FILE
PsiElement(atom_name)('any')
ERL_ARGUMENT_LIST
PsiElement(()('(')
- ERL_FUN_EXPRESSION
- PsiElement(fun)('fun')
+ ERL_FUN_REF_EXPRESSION
+ PsiElement($$fun_ref_expr)('fun')
ERL_MODULE_REF
ERL_Q_ATOM
ERL_ATOM
diff --git a/testData/parser/Mnesia.txt b/testData/parser/Mnesia.txt
index b1e260e42..f994ffc03 100644
--- a/testData/parser/Mnesia.txt
+++ b/testData/parser/Mnesia.txt
@@ -33676,8 +33676,8 @@ ERL_FILE
PsiElement(atom_name)('foldl')
ERL_ARGUMENT_LIST
PsiElement(()('(')
- ERL_FUN_EXPRESSION
- PsiElement(fun)('fun')
+ ERL_FUN_REF_EXPRESSION
+ PsiElement($$fun_ref_expr)('fun')
ERL_FUNCTION_WITH_ARITY
ERL_Q_ATOM
ERL_ATOM