@@ -763,28 +763,39 @@ private boolean tryVariableExpressionAsProperty(final VariableExpression vexp, f
763763
764764 @ Override
765765 public void visitPropertyExpression (final PropertyExpression expression ) {
766- if (existsProperty (expression , !typeCheckingContext .isTargetOfEnclosingAssignment (expression ))) return ;
767-
768- if (!extension .handleUnresolvedProperty (expression )) {
769- var objectExpression = expression .getObjectExpression ();
770- var objectExpressionType = (objectExpression instanceof ClassExpression
771- ? objectExpression .getType () : wrapTypeIfNecessary (getType (objectExpression )));
772- objectExpressionType = findCurrentInstanceOfClass (objectExpression , objectExpressionType );
773- addStaticTypeError ("No such property: " + expression .getPropertyAsString () + " for class: " + prettyPrintTypeName (objectExpressionType ), expression );
766+ boolean readOnly = !typeCheckingContext .isTargetOfEnclosingAssignment (expression );
767+ if (existsProperty (expression , readOnly )
768+ || extension .handleUnresolvedProperty (expression )) {
769+ return ; // resolved or excused
774770 }
771+ recordMissingProperty (expression );
775772 }
776773
777774 @ Override
778775 public void visitAttributeExpression (final AttributeExpression expression ) {
779- if (existsProperty (expression , true )) return ;
776+ boolean readOnly = true ;
777+ if (existsProperty (expression , readOnly )
778+ || extension .handleUnresolvedAttribute (expression )) {
779+ return ; // resolved or excused
780+ }
781+ recordMissingProperty (expression );
782+ }
780783
781- if (!extension .handleUnresolvedAttribute (expression )) {
782- var objectExpression = expression .getObjectExpression ();
783- var objectExpressionType = (objectExpression instanceof ClassExpression
784- ? objectExpression .getType () : wrapTypeIfNecessary (getType (objectExpression )));
785- objectExpressionType = findCurrentInstanceOfClass (objectExpression , objectExpressionType );
786- addStaticTypeError ("No such attribute: " + expression .getPropertyAsString () + " for class: " + prettyPrintTypeName (objectExpressionType ), expression );
784+ private void recordMissingProperty (final PropertyExpression expression ) {
785+ var objectExpression = expression .getObjectExpression ();
786+ var objectExpressionType = findCurrentInstanceOfClass (objectExpression , getType (objectExpression ));
787+
788+ String pattern ;
789+ if (!isClassClassNodeWrappingConcreteType (objectExpressionType )) {
790+ pattern = "No such {0,choice,1#attribute|2#property}: {1} for class: {2}" ;
791+ } else {
792+ objectExpressionType = objectExpressionType .getGenericsTypes ()[0 ].getType ();
793+ pattern = "No such {0,choice,1#attribute|2#property}: {1} for Class or static {0,choice,1#field|2#property} for class: {2}" ;
787794 }
795+
796+ String error = java .text .MessageFormat .format (pattern , expression instanceof AttributeExpression ? 1 : 2 , expression .getPropertyAsString (), prettyPrintTypeName (wrapTypeIfNecessary (objectExpressionType )));
797+ ASTNode node = expression .getLineNumber () > 0 ? expression : expression .getProperty (); // GROOVY-11663
798+ addStaticTypeError (error , node );
788799 }
789800
790801 @ Override
0 commit comments