[ 
https://issues.apache.org/jira/browse/GROOVY-9127?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16848284#comment-16848284
 ] 

Eric Milles commented on GROOVY-9127:
-------------------------------------

{{StaticTypeCheckingVisitor.existsProperty}} is looking for a setter, finds 
none and then finds a getter, so it indicates that the property is read-only. 
This block could look for accessible field. OrĀ {{typeCheckAssignment}} could 
check for accessible field in case of assignment and read-only property.
{code:java}
                ...
                FieldNode field = current.getDeclaredField(propertyName); // 
could check parent class for accessible field...
                field = allowStaticAccessToMember(field, staticOnly);
                if (storeField(field, isAttributeExpression, pexp, current, 
visitor, receiver.getData(), !readMode))
                    return true;
                ...
                } else if (!readMode && checkGetterOrSetter) {
                    if (!setters.isEmpty()) {
                        if (visitor != null) {
                            if (field != null) {
                                visitor.visitField(field);
                            } else {
                                for (MethodNode setter : setters) {
                                    ClassNode setterType = 
setter.getParameters()[0].getOriginType();
                                    FieldNode virtual = new 
FieldNode(propertyName, 0, setterType, current, EmptyExpression.INSTANCE);
                                    visitor.visitField(virtual);
                                }
                            }
                        }
                        //TODO: apply generics on parameter[0]?
//                                storeType(pexp, 
setter.getParameters()[0].getType());
                        SetterInfo info = new SetterInfo(current, setterName, 
setters);
                        BinaryExpression enclosingBinaryExpression = 
typeCheckingContext.getEnclosingBinaryExpression();
                        if (enclosingBinaryExpression != null) {
                            
putSetterInfo(enclosingBinaryExpression.getLeftExpression(), info);
                        }
                        String delegationData = receiver.getData();
                        if (delegationData != null) {
                            
pexp.putNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER, delegationData);
                        }
                        return true;
                    } else if (getter != null && propertyNode == null) {
                        
pexp.putNodeMetaData(StaticTypesMarker.READONLY_PROPERTY, Boolean.TRUE); // 
gets here!
                    }
                }


    protected void typeCheckAssignment(
            final BinaryExpression assignmentExpression,
            final Expression leftExpression,
            final ClassNode leftExpressionType,
            final Expression rightExpression,
            final ClassNode inferredRightExpressionTypeOrig) {
        ClassNode inferredRightExpressionType = inferredRightExpressionTypeOrig;
        if (!typeCheckMultipleAssignmentAndContinue(leftExpression, 
rightExpression)) return;

        if (leftExpression instanceof VariableExpression
                && ((VariableExpression) leftExpression).getAccessedVariable() 
instanceof FieldNode) {
            checkOrMarkPrivateAccess(leftExpression, (FieldNode) 
((VariableExpression) leftExpression).getAccessedVariable(), true);
        }

        //TODO: need errors for write-only too!
        if (addedReadOnlyPropertyError(leftExpression)) return; // error 
recorded here!
{code}

> Cannot set protected field from subclass
> ----------------------------------------
>
>                 Key: GROOVY-9127
>                 URL: https://issues.apache.org/jira/browse/GROOVY-9127
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.5.6
>            Reporter: paolo di tommaso
>            Priority: Major
>
> Consider the following code 
> {code}
> @CompileStatic
> abstract class Foo {
>     protected String field1
>     String getField1() {
>         field1
>     }
> }
> @CompileStatic
> class Bar extends Foo {
>     void changeField1()  {
>         this.field1 = 'foo'
>     }
>     @Override
>     String getField1() { return 'bar command' }
> }
> {code}
> It fails to compile with the following error message: 
> {code}
> [Static type checking] - Cannot set read-only property: field1
>  @ line 29, column 9.
>            this.field1 = 'foo'
>            ^
> {code}
> Which does not make much sense to me because protected field should be 
> accessible to subclasses by definition. Tested also with 2.5.8-SNAPSHOT 
> reporting the same issue.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to