diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
index 89801b5de43c..dc4af2ee9f40 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
@@ -361,6 +361,7 @@ cannot.find.operator.overload.method=Cannot resolve index access with arguments
named.arguments.are.not.allowed.inside.index.operations=Named arguments are not allowed inside index operations
expected.0.to.be.inline.constant=Expected ''{0}'' to be an inline constant
cannot.assign.a.value.to.final.field.0=Cannot assign a value to final field ''{0}''
+cannot.assign.a.value.to.final.parameter.0=Cannot assign a value to final parameter ''{0}''
variable.0.might.not.have.been.initialized=Variable ''{0}'' might not have been initialized
unexpected.symbol=Unexpected symbol
statement.expected=Statement expected
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
index c217be6ab35b..7a570e0a3c9f 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
@@ -284,6 +284,7 @@ public class GroovyAnnotator extends GroovyElementVisitor {
checkStringNameIdentifier(referenceExpression);
checkThisOrSuperReferenceExpression(referenceExpression, myHolder);
checkFinalFieldAccess(referenceExpression);
+ checkFinalParameterAccess(referenceExpression);
if (ResolveUtil.isKeyOfMap(referenceExpression)) {
PsiElement nameElement = referenceExpression.getReferenceNameElement();
LOG.assertTrue(nameElement != null);
@@ -296,6 +297,19 @@ public class GroovyAnnotator extends GroovyElementVisitor {
}
}
+ private void checkFinalParameterAccess(GrReferenceExpression ref) {
+ final PsiElement resolved = ref.resolve();
+
+ if (resolved instanceof GrParameter) {
+ final GrParameter parameter = (GrParameter)resolved;
+ if (parameter.isPhysical() && parameter.hasModifierProperty(FINAL) && PsiUtil.isLValue(ref)) {
+ if (parameter.getDeclarationScope() instanceof PsiMethod) {
+ myHolder.createErrorAnnotation(ref, GroovyBundle.message("cannot.assign.a.value.to.final.parameter.0", parameter.getName()));
+ }
+ }
+ }
+ }
+
private void checkFinalFieldAccess(@NotNull GrReferenceExpression ref) {
final PsiElement resolved = ref.resolve();
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
index 0331e2e4f6c9..7dc1e6fd9186 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy
@@ -1426,4 +1426,28 @@ A.foo = 3 //no error
}
''')
}
+
+ void testFinalParameter() {
+ testHighlighting('''\
+def foo0(final i) {
+ i = 5
+ print i
+}
+
+def foo1(i) {
+ i = 5
+ print i
+}
+
+def foo2(final i = 4) {
+ i = 5
+ print i
+}
+
+def foo3(final i) {
+ print i
+}
+''')
+ }
+
}
\ No newline at end of file