mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
final fields cannot be modified inside its class
This commit is contained in:
@@ -360,3 +360,4 @@ annotation.type.cannot.be.inner=Annotation type cannot be inner
|
||||
cannot.find.operator.overload.method=Cannot resolve index access with arguments {0}
|
||||
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}''
|
||||
|
||||
@@ -286,6 +286,7 @@ public class GroovyAnnotator extends GroovyElementVisitor {
|
||||
public void visitReferenceExpression(final GrReferenceExpression referenceExpression) {
|
||||
checkStringNameIdentifier(referenceExpression);
|
||||
checkThisOrSuperReferenceExpression(referenceExpression, myHolder);
|
||||
checkFinalFieldAccess(referenceExpression);
|
||||
if (ResolveUtil.isKeyOfMap(referenceExpression)) {
|
||||
PsiElement nameElement = referenceExpression.getReferenceNameElement();
|
||||
LOG.assertTrue(nameElement != null);
|
||||
@@ -298,6 +299,40 @@ public class GroovyAnnotator extends GroovyElementVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkFinalFieldAccess(@NotNull GrReferenceExpression ref) {
|
||||
final PsiElement resolved = ref.resolve();
|
||||
|
||||
if (resolved instanceof GrField && resolved.isPhysical() && ((GrField)resolved).hasModifierProperty(FINAL) && PsiUtil.isLValue(ref)) {
|
||||
final GrField field = (GrField)resolved;
|
||||
|
||||
final PsiClass containingClass = field.getContainingClass();
|
||||
if (containingClass != null && PsiTreeUtil.isAncestor(containingClass, ref, true)) {
|
||||
GrMember container = findClassMemberContainer(ref, containingClass);
|
||||
|
||||
if (field.hasModifierProperty(STATIC)) {
|
||||
if (container instanceof GrClassInitializer && ((GrClassInitializer)container).isStatic()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (container instanceof GrMethod && ((GrMethod)container).isConstructor()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
myHolder.createErrorAnnotation(ref, GroovyBundle.message("cannot.assign.a.value.to.final.field.0", field.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static GrMember findClassMemberContainer(@NotNull GrReferenceExpression ref, @NotNull PsiClass aClass) {
|
||||
for (PsiElement parent = ref.getParent(); parent != null && parent != aClass; parent = parent.getParent()) {
|
||||
if (parent instanceof GrMember && ((GrMember)parent).getContainingClass() == aClass) return (GrMember)parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkStringNameIdentifier(GrReferenceExpression ref) {
|
||||
final PsiElement nameElement = ref.getReferenceNameElement();
|
||||
if (nameElement == null) return;
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,9 +20,9 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiCodeBlock;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
|
||||
@@ -56,12 +56,12 @@ public class GrClassInitializerImpl extends GroovyPsiElementImpl implements GrCl
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return findChildByType(GroovyTokenTypes.kSTATIC) != null;
|
||||
return getModifierList().hasExplicitModifier(PsiModifier.STATIC);
|
||||
}
|
||||
|
||||
|
||||
public PsiClass getContainingClass() {
|
||||
PsiElement parent = getParent().getParent();
|
||||
PsiElement parent = getParent();
|
||||
if (parent instanceof GrTypeDefinitionBody) {
|
||||
final PsiElement pparent = parent.getParent();
|
||||
if (pparent instanceof PsiClass) {
|
||||
|
||||
+43
@@ -1368,5 +1368,48 @@ def bar
|
||||
''')
|
||||
}
|
||||
|
||||
void testFinalFieldRewrite() {
|
||||
testHighlighting('''\
|
||||
class A {
|
||||
final foo = 1
|
||||
|
||||
def A() {
|
||||
foo = 2 //no error
|
||||
}
|
||||
|
||||
def foo() {
|
||||
<error descr="Cannot assign a value to final field 'foo'">foo</error> = 2
|
||||
}
|
||||
}
|
||||
|
||||
new A().foo = 2 //no error
|
||||
''')
|
||||
}
|
||||
|
||||
void testStaticFinalFieldRewrite() {
|
||||
testHighlighting('''\
|
||||
class A {
|
||||
static final foo = 1
|
||||
|
||||
def A() {
|
||||
<error descr="Cannot assign a value to final field 'foo'">foo</error> = 2
|
||||
}
|
||||
|
||||
static {
|
||||
foo = 2 //no error
|
||||
}
|
||||
|
||||
def foo() {
|
||||
<error descr="Cannot assign a value to final field 'foo'">foo</error> = 2
|
||||
}
|
||||
|
||||
static def bar() {
|
||||
<error descr="Cannot assign a value to final field 'foo'">foo</error> = 2
|
||||
}
|
||||
}
|
||||
|
||||
A.foo = 3 //no error
|
||||
''')
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user