Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-8208

VariableExpressionTransformer does not set source position on property expressions

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • None
    • 2.4.13
    • xforms
    • None

    Description

      Two paths in VariableExpressionTransformer create PropertyExpression nodes to stand in for unresolved variable references. Neither case sets the exp source position onto the new node. Other paths through this method transfer position info.
      The fix is simple:

      private static Expression tryTransformDelegateToProperty(VariableExpression expr) {
              // we need to transform variable expressions that go to a delegate
              // to a property expression, as ACG would loose the information
              // in processClassVariable before it reaches any makeCall, that could
              // handle it
              Object val = expr.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER);
              if (val == null) return null;
              VariableExpression implicitThis = new VariableExpression("this");
              PropertyExpression pexp = new PropertyExpression(implicitThis, expr.getName());
              pexp.copyNodeMetaData(expr);
              pexp.setImplicitThis(true);
              // GRECLIPSE add
              pexp.getProperty().setSourcePosition(expr);
              // GRECLIPSE end
              ClassNode owner = expr.getNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER);
              if (owner != null) {
                  implicitThis.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, owner);
                  implicitThis.putNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER, val);
              }
              return pexp;
          }
      
          private static Expression tryTransformPrivateFieldAccess(VariableExpression expr) {
              FieldNode field = expr.getNodeMetaData(StaticTypesMarker.PV_FIELDS_ACCESS);
              if (field == null) {
                  field = expr.getNodeMetaData(StaticTypesMarker.PV_FIELDS_MUTATION);
              }
              if (field != null) {
                  // access to a private field from a section of code that normally doesn't have access to it, like a
                  // closure or an inner class
                  VariableExpression receiver = new VariableExpression("this");
                  PropertyExpression pexp = new PropertyExpression(
                          receiver,
                          expr.getName()
                  );
                  pexp.setImplicitThis(true);
                  // GRECLIPSE add
                  pexp.getProperty().setSourcePosition(expr);
                  // GRECLIPSE end
                  // put the receiver inferred type so that the class writer knows that it will have to call a bridge method
                  receiver.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, field.getDeclaringClass());
                  // add inferred type information
                  pexp.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, field.getOriginType());
                  return pexp;
              }
              return null;
          }
      

      The first method affects code like

      @groovy.transform.CompileStatic
      class E {
          D d = new D()
          void doSomething() {
              d.with { // 'foo' and 'bar' VariableExpressions are xformed to PropertyExpressions
                  foo = 'foo'
                  bar = new D()
                  bar.foo = 'bar'
              }
          }
      }
      

      The second method affects code like

      @groovy.transform.CompileStatic
      class X {
        String id
        @Lazy Object thing = { ->
          Directory.lookup(id) // 'id' is transformed from a VariableExpression to a PropertyExpression
        }()
      }
      

      Attachments

        Issue Links

          Activity

            People

              jwagenleitner John Wagenleitner
              emilles Eric Milles
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: