Skip to content

Commit a9ee29e

Browse files
authored
Merge pull request #520 from NativeScript/pete/fix-inner-classes
Change Java inner classes convention
2 parents e5364a7 + 1996e68 commit a9ee29e

16 files changed

Lines changed: 128 additions & 204 deletions

runtime/src/main/java/com/tns/MethodResolver.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,15 +211,19 @@ static Constructor<?> resolveConstructor(Class<?> clazz, Object[] args) throws C
211211
{
212212
Constructor<?>[] constructors = clazz.getConstructors();
213213

214+
int argLen = (args != null) ? args.length : 0;
215+
214216
if (constructors.length == 1)
215217
{
218+
if(argLen != constructors[0].getParameterTypes().length) {
219+
return null;
220+
}
221+
216222
return constructors[0];
217223
}
218224

219225
ArrayList<Tuple<Constructor<?>, Integer>> candidates = new ArrayList<Tuple<Constructor<?>, Integer>>();
220226

221-
int argLen = (args != null) ? args.length : 0;
222-
223227
for (Constructor<?> constructor : constructors)
224228
{
225229
int dist = 0;
@@ -229,11 +233,11 @@ static Constructor<?> resolveConstructor(Class<?> clazz, Object[] args) throws C
229233

230234
if (args == null)
231235
{
232-
233236
if (paramTypes.length == 0)
234237
{
235238
return constructor;
236239
}
240+
237241
success = false;
238242
}
239243
else
@@ -273,6 +277,7 @@ static Constructor<?> resolveConstructor(Class<?> clazz, Object[] args) throws C
273277
{
274278
return constructor;
275279
}
280+
276281
candidates.add(new Tuple<Constructor<?>, Integer>(constructor, Integer.valueOf(dist)));
277282
}
278283
}

runtime/src/main/java/com/tns/Runtime.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ void passUncaughtExceptionToJs(Throwable ex, String stackTrace)
5454

5555
private final static HashSet<ClassLoader> classLoaderCache = new HashSet<ClassLoader>();
5656

57+
private final static String FAILED_CTOR_RESOLUTION_MSG = "Check the number and type of arguments.\n" +
58+
"Primitive types need to be manually wrapped in their respective Object wrappers.\n" +
59+
"If you are creating an instance of an inner class, make sure to always provide reference to the outer `this` as the first argument.";
60+
5761
private final SparseArray<Object> strongInstances = new SparseArray<Object>();
5862

5963
private final SparseArray<WeakReference<Object>> weakInstances = new SparseArray<WeakReference<Object>>();
@@ -791,7 +795,7 @@ private String resolveConstructorSignature(Class<?> clazz, Object[] args) throws
791795

792796
if (res == null)
793797
{
794-
throw new Exception("Failed resolving constructor on class " + clazz.getName());
798+
throw new Exception("Failed resolving constructor for class \'" + clazz.getName() + "\' with " + (args != null ? args.length : 0) + " parameters. " + FAILED_CTOR_RESOLUTION_MSG);
795799
}
796800

797801
return res;

runtime/src/main/jni/ArgsWrapper.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@ namespace tns
2121
struct ArgsWrapper
2222
{
2323
public:
24-
ArgsWrapper(const v8::FunctionCallbackInfo<v8::Value>& a, ArgType t, v8::Local<v8::Object> _outerThis)
24+
ArgsWrapper(const v8::FunctionCallbackInfo<v8::Value>& a, ArgType t)
2525
:
26-
args(a), type(t), outerThis(_outerThis)
26+
args(a), type(t)
2727
{
2828
}
2929
v8::FunctionCallbackInfo<v8::Value> args;
3030
ArgType type;
31-
v8::Local<v8::Object> outerThis;
3231
};
3332
}
3433

