Commit 20ec96d9 authored by qsr@chromium.org's avatar qsr@chromium.org

Updating JNIAdditionalImport to allow more than one import.

R=bulach@chromium.org

Review URL: https://codereview.chromium.org/298973005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272524 0039d316-1c4b-4281-b951-d872f2087c98
parent 0d8239e4
...@@ -31,5 +31,5 @@ import java.lang.annotation.Target; ...@@ -31,5 +31,5 @@ import java.lang.annotation.Target;
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS) @Retention(RetentionPolicy.CLASS)
public @interface JNIAdditionalImport { public @interface JNIAdditionalImport {
Class<?> value(); Class<?>[] value();
} }
...@@ -161,6 +161,19 @@ class JniParams(object): ...@@ -161,6 +161,19 @@ class JniParams(object):
JniParams._fully_qualified_class = 'L' + fully_qualified_class JniParams._fully_qualified_class = 'L' + fully_qualified_class
JniParams._package = '/'.join(fully_qualified_class.split('/')[:-1]) JniParams._package = '/'.join(fully_qualified_class.split('/')[:-1])
@staticmethod
def AddAdditionalImport(class_name):
assert class_name.endswith('.class')
raw_class_name = class_name[:-len('.class')]
if '.' in raw_class_name:
raise SyntaxError('%s cannot be used in @JNIAdditionalImport. '
'Only import unqualified outer classes.' % class_name)
new_import = 'L%s/%s' % (JniParams._package, raw_class_name)
if new_import in JniParams._imports:
raise SyntaxError('Do not use JNIAdditionalImport on an already '
'imported class: %s' % (new_import.replace('/', '.')))
JniParams._imports += [new_import]
@staticmethod @staticmethod
def ExtractImportsAndInnerClasses(contents): def ExtractImportsAndInnerClasses(contents):
if not JniParams._package: if not JniParams._package:
...@@ -179,17 +192,10 @@ class JniParams(object): ...@@ -179,17 +192,10 @@ class JniParams(object):
inner] inner]
re_additional_imports = re.compile( re_additional_imports = re.compile(
r'@JNIAdditionalImport\((?P<class_name>\w+?)\.class\)') r'@JNIAdditionalImport\(\s*{?(?P<class_names>.*?)}?\s*\)')
for match in re.finditer(re_additional_imports, contents): for match in re.finditer(re_additional_imports, contents):
class_name = match.group('class_name') for class_name in match.group('class_names').split(','):
if '.' in class_name: JniParams.AddAdditionalImport(class_name.strip())
raise SyntaxError('*.class cannot be used in @JNIAdditionalImport. '
'Only import unqualified outer classes.' % class_name)
new_import = 'L%s/%s' % (JniParams._package, class_name)
if new_import in JniParams._imports:
raise SyntaxError('Do not use JNIAdditionalImport on an already '
'imported class: %s' % (new_import.replace('/', '.')))
JniParams._imports += [new_import]
@staticmethod @staticmethod
def ParseJavaPSignature(signature_line): def ParseJavaPSignature(signature_line):
......
...@@ -148,6 +148,8 @@ class TestGenerator(unittest.TestCase): ...@@ -148,6 +148,8 @@ class TestGenerator(unittest.TestCase):
int nativeDataFetcherImplAndroid, int nativeDataFetcherImplAndroid,
double alpha, double beta, double gamma); double alpha, double beta, double gamma);
""" """
jni_generator.JniParams.SetFullyQualifiedClass(
'org/chromium/example/jni_generator/SampleForTests')
jni_generator.JniParams.ExtractImportsAndInnerClasses(test_data) jni_generator.JniParams.ExtractImportsAndInnerClasses(test_data)
natives = jni_generator.ExtractNatives(test_data, 'int') natives = jni_generator.ExtractNatives(test_data, 'int')
golden_natives = [ golden_natives = [
...@@ -1033,7 +1035,7 @@ class Foo { ...@@ -1033,7 +1035,7 @@ class Foo {
# Ensure it's fine with the import. # Ensure it's fine with the import.
generate('import java.lang.Runnable;') generate('import java.lang.Runnable;')
def testJNIAdditionalImport(self): def testSingleJNIAdditionalImport(self):
test_data = """ test_data = """
package org.chromium.foo; package org.chromium.foo;
...@@ -1052,6 +1054,27 @@ class Foo { ...@@ -1052,6 +1054,27 @@ class Foo {
TestOptions()) TestOptions())
self.assertGoldenTextEquals(jni_from_java.GetContent()) self.assertGoldenTextEquals(jni_from_java.GetContent())
def testMultipleJNIAdditionalImport(self):
test_data = """
package org.chromium.foo;
@JNIAdditionalImport({Bar1.class, Bar2.class})
class Foo {
@CalledByNative
private static void calledByNative(Bar1.Callback callback1,
Bar2.Callback callback2) {
}
private static native void nativeDoSomething(Bar1.Callback callback1,
Bar2.Callback callback2);
}
"""
jni_from_java = jni_generator.JNIFromJavaSource(test_data,
'org/chromium/foo/Foo',
TestOptions())
self.assertGoldenTextEquals(jni_from_java.GetContent())
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file is autogenerated by
// base/android/jni_generator/jni_generator.py
// For
// org/chromium/foo/Foo
#ifndef org_chromium_foo_Foo_JNI
#define org_chromium_foo_Foo_JNI
#include <jni.h>
#include "base/android/jni_generator/jni_generator_helper.h"
#include "base/android/jni_int_wrapper.h"
// Step 1: forward declarations.
namespace {
const char kFooClassPath[] = "org/chromium/foo/Foo";
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_Foo_clazz = NULL;
} // namespace
static void DoSomething(JNIEnv* env, jclass jcaller,
jobject callback1,
jobject callback2);
// Step 2: method stubs.
static base::subtle::AtomicWord g_Foo_calledByNative = 0;
static void Java_Foo_calledByNative(JNIEnv* env, jobject callback1,
jobject callback2) {
/* Must call RegisterNativesImpl() */
CHECK_CLAZZ(env, g_Foo_clazz,
g_Foo_clazz);
jmethodID method_id =
base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_STATIC>(
env, g_Foo_clazz,
"calledByNative",
"("
"Lorg/chromium/foo/Bar1$Callback;"
"Lorg/chromium/foo/Bar2$Callback;"
")"
"V",
&g_Foo_calledByNative);
env->CallStaticVoidMethod(g_Foo_clazz,
method_id, callback1, callback2);
jni_generator::CheckException(env);
}
// Step 3: RegisterNatives.
static const JNINativeMethod kMethodsFoo[] = {
{ "nativeDoSomething",
"("
"Lorg/chromium/foo/Bar1$Callback;"
"Lorg/chromium/foo/Bar2$Callback;"
")"
"V", reinterpret_cast<void*>(DoSomething) },
};
static bool RegisterNativesImpl(JNIEnv* env) {
g_Foo_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
base::android::GetClass(env, kFooClassPath).obj()));
const int kMethodsFooSize = arraysize(kMethodsFoo);
if (env->RegisterNatives(g_Foo_clazz,
kMethodsFoo,
kMethodsFooSize) < 0) {
jni_generator::HandleRegistrationError(
env, g_Foo_clazz, __FILE__);
return false;
}
return true;
}
#endif // org_chromium_foo_Foo_JNI
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment