private void addMopMethods()

in src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java [226:337]


    private void addMopMethods(final InnerClassNode node) {
        final boolean isStatic = isStatic(node);
        final ClassNode outerClass = node.getOuterClass();
        final int outerClassDistance = getObjectDistance(outerClass);
        final String classInternalName = BytecodeHelper.getClassInternalName(node);
        final String outerClassInternalName = getInternalName(outerClass, isStatic);
        final String outerClassDescriptor = getTypeDescriptor(outerClass, isStatic);

        addMissingHandler(node,
                "methodMissing",
                ACC_PUBLIC,
                OBJECT_TYPE,
                params(param(STRING_TYPE, "name"), param(OBJECT_TYPE, "args")),
                (methodBody, parameters) -> {
                    if (isStatic) {
                        setMethodDispatcherCode(methodBody, classX(outerClass), parameters);
                    } else {
                        methodBody.addStatement(
                                new BytecodeSequence(new BytecodeInstruction() {
                                    @Override
                                    public void visit(final MethodVisitor mv) {
                                        getThis(mv, classInternalName, outerClassDescriptor, outerClassInternalName);
                                        mv.visitVarInsn(ALOAD, 1);
                                        mv.visitVarInsn(ALOAD, 2);
                                        mv.visitMethodInsn(INVOKEVIRTUAL, outerClassInternalName, "this$dist$invoke$" + outerClassDistance, "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", false);
                                        mv.visitInsn(ARETURN);
                                    }
                                })
                        );
                    }
                }
        );

        addMissingHandler(node,
                "$static_methodMissing",
                ACC_PUBLIC | ACC_STATIC,
                OBJECT_TYPE,
                params(param(STRING_TYPE, "name"), param(OBJECT_TYPE, "args")),
                (methodBody, parameters) -> {
                    setMethodDispatcherCode(methodBody, classX(outerClass), parameters);
                }
        );

        addMissingHandler(node,
                "propertyMissing",
                ACC_PUBLIC,
                VOID_TYPE,
                params(param(STRING_TYPE, "name"), param(OBJECT_TYPE, "value")),
                (methodBody, parameters) -> {
                    if (isStatic) {
                        setPropertySetterDispatcher(methodBody, classX(outerClass), parameters);
                    } else {
                        methodBody.addStatement(
                                new BytecodeSequence(new BytecodeInstruction() {
                                    @Override
                                    public void visit(final MethodVisitor mv) {
                                        getThis(mv, classInternalName, outerClassDescriptor, outerClassInternalName);
                                        mv.visitVarInsn(ALOAD, 1);
                                        mv.visitVarInsn(ALOAD, 2);
                                        mv.visitMethodInsn(INVOKEVIRTUAL, outerClassInternalName, "this$dist$set$" + outerClassDistance, "(Ljava/lang/String;Ljava/lang/Object;)V", false);
                                        mv.visitInsn(RETURN);
                                    }
                                })
                        );
                    }
                }
        );

        addMissingHandler(node,
                "$static_propertyMissing",
                ACC_PUBLIC | ACC_STATIC,
                VOID_TYPE,
                params(param(STRING_TYPE, "name"), param(OBJECT_TYPE, "value")),
                (methodBody, parameters) -> {
                    setPropertySetterDispatcher(methodBody, classX(outerClass), parameters);
                }
        );

        addMissingHandler(node,
                "propertyMissing",
                ACC_PUBLIC,
                OBJECT_TYPE,
                params(param(STRING_TYPE, "name")),
                (methodBody, parameters) -> {
                    if (isStatic) {
                        setPropertyGetterDispatcher(methodBody, classX(outerClass), parameters);
                    } else {
                        methodBody.addStatement(
                                new BytecodeSequence(new BytecodeInstruction() {
                                    @Override
                                    public void visit(final MethodVisitor mv) {
                                        getThis(mv, classInternalName, outerClassDescriptor, outerClassInternalName);
                                        mv.visitVarInsn(ALOAD, 1);
                                        mv.visitMethodInsn(INVOKEVIRTUAL, outerClassInternalName, "this$dist$get$" + outerClassDistance, "(Ljava/lang/String;)Ljava/lang/Object;", false);
                                        mv.visitInsn(ARETURN);
                                    }
                                })
                        );
                    }
                }
        );

        addMissingHandler(node,
                "$static_propertyMissing",
                ACC_PUBLIC | ACC_STATIC,
                OBJECT_TYPE,
                params(param(STRING_TYPE, "name")),
                (methodBody, parameters) -> {
                    setPropertyGetterDispatcher(methodBody, classX(outerClass), parameters);
                }
        );
    }