Test & fix for Bug 370076 - [compiler] misplaced annotation before
labeled callin binding is silently ignored
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index 3834f47..14b0ec0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -1887,6 +1887,8 @@
 	int SyntaxErrorInCallinLabel                 = SYNTAX_RELATED + 3302; // A.3.3
 	int CallinReplaceKeyWordNotOptional          = SYNTAX_RELATED + 3303; // A.3.3
 	int IllegalMappingRHSTypeParameter   		 = SYNTAX_RELATED + 3304; // 4.3.3
+	int IllegalModifierBeforeCallinLabel 		 = SYNTAX_RELATED + 3305; // A.3.3 // FIXME: annotations are still missing from OTJLD A.3.3  
+
 	int IllegalModifierInMethodSpecRight         = SYNTAX_RELATED + 3501; // A.3.5
 
 	int SyntaxErrorIllegalDeclaredLifting        = SYNTAX_RELATED + 6001; // A.6(a)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index f7ed186..7276e84 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -2505,6 +2505,11 @@
 	}
 
 	pushOnAstStack(new CallinLabel(ident, (int)(pos >>> 32), (int)pos));
+	if (this.expressionLengthStack[this.expressionLengthPtr] > 0) {
+		Expression annot = this.expressionStack[this.expressionPtr];
+		this.problemReporter().illegalModifierBeforeCallinLabel(annot.sourceStart, annot.sourceEnd);
+		this.expressionPtr -= this.expressionLengthStack[this.expressionLengthPtr--];
+	}
 }
 private void consumeCallinModifier(int tokenID) {
 	// CallinModifier ::= 'replace'
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index e67589e..a3c2f5d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -11965,6 +11965,16 @@
         modifiersEnd);
 }
 
