[ 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)