Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dcc9dced authored by Raphael's avatar Raphael Committed by Android Git Automerger
Browse files

am cb7c5498: am 91512f57: Layoutlib_create: Unittest for ClassHasNativeVisitor.

Merge commit 'cb7c5498'

* commit 'cb7c5498':
  Layoutlib_create: Unittest for ClassHasNativeVisitor.
parents 22ba86cf cb7c5498
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.tools.layoutlib.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Denotes a parameter or field can be null.
 * <p/>
 * When decorating a method call parameter, this denotes the parameter can
 * legitimately be null and the method will gracefully deal with it. Typically used
 * on optional parameters.
 * <p/>
 * When decorating a method, this denotes the method might legitimately return null.
 * <p/>
 * This is a marker annotation and it has no specific attributes.
 */
@Retention(RetentionPolicy.SOURCE)
public @interface Nullable {
}
+50 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.tools.layoutlib.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Denotes that the class, method or field has its visibility relaxed so
 * that unit tests can access it.
 * <p/>
 * The <code>visibility</code> argument can be used to specific what the original
 * visibility should have been if it had not been made public or package-private for testing.
 * The default is to consider the element private.
 */
@Retention(RetentionPolicy.SOURCE)
public @interface VisibleForTesting {
    /**
     * Intended visibility if the element had not been made public or package-private for
     * testing.
     */
    enum Visibility {
        /** The element should be considered protected. */
        PROTECTED,
        /** The element should be considered package-private. */
        PACKAGE,
        /** The element should be considered private. */
        PRIVATE
    }

    /**
     * Intended visibility if the element had not been made public or package-private for testing.
     * If not specified, one should assume the element originally intended to be private.
     */
    Visibility visibility() default Visibility.PRIVATE;
}
+13 −3
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.tools.layoutlib.create;

import com.android.tools.layoutlib.annotations.VisibleForTesting;
import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassVisitor;
@@ -34,6 +37,11 @@ public class ClassHasNativeVisitor implements ClassVisitor {
        return mHasNativeMethods;
    }

    @VisibleForTesting(visibility=Visibility.PRIVATE)
    protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
        mHasNativeMethods = hasNativeMethods;
    }

    public void visit(int version, int access, String name, String signature,
            String superName, String[] interfaces) {
        // pass
@@ -65,7 +73,9 @@ public class ClassHasNativeVisitor implements ClassVisitor {

    public MethodVisitor visitMethod(int access, String name, String desc,
            String signature, String[] exceptions) {
        mHasNativeMethods |= ((access & Opcodes.ACC_NATIVE) != 0);
        if ((access & Opcodes.ACC_NATIVE) != 0) {
            setHasNativeMethods(true, name);
        }
        return null;
    }

+98 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.tools.layoutlib.create;

import static org.junit.Assert.*;

import org.junit.Test;
import org.objectweb.asm.ClassReader;

import java.io.IOException;
import java.util.ArrayList;


/**
 * Tests {@link ClassHasNativeVisitor}.
 */
public class ClassHasNativeVisitorTest {

    @Test
    public void testHasNative() throws IOException {
        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
        ClassReader cr = new ClassReader(
                "com.android.tools.layoutlib.create.ClassHasNativeVisitorTest$ClassWithNative");

        cr.accept(cv, 0 /* flags */);
        assertArrayEquals(new String[] { "native_method" }, cv.getMethodsFound());
        assertTrue(cv.hasNativeMethods());
    }

    @Test
    public void testHasNoNative() throws IOException {
        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
        ClassReader cr = new ClassReader(
                "com.android.tools.layoutlib.create.ClassHasNativeVisitorTest$ClassWithoutNative");

        cr.accept(cv, 0 /* flags */);
        assertArrayEquals(new String[0], cv.getMethodsFound());
        assertFalse(cv.hasNativeMethods());
    }

    /**
     * Overrides {@link ClassHasNativeVisitor} to collec the name of the native methods found.
     */
    private static class MockClassHasNativeVisitor extends ClassHasNativeVisitor {
        private ArrayList<String> mMethodsFound = new ArrayList<String>();

        public String[] getMethodsFound() {
            return mMethodsFound.toArray(new String[mMethodsFound.size()]);
        }

        @Override
        protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
            if (hasNativeMethods) {
                mMethodsFound.add(methodName);
            }
            super.setHasNativeMethods(hasNativeMethods, methodName);
        }
    }

    /**
     * Dummy test class with a native method.
     */
    public static class ClassWithNative {
        public ClassWithNative() {
        }

        public void callTheNativeMethod() {
            native_method();
        }

        private native void native_method();
    }

    /**
     * Dummy test class with no native method.
     */
    public static class ClassWithoutNative {
        public ClassWithoutNative() {
        }

        public void someMethod() {
        }
    }
}