private static <T, G extends T> void generateOnMeasureMethod(DexMaker dexMaker,
                                                                 TypeId<G> generatedType,
                                                                 TypeId<T> baseType) {
        final FieldId<G, Interceptor> interceptorField =
                generatedType.getField(INTERCEPTOR_TYPE, FIELD_NAME_INTERCEPTOR);

        final String methodName = ViewMethod.ON_MEASURE.getName();

        final MethodId<T, Void> superMethod = baseType.getMethod(VOID_TYPE, methodName, TypeId.INT,
                TypeId.INT);
        final MethodId<Interceptor, Void> onMeasureMethod =
                INTERCEPTOR_TYPE.getMethod(VOID_TYPE, methodName, VIEW_TYPE, TypeId.INT, TypeId.INT);

        final MethodId<G, Void> methodId = generatedType.getMethod(VOID_TYPE, methodName,
                TypeId.INT, TypeId.INT);
        final Code code = dexMaker.declare(methodId, PUBLIC);

        final Local<G> localThis = code.getThis(generatedType);
        final Local<Interceptor> nullInterceptor = code.newLocal(INTERCEPTOR_TYPE);
        final Local<Interceptor> localInterceptor = code.newLocal(INTERCEPTOR_TYPE);
        final Local<Integer> localWidth = code.getParameter(0, TypeId.INT);
        final Local<Integer> localHeight = code.getParameter(1, TypeId.INT);

        code.iget(interceptorField, localInterceptor, localThis);
        code.loadConstant(nullInterceptor, null);

        // Interceptor is not null, call it.
        final Label interceptorNullCase = new Label();
        code.compare(Comparison.EQ, interceptorNullCase, nullInterceptor, localInterceptor);
        code.invokeVirtual(onMeasureMethod, null, localInterceptor, localThis,
                localWidth, localHeight);
        code.returnVoid();

        // Interceptor is null, call super method.
        code.mark(interceptorNullCase);
        code.invokeSuper(superMethod, null, localThis, localWidth, localHeight);
        code.returnVoid();

        final MethodId<G, Void> callsSuperMethod = generatedType.getMethod(VOID_TYPE,
                ViewMethod.ON_MEASURE.getInvokeName(), TypeId.INT, TypeId.INT);

        final Code superCode = dexMaker.declare(callsSuperMethod, PUBLIC);

        final Local<G> superThis = superCode.getThis(generatedType);
        final Local<Integer> superLocalWidth = superCode.getParameter(0, TypeId.INT);
        final Local<Integer> superLocalHeight = superCode.getParameter(1, TypeId.INT);
        superCode.invokeSuper(superMethod, null, superThis, superLocalWidth, superLocalHeight);
        superCode.returnVoid();
    }
private static < T , G extends T > void generateOnMeasureMethod ( DexMaker dexMaker , TypeId < G > generatedType , TypeId < T > baseType ) { final FieldId < G , Interceptor > interceptorField = generatedType . getField ( INTERCEPTOR_TYPE , FIELD_NAME_INTERCEPTOR ) ; final String methodName = ViewMethod . ON_MEASURE . getName ( ) ; final MethodId < T , Void > superMethod = baseType . getMethod ( VOID_TYPE , methodName , TypeId . INT , TypeId . INT ) ; final MethodId < Interceptor , Void > onMeasureMethod = INTERCEPTOR_TYPE . getMethod ( VOID_TYPE , methodName , VIEW_TYPE , TypeId . INT , TypeId . INT ) ; final MethodId < G , Void > methodId = generatedType . getMethod ( VOID_TYPE , methodName , TypeId . INT , TypeId . INT ) ; final Code code = dexMaker . declare ( methodId , PUBLIC ) ; final Local < G > localThis = code . getThis ( generatedType ) ; final Local < Interceptor > nullInterceptor = code . newLocal ( INTERCEPTOR_TYPE ) ; final Local < Interceptor > localInterceptor = code . newLocal ( INTERCEPTOR_TYPE ) ; final Local < Integer > localWidth = code . getParameter ( 0 , TypeId . INT ) ; final Local < Integer > localHeight = code . getParameter ( 1 , TypeId . INT ) ; code . iget ( interceptorField , localInterceptor , localThis ) ; code . loadConstant ( nullInterceptor , null ) ; final Label interceptorNullCase = new Label ( ) ; code . compare ( Comparison . EQ , interceptorNullCase , nullInterceptor , localInterceptor ) ; code . invokeVirtual ( onMeasureMethod , null , localInterceptor , localThis , localWidth , localHeight ) ; code . returnVoid ( ) ; code . mark ( interceptorNullCase ) ; code . invokeSuper ( superMethod , null , localThis , localWidth , localHeight ) ; code . returnVoid ( ) ; final MethodId < G , Void > callsSuperMethod = generatedType . getMethod ( VOID_TYPE , ViewMethod . ON_MEASURE . getInvokeName ( ) , TypeId . INT , TypeId . INT ) ; final Code superCode = dexMaker . declare ( callsSuperMethod , PUBLIC ) ; final Local < G > superThis = superCode . getThis ( generatedType ) ; final Local < Integer > superLocalWidth = superCode . getParameter ( 0 , TypeId . INT ) ; final Local < Integer > superLocalHeight = superCode . getParameter ( 1 , TypeId . INT ) ; superCode . invokeSuper ( superMethod , null , superThis , superLocalWidth , superLocalHeight ) ; superCode . returnVoid ( ) ; }
Generates the {@link android.view.View#onMeasure(int, int)} method for the proxy class.