private void createFinalFieldGetter(Field field) {
    String getterName = GroovyRuntimeUtil.propertyToGetterMethodName(field.getName());
    MethodNode getter = spec.getAst().getMethod(getterName, Parameter.EMPTY_ARRAY);
    if (getter != null) {
      errorReporter.error(field.getAst(),
          "Final field '%s' conflicts with method '%s'; please rename either of them",
          field.getName(), getter.getName());
      return;
    }

    BlockStatement getterBlock = new BlockStatement();
    getter = new MethodNode(getterName, determineVisibilityForFinalFieldAccessor(field) | Opcodes.ACC_SYNTHETIC,
        field.getAst().getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, getterBlock);

    getterBlock.addStatement(
        new ReturnStatement(
            new ExpressionStatement(
                new VariableExpression(field.getAst().getName(), field.getAst().getType()))));

    getter.setSourcePosition(field.getAst());
    spec.getAst().addMethod(getter);
  }
A Spec visitor responsible for most of the rewriting of a Spec's AST.

@author Peter Niederwieser
spock-core/src/main/java/org/spockframework/compiler/SpecRewriter.java