Skip to content

Commit

Permalink
Fix for #1129: after "x." check for declaration to prevent "x.\ndef" "y"
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Jul 31, 2020
1 parent da8a60c commit 79b1624
Show file tree
Hide file tree
Showing 18 changed files with 14,788 additions and 14,564 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1679,8 +1679,9 @@ public void testParsingRecovery_InstrusivePathExpr1() {
"import java.text.NumberFormat\n" +
"\n" +
"class X {\n" +
" @SuppressWarnings('rawtypes')\n" +
" static void main(args) {\n" +
" NumberFormat.\n" + // added after next line
" NumberFormat.\n" + // caret
" Set s = []\n" +
" }\n" +
"}\n",
Expand All @@ -1689,10 +1690,10 @@ public void testParsingRecovery_InstrusivePathExpr1() {

runNegativeTest(sources,
"----------\n" +
"1. ERROR in X.groovy (at line 8)\n" +
"1. ERROR in X.groovy (at line 9)\n" +
"\tSet s = []\n" +
"\t ^\n" +
"Groovy:Apparent variable 's' was found in a static scope but doesn't refer to a local variable, static field or class.\n" +
"\t^\n" +
"Groovy:unexpected token: Set\n" +
"----------\n");

ModuleNode mn = getModuleNode("X.groovy");
Expand All @@ -1713,7 +1714,7 @@ public void testParsingRecovery_InstrusivePathExpr2() {
"\n" +
"class X {\n" +
" static void main(args) {\n" +
" NumberFormat.\n" + // added after next line
" NumberFormat.\n" + // caret
" Set<Integer> s = []\n" +
" }\n" +
"}\n",
Expand All @@ -1724,8 +1725,8 @@ public void testParsingRecovery_InstrusivePathExpr2() {
"----------\n" +
"1. ERROR in X.groovy (at line 8)\n" +
"\tSet<Integer> s = []\n" +
"\t ^\n" +
"Groovy:unexpected token: >\n" +
"\t^\n" +
"Groovy:unexpected token: Set\n" +
"----------\n");

ModuleNode mn = getModuleNode("X.groovy");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2586,29 +2586,7 @@ public void testMissingContext_GRE308_2() {
}

@Test
public void testInvalidScripts_GRE323_1() {
//@formatter:off
String[] sources = {
"Foo.groovy",
"def foo(closure) {\n" +
" closure()\n" +
"}\n" +
"\n" +
"foo {\n" +
" final session2 = null\n" +
" \n" +
" // Define scenarios\n" +
" def secBoardRep = session2\n" +
" def x\n" +
"}\n",
};
//@formatter:on

runNegativeTest(sources, "");
}

@Test
public void testInvalidScripts_GRE323_1b() {
public void testSloppyScript_GRE323_1() {
//@formatter:off
String[] sources = {
"Foo.groovy",
Expand All @@ -2630,7 +2608,7 @@ public void testInvalidScripts_GRE323_1b() {
}

@Test
public void testInvalidScripts_GRE323_2() {
public void testSloppyScript_GRE323_2() {
//@formatter:off
String[] sources = {
"Foo.groovy",
Expand All @@ -2648,27 +2626,17 @@ public void testInvalidScripts_GRE323_2() {
};
//@formatter:on

runConformTest(sources, "", "groovy.lang.MissingPropertyException: No such property: x for class: Foo");
runNegativeTest(sources,
"----------\n" +
"1. ERROR in Foo.groovy (at line 10)\n" +
"\tdef x\n" +
"\t^\n" +
"Groovy:unexpected token: def\n" +
"----------\n");
}

@Test // removed surrounding method
public void testInvalidScripts_GRE323_3() {
//@formatter:off
String[] sources = {
"Foo.groovy",
"final session2 = null\n" +
"\n" +
"// Define scenarios\n" +
"def secBoardRep = session2\n" +
"def x\n",
};
//@formatter:on

runNegativeTest(sources, "");
}

@Test
public void testInvalidScripts_GRE323_3b() {
public void testSloppyScript_GRE323_3() {
//@formatter:off
String[] sources = {
"Foo.groovy",
Expand All @@ -2684,7 +2652,7 @@ public void testInvalidScripts_GRE323_3b() {
}

@Test
public void testInvalidScripts_GRE323_4() {
public void testSloppyScript_GRE323_4() {
//@formatter:off
String[] sources = {
"Foo.groovy",
Expand All @@ -2702,18 +2670,24 @@ public void testInvalidScripts_GRE323_4() {
};
//@formatter:on

runConformTest(sources, "", "groovy.lang.MissingPropertyException: No such property: x for class: Foo");
runNegativeTest(sources,
"----------\n" +
"1. ERROR in Foo.groovy (at line 10)\n" +
"\tdef x\n" +
"\t^\n" +
"Groovy:unexpected token: def\n" +
"----------\n");
}

@Test
public void testInvalidScripts_GRE323_4b() {
public void testSloppyScript_GRE323_4b() {
//@formatter:off
String[] sources = {
"Run.java",
"public class Run {\n" +
" public static void main(String[]argv) {\n" +
" try {\n" +
" Foo.main(null);\n" +
" Foo.main();\n" +
" } catch (Throwable t) {\n" +
" System.out.println(t.getMessage());\n" +
" }\n" +
Expand All @@ -2735,11 +2709,17 @@ public void testInvalidScripts_GRE323_4b() {
};
//@formatter:on

runConformTest(sources, "No such property: x for class: Foo");
runNegativeTest(sources,
"----------\n" +
"1. ERROR in Foo.groovy (at line 10)\n" +
"\tdef x\n" +
"\t^\n" +
"Groovy:unexpected token: def\n" +
"----------\n");
}

@Test
public void testInvalidScripts_GRE323_5() {
public void testSloppyScript_GRE323_5() {
//@formatter:off
String[] sources = {
"Foo.groovy",
Expand All @@ -2758,11 +2738,22 @@ public void testInvalidScripts_GRE323_5() {
};
//@formatter:on

runNegativeTest(sources, "");
runNegativeTest(sources,
"----------\n" +
"1. ERROR in Foo.groovy (at line 11)\n" +
"\tdef x\n" +
"\t^\n" +
"Groovy:unexpected token: def\n" +
"----------\n" +
"2. ERROR in Foo.groovy (at line 11)\n" +
"\tdef x\n" +
"\t ^\n" +
"Groovy:The current scope already contains a variable of the name x\n" +
"----------\n");
}

@Test
public void testInvalidScripts_GRE323_5b() {
public void testSloppyScript_GRE323_5b() {
//@formatter:off
String[] sources = {
"Foo.groovy",
Expand All @@ -2781,11 +2772,22 @@ public void testInvalidScripts_GRE323_5b() {
};
//@formatter:on

runConformTest(sources, "DEF");
runNegativeTest(sources,
"----------\n" +
"1. ERROR in Foo.groovy (at line 11)\n" +
"\tdef x\n" +
"\t^\n" +
"Groovy:unexpected token: def\n" +
"----------\n" +
"2. ERROR in Foo.groovy (at line 11)\n" +
"\tdef x\n" +
"\t ^\n" +
"Groovy:The current scope already contains a variable of the name x\n" +
"----------\n");
}

@Test
public void testInvalidScripts_GRE323_6() {
public void testSloppyScript_GRE323_6() {
//@formatter:off
String[] sources = {
"Foo.groovy",
Expand Down
26 changes: 11 additions & 15 deletions base/org.codehaus.groovy24/src/org/codehaus/groovy/antlr/groovy.g
Original file line number Diff line number Diff line change
Expand Up @@ -2738,20 +2738,19 @@ pathElement[AST prefix] {Token operator = LT(1);}
:
{ #pathElement = prefix; }
( nls!
( SPREAD_DOT! // Spread operator: x*.y === x?.collect{it.y}
( SPREAD_DOT! // Spread operator: x*.y === x?.collect{it.y}
|
OPTIONAL_DOT! // Optional-null operator: x?.y === (x==null)?null:x.y
OPTIONAL_DOT! // Null-safe operator: x?.y === (x==null)?null:x.y
|
MEMBER_POINTER! // Member pointer operator: foo.&y == foo.metaClass.getMethodPointer(foo, "y")
MEMBER_POINTER! // Reference operator: x.&y === x.metaClass.getMethodPointer(x,"y")
|
DOT! // The all-powerful dot.
DOT! // The all-powerful dot
)
) nls!
(ta:typeArguments!)?
// GRECLIPSE edit -- recovery for missing identifier
//np:namePart!
//{ #pathElement = #(create(operator.getType(),operator.getText(),prefix,LT(1)),prefix,ta,np); }
(np:namePart!)?
( (declarationStart) => nls! | (np:namePart!)? )
{
if (#np == null) {
GroovySourceToken ident = new GroovySourceToken(IDENT);
Expand All @@ -2761,23 +2760,24 @@ pathElement[AST prefix] {Token operator = LT(1);}
ident.setColumnLast(((SourceInfo) LT(0)).getColumnLast());
#np = #(create(ident.getType(),ident.getText(),ident,null));
reportError(new NoViableAltException(LT(1), getFilename()));
while (LA(0) == NLS) rewind(mark() - 1); // give back spaces
}
#pathElement = #(create(operator.getType(),operator.getText(),prefix,LT(1)),prefix,ta,np);
}
// GRECLIPSE end
{ #pathElement = #(create(operator.getType(),operator.getText(),prefix,LT(1)),prefix,ta,np); }
|
mca:methodCallArgs[prefix]!
{ #pathElement = #mca; }
{ #pathElement = #mca; }
|
// Can always append a block, as foo{bar}
apb:appendedBlock[prefix]!
{ #pathElement = #apb; }
{ #pathElement = #apb; }
|
// Element selection is always an option, too.
// In Groovy, the stuff between brackets is a general argument list,
// since the bracket operator is transformed into a method call.
ipa:indexPropertyArgs[prefix]!
{ #pathElement = #ipa; }
{ #pathElement = #ipa; }
;
pathElementStart!
Expand All @@ -2793,7 +2793,7 @@ pathElementStart!
/** This is the grammar for what can follow a dot: x.a, x.@a, x.&a, x.'a', etc.
* Note: <code>typeArguments</code> is handled by the caller of <code>namePart</code>.
*/
namePart {Token first = LT(1);}
namePart
:
( ats:AT^ {#ats.setType(SELECT_SLOT);} )?
// foo.@bar selects the field (or attribute), not property
Expand Down Expand Up @@ -2939,10 +2939,6 @@ methodCallArgs[AST callee]
*/
appendedBlock[AST callee]
:
/* FIXME DECIDE: should appended blocks accept labels?
( (IDENT COLON nls LCURLY)=>
IDENT c:COLON^ {#c.setType(LABELED_ARG);} nls!
)? */
cb:closableBlock!
{
// If the callee is itself a call, flatten the AST.
Expand Down
Loading

0 comments on commit 79b1624

Please sign in to comment.