runtime/src/main/jni/CallbackHandlers.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,15 @@ bool CallbackHandlers::RegisterInstance(Isolate *isolate, const Local<Object> &j
101101
JavaObjectIdScope objIdScope(env, CURRENT_OBJECTID_FIELD_ID, runtime->GetJavaRuntime(),
102102
javaObjectID);
103103

104-
if (argWrapper.type == ArgType::Interface) {
105-
instance = env.NewObject(generatedJavaClass, mi.mid);
106-
}
107-
else {
108-
// resolve arguments before passing them on to the constructor
109-
JsArgConverter argConverter(argWrapper.args, mi.signature, argWrapper.outerThis);
110-
auto ctorArgs = argConverter.ToArgs();
104+
if(argWrapper.type == ArgType::Interface)
105+
{
106+
instance = env.NewObject(generatedJavaClass, mi.mid);
107+
}
108+
else
109+
{
110+
// resolve arguments before passing them on to the constructor
111+
JsArgConverter argConverter(argWrapper.args, mi.signature);
112+
auto ctorArgs = argConverter.ToArgs();
111113

112114
instance = env.NewObjectA(generatedJavaClass, mi.mid, ctorArgs);
113115
}

runtime/src/main/jni/JsArgConverter.cpp

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ using namespace std;
1818
using namespace tns;
1919

2020
JsArgConverter::JsArgConverter(const v8::FunctionCallbackInfo<Value>& args, bool hasImplementationObject, const string& methodSignature, MetadataEntry *entry)
21-
: m_isolate(args.GetIsolate()), m_env(JEnv()), m_methodSignature(methodSignature), m_isValid(true), m_error(Error()), m_tokens(nullptr)
21+
: m_isolate(args.GetIsolate()), m_env(JEnv()), m_methodSignature(methodSignature), m_isValid(true), m_error(Error()), m_tokens(nullptr)
2222
{
2323
m_argsLen = !hasImplementationObject ? args.Length() : args.Length() - 1;
2424

@@ -52,50 +52,8 @@ JsArgConverter::JsArgConverter(const v8::FunctionCallbackInfo<Value>& args, bool
5252
}
5353
}
5454

55-
JsArgConverter::JsArgConverter(const v8::FunctionCallbackInfo<Value>& args, const string& methodSignature, const Local<Object>& outerThis)
56-
: m_isolate(args.GetIsolate()), m_env(JEnv()), m_methodSignature(methodSignature), m_isValid(true), m_error(Error()), m_tokens(nullptr)
57-
{
58-
auto isInnerClass = !outerThis.IsEmpty();
59-
if (isInnerClass)
60-
{
61-
m_argsLen = args.Length() + 1;
62-
}
63-
else
64-
{
65-
m_argsLen = args.Length();
66-
}
67-
68-
JniSignatureParser parser(m_methodSignature);
69-
m_tokens2 = parser.Parse();
70-
m_tokens = &m_tokens2;
71-
72-
for (int i = 0; i < m_argsLen; i++)
73-
{
74-
if (isInnerClass)
75-
{
76-
if (i == 0)
77-
{
78-
m_isValid = ConvertArg(outerThis, i);
79-
}
80-
else
81-
{
82-
m_isValid = ConvertArg(args[i - 1], i);
83-
}
84-
}
85-
else
86-
{
87-
m_isValid = ConvertArg(args[i], i);
88-
}
89-
90-
if (!m_isValid)
91-
{
92-
break;
93-
}
94-
}
95-
}
96-
9755
JsArgConverter::JsArgConverter(const v8::FunctionCallbackInfo<Value>& args, const string& methodSignature)
98-
: m_isolate(args.GetIsolate()), m_env(JEnv()), m_methodSignature(methodSignature), m_isValid(true), m_error(Error()), m_tokens(nullptr)
56+
: m_isolate(args.GetIsolate()), m_env(JEnv()), m_methodSignature(methodSignature), m_isValid(true), m_error(Error()), m_tokens(nullptr)
9957
{
10058
m_argsLen = args.Length();
10159

@@ -107,6 +65,7 @@ JsArgConverter::JsArgConverter(const v8::FunctionCallbackInfo<Value>& args, cons
10765
{
10866
m_isValid = ConvertArg(args[i], i);
10967

68+
11069
if (!m_isValid)
11170
{
11271
break;
@@ -324,8 +283,8 @@ bool JsArgConverter::ConvertJavaScriptNumber(const Local<Value>& jsValue, int in
324283
bool success = true;
325284

326285
jvalue value =
327-
{
328-
0 };
286+
{
287+
0 };
329288

330289
const auto& typeSignature = m_tokens->at(index);
331290

runtime/src/main/jni/JsArgConverter.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ namespace tns
1616

1717
JsArgConverter(const v8::FunctionCallbackInfo<v8::Value>& args, const std::string& methodSignature);
1818

19-
JsArgConverter(const v8::FunctionCallbackInfo<v8::Value>& args, const std::string& methodSignature, const v8::Local<v8::Object>& outerThis);
20-
2119
~JsArgConverter();
2220

2321
jvalue* ToArgs();

runtime/src/main/jni/JsArgToArrayConverter.cpp

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ using namespace tns;
2323
* Converts a single JavaScript (V8) object to its respective Java representation
2424
*/
2525
JsArgToArrayConverter::JsArgToArrayConverter(Isolate *isolate, const v8::Local<Value>& arg, bool isImplementationObject, int classReturnType)
26-
: m_isolate(isolate), m_arr(nullptr), m_argsAsObject(nullptr), m_argsLen(0), m_isValid(false), m_error(Error()), m_return_type(classReturnType)
26+
: m_isolate(isolate), m_arr(nullptr), m_argsAsObject(nullptr), m_argsLen(0), m_isValid(false), m_error(Error()), m_return_type(classReturnType)
2727
{
2828
if (!isImplementationObject)
2929
{
@@ -38,18 +38,10 @@ JsArgToArrayConverter::JsArgToArrayConverter(Isolate *isolate, const v8::Local<V
3838
/*
3939
* Converts an array of JavaScript (V8) objects to a Java array of objects
4040
*/
41-
JsArgToArrayConverter::JsArgToArrayConverter(const v8::FunctionCallbackInfo<Value>& args, bool hasImplementationObject, const Local<Object>& outerThis)
42-
: m_isolate(args.GetIsolate()), m_arr(nullptr), m_argsAsObject(nullptr), m_argsLen(0), m_isValid(false), m_error(Error()), m_return_type(static_cast<int>(Type::Null))
41+
JsArgToArrayConverter::JsArgToArrayConverter(const v8::FunctionCallbackInfo<Value>& args, bool hasImplementationObject)
42+
: m_isolate(args.GetIsolate()), m_arr(nullptr), m_argsAsObject(nullptr), m_argsLen(0), m_isValid(false), m_error(Error()), m_return_type(static_cast<int>(Type::Null))
4343
{
44-
auto isInnerClass = !outerThis.IsEmpty();
45-
if (isInnerClass)
46-
{
47-
m_argsLen = args.Length() + 1;
48-
}
49-
else
50-
{
51-
m_argsLen = !hasImplementationObject ? args.Length() : args.Length() - 2;
52-
}
44+
m_argsLen = !hasImplementationObject ? args.Length() : args.Length() - 2;
5345

5446
bool success = true;
5547

@@ -60,21 +52,7 @@ JsArgToArrayConverter::JsArgToArrayConverter(const v8::FunctionCallbackInfo<Valu
6052

6153
for (int i = 0; i < m_argsLen; i++)
6254
{
63-
if (isInnerClass)
64-
{
65-
if (i == 0)
66-
{
67-
success = ConvertArg(outerThis, i);
68-
}
69-
else
70-
{
71-
success = ConvertArg(args[i - 1], i);
72-
}
73-
}
74-
else
75-
{
76-
success = ConvertArg(args[i], i);
77-
}
55+
success = ConvertArg(args[i], i);
7856

7957
if (!success)
8058
{
@@ -294,7 +272,7 @@ bool JsArgToArrayConverter::ConvertArg(const Local<Value>& arg, int index)
294272

295273
case CastType::None:
296274
obj = objectManager->GetJavaObjectByJsObject(jsObj);
297-
275+
298276
castValue = jsObj->GetHiddenValue(V8StringConstants::GetNullNodeName());
299277

300278
if(!castValue.IsEmpty()) {

runtime/src/main/jni/JsArgToArrayConverter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace tns
1111
class JsArgToArrayConverter
1212
{
1313
public:
14-
JsArgToArrayConverter(const v8::FunctionCallbackInfo<v8::Value>& args, bool hasImplementationObject, const v8::Local<v8::Object>& outerThis = v8::Local<v8::Object>());
14+
JsArgToArrayConverter(const v8::FunctionCallbackInfo<v8::Value>& args, bool hasImplementationObject);
1515

1616
JsArgToArrayConverter(v8::Isolate *isolate, const v8::Local<v8::Value>& arg, bool isImplementationObject, int classReturnType);
1717

0 commit comments

Comments
 (0)