+public void illegalModifierBeforeCallinLabel(int modifiersStart, int modifiersEnd)
+{
+    this.handle(
+        IProblem.IllegalModifierBeforeCallinLabel,
+        NoArgument,
+        NoArgument,
+        modifiersStart,
+        modifiersEnd);
+}
+
 public void wrongModifierInCalloutMapping(
 		AbstractMethodMappingDeclaration methodMapping, int modifiersStart, int modifiersEnd)
 {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index ae8ecfa..1a6a587 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -1045,6 +1045,8 @@
 2003302 = Syntax error: callin label must be a simple name (OTJLD A.3.3).
 2003303 = Callin modifier (before, after or replace) missing for callin-binding {0} (OTJLD A.3.3).
 2003304 = Syntax error: right hand side of method binding does not specify type arguments (OTJLD A.3.3).
+2003305 = Syntax error: callin annotations must be specified after the callin name (OTJLD A.3.3).
+
 2003501 = Method designator must not specify a modifier (OTJLD A.3.5). 
 
 2006001 = Syntax Error: Declared lifting type not support in this position (OTJLD A.6(a)).
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java
index ef90e1b..0a3d808 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java
@@ -8084,15 +8084,17 @@
     // callin doesn't fire due to LiftingFailedException behind the scenes (arg lifting in replace-callin)
     public void test726_callinWithHiddenLiftingProblem4() {
         Map options = getCompilerOptions();
-        options.put(CompilerOptions.OPTION_ReportHiddenLiftingProblem, CompilerOptions.WARNING);
+        options.put(CompilerOptions.OPTION_ReportHiddenLiftingProblem, CompilerOptions.ERROR);
+        options.put(CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.ENABLED);
     	runConformTest(
     		new String[] {
     	"Team726cwhlp4.java",
     			"@SuppressWarnings(\"ambiguousbinding\")\n" +
     			"public team class Team726cwhlp4 {\n" +
     			"	protected class ROK playedBy T726cwhlp4 {\n" +
+    			"       mycallin:\n" +
     			"		@SuppressWarnings(\"hidden-lifting-problem\")\n" +
-    			"		mycallin: bar <- replace foo;\n" + // argument lifting going bad
+    			"		bar <- replace foo;\n" + // argument lifting going bad
     			"       @SuppressWarnings(\"basecall\")\n" +
     			"		callin void bar(R0 r) {\n" +
     			"			System.out.print(\"NOK\");\n" +
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/syntax/Syntax.java b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/syntax/Syntax.java
index 00b784b..97a3fe7 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/syntax/Syntax.java
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/syntax/Syntax.java
@@ -1375,4 +1375,88 @@
     		"Illegal modifier for the field val; only public, protected, private, static, final, transient & volatile are permitted\n" + 
     		"----------\n");
     }
+    
+    // illegal order of callin label and annotation (long)
+    public void test8133_callinWithNameAndAnnotation1() {
+    	runNegativeTest(
+    		new String[] {
+    	"Team8133cwnaa1.java",
+    			"public team class Team8133cwnaa1 {\n" +
+    			"    protected class R playedBy T8133cwnaa1 {\n" +
+    			"	     @SuppressWarnings(\"unused\")\n" +
+    			"        name: void foo() <- after void bar();\n" +
+    			"        void foo() {}\n" +
+    			"    }\n" +
+    			"}\n",
+    	"T8133cwnaa1.java",
+    			"public class T8133cwnaa1 { void bar() {} }\n"
+    		},
+    		"----------\n" + 
+			"1. ERROR in Team8133cwnaa1.java (at line 3)\n" + 
+			"	@SuppressWarnings(\"unused\")\n" + 
+			"	^^^^^^^^^^^^^^^^^\n" + 
+			"Syntax error: callin annotations must be specified after the callin name (OTJLD A.3.3).\n" + 
+			"----------\n");
+    }
+
+    // illegal order of callin label and annotation (short)
+    public void test8133_callinWithNameAndAnnotation2() {
+    	runNegativeTest(
+    		new String[] {
+    	"Team8133cwnaa2.java",
+    			"public team class Team8133cwnaa2 {\n" +
+    			"    protected class R playedBy T8133cwnaa2 {\n" +
+    			"	     @SuppressWarnings(\"unused\")\n" +
+    			"        name: foo <- after bar;\n" +
+    			"        void foo() {}\n" +
+    			"    }\n" +
+    			"}\n",
+    	"T8133cwnaa2.java",
+    			"public class T8133cwnaa2 { void bar() {} }\n"
+    		},
+    		"----------\n" + 
+			"1. ERROR in Team8133cwnaa2.java (at line 3)\n" + 
+			"	@SuppressWarnings(\"unused\")\n" + 
+			"	^^^^^^^^^^^^^^^^^\n" + 
+			"Syntax error: callin annotations must be specified after the callin name (OTJLD A.3.3).\n" + 
+			"----------\n");
+    }
+    
+    // correct order of callin label and annotation (long)
+    public void test8133_callinWithNameAndAnnotation3() {
+    	runConformTest(
+    		new String[] {
+    	"Team8133cwnaa3.java",
+    			"public team class Team8133cwnaa3 {\n" +
+    			"    protected class R playedBy T8133cwnaa3 {\n" +
+    			"        name:\n" +
+    			"	     @SuppressWarnings(\"all\")\n" +
+    			"        void foo() <- after void bar();\n" +
+    			"        void foo() {}\n" +
+    			"    }\n" +
+    			"}\n",
+    	"T8133cwnaa3.java",
+    			"public class T8133cwnaa3 { void bar() {} }\n"
+    		},
+    		"");
+    }
+
+    // correct order of callin label and annotation (short)
+    public void test8133_callinWithNameAndAnnotation4() {
+    	runConformTest(
+    		new String[] {
+    	"Team8133cwnaa4.java",
+    			"public team class Team8133cwnaa4 {\n" +
+    			"    protected class R playedBy T8133cwnaa4 {\n" +
+    			"        name:\n" +
+    			"	     @SuppressWarnings(\"all\")\n" +
+    			"        foo <- after bar;\n" +
+    			"        void foo() {}\n" +
+    			"    }\n" +
+    			"}\n",
+    	"T8133cwnaa4.java",
+    			"public class T8133cwnaa4 { void bar() {} }\n"
+    		},
+    		"");
+    }
 }