Skip to content

Commit 91512f5

Browse files
Raphaelralf-at-android
authored andcommitted
Layoutlib_create: Unittest for ClassHasNativeVisitor.
Change-Id: Id101bb3fc2644e450847e73c933cb6f616982f24
1 parent f2960b8 commit 91512f5

File tree

4 files changed

+196
-3
lines changed

4 files changed

+196
-3
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (C) 2010 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.tools.layoutlib.annotations;
18+
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
22+
/**
23+
* Denotes a parameter or field can be null.
24+
* <p/>
25+
* When decorating a method call parameter, this denotes the parameter can
26+
* legitimately be null and the method will gracefully deal with it. Typically used
27+
* on optional parameters.
28+
* <p/>
29+
* When decorating a method, this denotes the method might legitimately return null.
30+
* <p/>
31+
* This is a marker annotation and it has no specific attributes.
32+
*/
33+
@Retention(RetentionPolicy.SOURCE)
34+
public @interface Nullable {
35+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (C) 2010 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.tools.layoutlib.annotations;
18+
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
22+
/**
23+
* Denotes that the class, method or field has its visibility relaxed so
24+
* that unit tests can access it.
25+
* <p/>
26+
* The <code>visibility</code> argument can be used to specific what the original
27+
* visibility should have been if it had not been made public or package-private for testing.
28+
* The default is to consider the element private.
29+
*/
30+
@Retention(RetentionPolicy.SOURCE)
31+
public @interface VisibleForTesting {
32+
/**
33+
* Intended visibility if the element had not been made public or package-private for
34+
* testing.
35+
*/
36+
enum Visibility {
37+
/** The element should be considered protected. */
38+
PROTECTED,
39+
/** The element should be considered package-private. */
40+
PACKAGE,
41+
/** The element should be considered private. */
42+
PRIVATE
43+
}
44+
45+
/**
46+
* Intended visibility if the element had not been made public or package-private for testing.
47+
* If not specified, one should assume the element originally intended to be private.
48+
*/
49+
Visibility visibility() default Visibility.PRIVATE;
50+
}

tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
package com.android.tools.layoutlib.create;
1818

19+
import com.android.tools.layoutlib.annotations.VisibleForTesting;
20+
import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
21+
1922
import org.objectweb.asm.AnnotationVisitor;
2023
import org.objectweb.asm.Attribute;
2124
import org.objectweb.asm.ClassVisitor;
@@ -27,13 +30,18 @@
2730
* Indicates if a class contains any native methods.
2831
*/
2932
public class ClassHasNativeVisitor implements ClassVisitor {
30-
33+
3134
private boolean mHasNativeMethods = false;
32-
35+
3336
public boolean hasNativeMethods() {
3437
return mHasNativeMethods;
3538
}
3639

40+
@VisibleForTesting(visibility=Visibility.PRIVATE)
41+
protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
42+
mHasNativeMethods = hasNativeMethods;
43+
}
44+
3745
public void visit(int version, int access, String name, String signature,
3846
String superName, String[] interfaces) {
3947
// pass
@@ -65,7 +73,9 @@ public void visitInnerClass(String name, String outerName,
6573

6674
public MethodVisitor visitMethod(int access, String name, String desc,
6775
String signature, String[] exceptions) {
68-
mHasNativeMethods |= ((access & Opcodes.ACC_NATIVE) != 0);
76+
if ((access & Opcodes.ACC_NATIVE) != 0) {
77+
setHasNativeMethods(true, name);
78+
}
6979
return null;
7080
}
7181

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright (C) 2010 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.tools.layoutlib.create;
18+
19+
import static org.junit.Assert.*;
20+
21+
import org.junit.Test;
22+
import org.objectweb.asm.ClassReader;
23+
24+
import java.io.IOException;
25+
import java.util.ArrayList;
26+
27+
28+
/**
29+
* Tests {@link ClassHasNativeVisitor}.
30+
*/
31+
public class ClassHasNativeVisitorTest {
32+
33+
@Test
34+
public void testHasNative() throws IOException {
35+
MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
36+
ClassReader cr = new ClassReader(
37+
"com.android.tools.layoutlib.create.ClassHasNativeVisitorTest$ClassWithNative");
38+
39+
cr.accept(cv, 0 /* flags */);
40+
assertArrayEquals(new String[] { "native_method" }, cv.getMethodsFound());
41+
assertTrue(cv.hasNativeMethods());
42+
}
43+
44+
@Test
45+
public void testHasNoNative() throws IOException {
46+
MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
47+
ClassReader cr = new ClassReader(
48+
"com.android.tools.layoutlib.create.ClassHasNativeVisitorTest$ClassWithoutNative");
49+
50+
cr.accept(cv, 0 /* flags */);
51+
assertArrayEquals(new String[0], cv.getMethodsFound());
52+
assertFalse(cv.hasNativeMethods());
53+
}
54+
55+
/**
56+
* Overrides {@link ClassHasNativeVisitor} to collec the name of the native methods found.
57+
*/
58+
private static class MockClassHasNativeVisitor extends ClassHasNativeVisitor {
59+
private ArrayList<String> mMethodsFound = new ArrayList<String>();
60+
61+
public String[] getMethodsFound() {
62+
return mMethodsFound.toArray(new String[mMethodsFound.size()]);
63+
}
64+
65+
@Override
66+
protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
67+
if (hasNativeMethods) {
68+
mMethodsFound.add(methodName);
69+
}
70+
super.setHasNativeMethods(hasNativeMethods, methodName);
71+
}
72+
}
73+
74+
/**
75+
* Dummy test class with a native method.
76+
*/
77+
public static class ClassWithNative {
78+
public ClassWithNative() {
79+
}
80+
81+
public void callTheNativeMethod() {
82+
native_method();
83+
}
84+
85+
private native void native_method();
86+
}
87+
88+
/**
89+
* Dummy test class with no native method.
90+
*/
91+
public static class ClassWithoutNative {
92+
public ClassWithoutNative() {
93+
}
94+
95+
public void someMethod() {
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)