/** * If we are in a constructor, that is static compiled, but in a class, that is not, it may happen * that init code from object initializers, fields or properties is added into the constructor * code. The backend assumes a purely static contructor, so it may fail if it encounters dynamic * code here. Thus we make this kind of code fail */ private void checkForConstructorWithCSButClassWithout(MethodNode node) { if (!(node instanceof ConstructorNode)) return; Object meta = node.getNodeMetaData(STATIC_COMPILE_NODE); if (!Boolean.TRUE.equals(meta)) return; ClassNode clz = typeCheckingContext.getEnclosingClassNode(); meta = clz.getNodeMetaData(STATIC_COMPILE_NODE); if (Boolean.TRUE.equals(meta)) return; if (clz.getObjectInitializerStatements().isEmpty() && clz.getFields().isEmpty() && clz.getProperties().isEmpty()) { return; } addStaticTypeError( "Cannot statically compile constructor implicitly including non static elements from object initializers, properties or fields.", node); }
protected ClassVisitor createClassVisitor() { CompilerConfiguration config = getConfiguration(); int computeMaxStackAndFrames = ClassWriter.COMPUTE_MAXS; if (CompilerConfiguration.isPostJDK7(config.getTargetBytecode()) || Boolean.TRUE.equals(config.getOptimizationOptions().get("indy"))) { computeMaxStackAndFrames += ClassWriter.COMPUTE_FRAMES; } return new ClassWriter(computeMaxStackAndFrames) { private ClassNode getClassNode(String name) { // try classes under compilation CompileUnit cu = getAST(); ClassNode cn = cu.getClass(name); if (cn != null) return cn; // try inner classes cn = cu.getGeneratedInnerClass(name); if (cn != null) return cn; // try class loader classes try { cn = ClassHelper.make(cu.getClassLoader().loadClass(name, false, true), false); } catch (Exception e) { throw new GroovyBugError(e); } return cn; } private ClassNode getCommonSuperClassNode(ClassNode c, ClassNode d) { // adapted from ClassWriter code if (c.isDerivedFrom(d)) return d; if (d.isDerivedFrom(c)) return c; if (c.isInterface() || d.isInterface()) return ClassHelper.OBJECT_TYPE; do { c = c.getSuperClass(); } while (c != null && !d.isDerivedFrom(c)); if (c == null) return ClassHelper.OBJECT_TYPE; return c; } @Override protected String getCommonSuperClass(String arg1, String arg2) { ClassNode a = getClassNode(arg1.replace('/', '.')); ClassNode b = getClassNode(arg2.replace('/', '.')); return getCommonSuperClassNode(a, b).getName().replace('.', '/'); } }; }