docs: public ClassNode getClassNode() {
          if (classNode == null && GroovyObject.class.isAssignableFrom(theClass)) {
              // let's try load it from the classpath
              String groovyFile = theClass.getName();
              int idx = groovyFile.indexOf('$');
              if (idx > 0) {
                  groovyFile = groovyFile.substring(0, idx);
              }
              groovyFile = groovyFile.replace('.', '/') + ".groovy";
  
              //System.out.println("Attempting to load: " + groovyFile);
              URL url = theClass.getClassLoader().getResource(groovyFile);
              if (url == null) {
                  url = Thread.currentThread().getContextClassLoader().getResource(groovyFile);
              }
              if (url != null) {
                  try {
  
                      /*
                       * todo there is no CompileUnit in scope so class name
                       * checking won't work but that mostly affects the bytecode
                       * generation rather than viewing the AST
                       */
                      CompilationUnit.ClassgenCallback search = new CompilationUnit.ClassgenCallback() {
                          public void call(ClassVisitor writer, ClassNode node) {
                              if (node.getName().equals(theClass.getName())) {
                                  MetaClassImpl.this.classNode = node;
                              }
                          }
                      };
  
                      CompilationUnit unit = new CompilationUnit();
                      unit.setClassgenCallback(search);
                      unit.addSource(url);
                      unit.compile(Phases.CLASS_GENERATION);
                  }
                  catch (Exception e) {
                      throw new GroovyRuntimeException("Exception thrown parsing: " + groovyFile + ". Reason: " + e, e);
                  }
              }
  
          }
          return classNode;
      }