From 7799ff019bb972f07b026b4a5867369edd7e396c Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Thu, 18 Aug 2016 15:55:03 +0100 Subject: [PATCH] syntax error when using anonymous struct in if-statement, fix #2746 (cherry picked from commit cf6153525597b6bdf1daabfbace230d7581069f4) --- gen/com/goide/parser/GoParser.java | 6 +- grammars/go.bnf | 2 +- src/com/goide/parser/GoParserUtil.java | 4 +- testData/parser/LiteralValuesElse.go | 18 ++++ testData/parser/LiteralValuesElse.txt | 113 +++++++++++++++++++++++ tests/com/goide/parser/GoParserTest.java | 1 + 6 files changed, 138 insertions(+), 6 deletions(-) create mode 100644 testData/parser/LiteralValuesElse.go create mode 100644 testData/parser/LiteralValuesElse.txt diff --git a/gen/com/goide/parser/GoParser.java b/gen/com/goide/parser/GoParser.java index 6ee8b5581e..00596cb9e7 100644 --- a/gen/com/goide/parser/GoParser.java +++ b/gen/com/goide/parser/GoParser.java @@ -2435,7 +2435,7 @@ static boolean LiteralTypeExprInner(PsiBuilder b, int l) { } /* ********************************************************** */ - // (<> | <> | <>) '{' ElementList? '}' + // (<> | <> | <>) '{' ElementList? '}' public static boolean LiteralValue(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "LiteralValue")) return false; boolean r, p; @@ -2449,14 +2449,14 @@ public static boolean LiteralValue(PsiBuilder b, int l) { return r || p; } - // <> | <> | <> + // <> | <> | <> private static boolean LiteralValue_0(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "LiteralValue_0")) return false; boolean r; Marker m = enter_section_(b); r = isModeOff(b, l + 1, "BLOCK?"); if (!r) r = isModeOn(b, l + 1, "PAR"); - if (!r) r = prevIsArrayType(b, l + 1); + if (!r) r = prevIsType(b, l + 1); exit_section_(b, m, null, r); return r; } diff --git a/grammars/go.bnf b/grammars/go.bnf index 58509f355e..c7e252a0c1 100644 --- a/grammars/go.bnf +++ b/grammars/go.bnf @@ -315,7 +315,7 @@ private LiteralTypeExprInner ::= StructType | ArrayOrSliceType | MapType LiteralTypeExpr ::= LiteralTypeExprInner | TypeName -LiteralValue ::= (<> | <> | <>) '{' ElementList? '}' {pin=2} +LiteralValue ::= (<> | <> | <>) '{' ElementList? '}' {pin=2} private ElementList ::= E ( ',' E? )* private E ::= <> | (!() Element) {recoverWhile=E_recover} private E_recover ::= !('}'|',') diff --git a/src/com/goide/parser/GoParserUtil.java b/src/com/goide/parser/GoParserUtil.java index 7d088ff782..d0e10d2088 100644 --- a/src/com/goide/parser/GoParserUtil.java +++ b/src/com/goide/parser/GoParserUtil.java @@ -135,10 +135,10 @@ public static boolean isModeOff(@NotNull PsiBuilder builder_, @SuppressWarnings( return getParsingModes(builder_).get(mode) == 0; } - public static boolean prevIsArrayType(@NotNull PsiBuilder builder_, @SuppressWarnings("UnusedParameters") int level) { + public static boolean prevIsType(@NotNull PsiBuilder builder_, @SuppressWarnings("UnusedParameters") int level) { LighterASTNode marker = builder_.getLatestDoneMarker(); IElementType type = marker != null ? marker.getTokenType() : null; - return type == GoTypes.ARRAY_OR_SLICE_TYPE || type == GoTypes.MAP_TYPE; + return type == GoTypes.ARRAY_OR_SLICE_TYPE || type == GoTypes.MAP_TYPE || type == GoTypes.STRUCT_TYPE; } public static boolean keyOrValueExpression(@NotNull PsiBuilder builder_, int level) { diff --git a/testData/parser/LiteralValuesElse.go b/testData/parser/LiteralValuesElse.go new file mode 100644 index 0000000000..6364b3ba1e --- /dev/null +++ b/testData/parser/LiteralValuesElse.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" +) + +func main() { + s := struct{ Username, Password string }{ + "User", + "Password", + } + + if s != struct{ Username, Password string }{} { + fmt.Println("yes") + } else { + fmt.Println("yes") + } +} \ No newline at end of file diff --git a/testData/parser/LiteralValuesElse.txt b/testData/parser/LiteralValuesElse.txt new file mode 100644 index 0000000000..0ea41aba69 --- /dev/null +++ b/testData/parser/LiteralValuesElse.txt @@ -0,0 +1,113 @@ +GO_FILE + PACKAGE_CLAUSE + PsiElement(package)('package') + PsiElement(identifier)('main') + IMPORT_LIST + IMPORT_DECLARATION + PsiElement(import)('import') + PsiElement(()('(') + IMPORT_SPEC + STRING_LITERAL + PsiElement(string)('"fmt"') + PsiElement())(')') + FUNCTION_DECLARATION + PsiElement(func)('func') + PsiElement(identifier)('main') + SIGNATURE + PARAMETERS + PsiElement(()('(') + PsiElement())(')') + BLOCK + PsiElement({)('{') + SIMPLE_STATEMENT + SHORT_VAR_DECLARATION + VAR_DEFINITION + PsiElement(identifier)('s') + PsiElement(:=)(':=') + COMPOSITE_LIT + STRUCT_TYPE + PsiElement(struct)('struct') + PsiElement({)('{') + FIELD_DECLARATION + FIELD_DEFINITION + PsiElement(identifier)('Username') + PsiElement(,)(',') + FIELD_DEFINITION + PsiElement(identifier)('Password') + TYPE + TYPE_REFERENCE_EXPRESSION + PsiElement(identifier)('string') + PsiElement(})('}') + LITERAL_VALUE + PsiElement({)('{') + ELEMENT + VALUE + STRING_LITERAL + PsiElement(string)('"User"') + PsiElement(,)(',') + ELEMENT + VALUE + STRING_LITERAL + PsiElement(string)('"Password"') + PsiElement(,)(',') + PsiElement(})('}') + IF_STATEMENT + PsiElement(if)('if') + SIMPLE_STATEMENT + LEFT_HAND_EXPR_LIST + CONDITIONAL_EXPR + REFERENCE_EXPRESSION + PsiElement(identifier)('s') + PsiElement(!=)('!=') + COMPOSITE_LIT + STRUCT_TYPE + PsiElement(struct)('struct') + PsiElement({)('{') + FIELD_DECLARATION + FIELD_DEFINITION + PsiElement(identifier)('Username') + PsiElement(,)(',') + FIELD_DEFINITION + PsiElement(identifier)('Password') + TYPE + TYPE_REFERENCE_EXPRESSION + PsiElement(identifier)('string') + PsiElement(})('}') + LITERAL_VALUE + PsiElement({)('{') + PsiElement(})('}') + BLOCK + PsiElement({)('{') + SIMPLE_STATEMENT + LEFT_HAND_EXPR_LIST + CALL_EXPR + REFERENCE_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(identifier)('fmt') + PsiElement(.)('.') + PsiElement(identifier)('Println') + ARGUMENT_LIST + PsiElement(()('(') + STRING_LITERAL + PsiElement(string)('"yes"') + PsiElement())(')') + PsiElement(})('}') + ELSE_STATEMENT + PsiElement(else)('else') + BLOCK + PsiElement({)('{') + SIMPLE_STATEMENT + LEFT_HAND_EXPR_LIST + CALL_EXPR + REFERENCE_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(identifier)('fmt') + PsiElement(.)('.') + PsiElement(identifier)('Println') + ARGUMENT_LIST + PsiElement(()('(') + STRING_LITERAL + PsiElement(string)('"yes"') + PsiElement())(')') + PsiElement(})('}') + PsiElement(})('}') \ No newline at end of file diff --git a/tests/com/goide/parser/GoParserTest.java b/tests/com/goide/parser/GoParserTest.java index 4c3718dac4..b4eb0362d1 100644 --- a/tests/com/goide/parser/GoParserTest.java +++ b/tests/com/goide/parser/GoParserTest.java @@ -34,6 +34,7 @@ public GoParserTest() { public void testIncompleteRanges() { doTest(false); } public void testTorture() { doTest(true); } public void testLiteralValues() { doTest(true); } + public void testLiteralValuesElse() { doTest(true); } public void testIfComposite() { doTest(true); } public void testArrayTypes() { doTest(true); } public void testArrayTypesInRanges() { doTest(true); }