Skip to content

Commit c166fd8

Browse files
committed
final fields cannot be set anymore
1 parent e72d385 commit c166fd8

10 files changed

+70
-8
lines changed

src/assets/app/mainpage.js

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ require("./tests/testsForTypescript");
1212
require("./tests/testGC");
1313
require("./tests/testsMemoryManagement");
1414
require("./tests/testIfAbleToRunExternalFile");
15+
require("./tests/finalFieldsSetTests");
1516

1617
var MainActivity = com.tns.NativeScriptActivity.extends({
1718
onCreate: function() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
var Assert = function(condition, failMessage) {
2+
if (condition == false) {
3+
fail(failMessage);
4+
}
5+
}
6+
7+
var When_a_java_final_field_is_set_exception_is_thrown = function() {
8+
9+
var exceptionCaught = false;
10+
var myButton1 = new com.tns.tests.Button1();
11+
try
12+
{
13+
myButton1.STATIC_IMAGE_ID = "NEW STATIC IMAGE ID VALUE";
14+
}
15+
catch (e)
16+
{
17+
Log("Tried to set final field: " + e);
18+
exceptionCaught = true;
19+
}
20+
21+
Assert(exceptionCaught === true, "When_a_java_final_field_is_set_exception_is_thrown FAILED: Exception(illegal access) should be thrown");
22+
}
23+
24+
When_a_java_final_field_is_set_exception_is_thrown();
624 Bytes
Binary file not shown.
3.53 KB
Binary file not shown.
37.8 KB
Binary file not shown.

src/jni/MetadataEntry.h

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace tns
3030
std::string declaringType;
3131
int paramCount;
3232
bool isStatic;
33+
bool isFinal;
3334
bool isMember;
3435
};
3536
}

src/jni/MetadataNode.cpp

+21-5
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ bool MetadataNode::IsMarkedAsSuper(const Handle<Object>& obj)
245245
Handle<Object> MetadataNode::CreateClassProxy(Isolate *isolate)
246246
{
247247
auto existingClassProxy = GetExistingClassProxy(m_name);
248+
248249
if (!existingClassProxy.IsEmpty())
249250
{
250251
return existingClassProxy;
@@ -601,6 +602,7 @@ Handle<Object> MetadataNode::GetImplementationObject(const Handle<Object>& objec
601602
void MetadataNode::GetterCallback(Local<String> property, const PropertyCallbackInfo<Value>& info)
602603
{
603604
string propName = ConvertToString(property);
605+
604606
if (propName.empty())
605607
return;
606608

@@ -1168,6 +1170,7 @@ vector<MetadataEntry> MetadataNode::GetMetadataCandidatesForTypeWithoutCustomMet
11681170
curPtr += sizeof(uint8_t) + sizeof(uint32_t);
11691171
}
11701172

1173+
//get candidates from instance methods metadata
11711174
uint16_t instanceMethodCout = *reinterpret_cast<uint16_t*>(curPtr);
11721175
curPtr += sizeof(uint16_t);
11731176
for (int i = 0; i < instanceMethodCout; i++)
@@ -1181,6 +1184,7 @@ vector<MetadataEntry> MetadataNode::GetMetadataCandidatesForTypeWithoutCustomMet
11811184
}
11821185
}
11831186

1187+
//get candidates from static methods metadata
11841188
uint16_t staticMethodCout = *reinterpret_cast<uint16_t*>(curPtr);
11851189
curPtr += sizeof(uint16_t);
11861190
for (int i = 0; i < staticMethodCout; i++)
@@ -1211,6 +1215,7 @@ vector<MetadataEntry> MetadataNode::GetMetadataCandidatesForTypeWithoutCustomMet
12111215
candidates.push_back(extendsEntry);
12121216
}
12131217

1218+
//get candidates from instance fields metadata
12141219
uint16_t instanceFieldCout = *reinterpret_cast<uint16_t*>(curPtr);
12151220
curPtr += sizeof(uint16_t);
12161221
for (int i = 0; i < instanceFieldCout; i++)
@@ -1224,6 +1229,7 @@ vector<MetadataEntry> MetadataNode::GetMetadataCandidatesForTypeWithoutCustomMet
12241229
}
12251230
}
12261231

1232+
//get candidates from static fields metadata
12271233
uint16_t staticFieldCout = *reinterpret_cast<uint16_t*>(curPtr);
12281234
curPtr += sizeof(uint16_t);
12291235
for (int i = 0; i < staticFieldCout; i++)
@@ -1327,20 +1333,21 @@ Handle<Function> MetadataNode::CreateFunction(const Handle<Object>& thiz, const
13271333
void MetadataNode::SetterCallback(Local<String> property, Local<Value> value, const PropertyCallbackInfo<Value>& info)
13281334
{
13291335
string propName = ConvertToString(property);
1336+
13301337
if (propName.empty())
13311338
return;
13321339

13331340
auto thiz = info.This();
13341341
MetadataNode *node = GetNodeFromHandle(thiz);
13351342

1336-
//
13371343
auto& cache = node->m_childCache;
13381344
auto itStart = cache.begin();
13391345
auto itEnd = cache.end();
13401346
auto itFound = find_if(itStart, itEnd, [&propName] (const MetadataCacheItem& item) { return item.name == propName; } );
13411347
if (itFound != itEnd)
13421348
{
13431349
const auto& cacheItem = *itFound;
1350+
13441351
if (cacheItem.type == MetadataCacheItemType::Field)
13451352
{
13461353
bool isStatic = cacheItem.entry.type == NodeType::StaticField;
@@ -1351,9 +1358,11 @@ void MetadataNode::SetterCallback(Local<String> property, Local<Value> value, co
13511358
{
13521359
assert(false);
13531360
}
1354-
return;
1361+
if (!cacheItem.entry.isFinal)
1362+
{
1363+
return;
1364+
}
13551365
}
1356-
//
13571366

13581367
DEBUG_WRITE("MetadataNode::SetterCallback propName='%s', node='%s', hash=%d", propName.c_str(), node->m_name.c_str(), thiz->GetIdentityHash());
13591368

@@ -1373,12 +1382,19 @@ void MetadataNode::SetterCallback(Local<String> property, Local<Value> value, co
13731382

13741383
if ((first.type == NodeType::Field) || (first.type == NodeType::StaticField))
13751384
{
1385+
if(first.isFinal)
1386+
{
1387+
Isolate *isolate(Isolate::GetCurrent());
1388+
Handle<String> exceptionMessage = ConvertToV8String("You are trying to SET a final field! Final fields can only be read.");
1389+
Local<Value> IllegalAccessException(exceptionMessage);
1390+
1391+
isolate->ThrowException(IllegalAccessException);
1392+
}
13761393
s_setJavaField(thiz, value, node->m_name, first.name, first.sig, first.declaringType, first.isStatic);
1377-
//
1394+
13781395
MetadataCacheItem cacheItem(propName, nullptr, MetadataCacheItemType::Field);
13791396
cacheItem.entry = first;
13801397
cache.push_back(cacheItem);
1381-
//
13821398
}
13831399
else
13841400
{

src/jni/MetadataReader.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -79,21 +79,32 @@ MetadataEntry MetadataReader::ReadInstanceFieldEntry(uint8_t*& data)
7979
MetadataEntry entry;
8080
uint8_t *curPtr = data;
8181

82+
//read name
8283
uint32_t nameOffset = *reinterpret_cast<uint32_t*>(curPtr);
8384
string name = ReadName(m_nameData, nameOffset);
8485
curPtr += sizeof(uint32_t);
8586

8687
uint16_t *nodeIdPtr = reinterpret_cast<uint16_t*>(curPtr);
8788

89+
// read node pointer id
8890
uint16_t nodeId = *nodeIdPtr++;
8991
string fieldTypeName = ReadTypeName(nodeId);
9092

93+
// read modifier
94+
uint8_t *nodeFinalVarPtr = reinterpret_cast<uint8_t*>(nodeIdPtr);
95+
uint8_t nodeFinalVar = *nodeFinalVarPtr;
96+
97+
if(nodeFinalVar == MetadataTreeNode::FINAL){
98+
entry.isFinal = true;
99+
nodeFinalVarPtr += sizeof(uint8_t);
100+
}
101+
91102
entry.name = name;
92103
entry.type = NodeType::Field;
93104
entry.sig = fieldTypeName;
94105
entry.isMember = true;
95106

96-
data = reinterpret_cast<uint8_t*>(nodeIdPtr);
107+
data = nodeFinalVarPtr;
97108

98109
return entry;
99110
}
@@ -104,7 +115,6 @@ MetadataEntry MetadataReader::ReadStaticFieldEntry(uint8_t*& data)
104115
MetadataEntry entry = ReadInstanceFieldEntry(data);
105116

106117
uint16_t *nodeIdPtr = reinterpret_cast<uint16_t*>(data);
107-
108118
uint16_t nodeId = *nodeIdPtr++;
109119
string declTypeName = ReadTypeName(nodeId);
110120

src/jni/MetadataTreeNode.h

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace tns
2626
static const uint8_t STATIC = 1 << 2;
2727
static const uint8_t ARRAY = 1 << 3;
2828
static const uint8_t PRIMITIVE = 1 << 4;
29+
static const uint8_t FINAL = 1 << 5;
2930
static const uint8_t PRIMITIVE_BYTE = 1 + PRIMITIVE;
3031
static const uint8_t PRIMITIVE_SHORT = 2 + PRIMITIVE;
3132
static const uint8_t PRIMITIVE_INT = 3 + PRIMITIVE;

src/src/com/tns/tests/Button1.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,16 @@ public int getInt()
7979

8080
private boolean IMAGE_ID_BOOL_PROP = false;
8181

82-
82+
public String GetStaticImageId()
83+
{
84+
return STATIC_IMAGE_ID;
85+
}
86+
87+
public static String SGetStaticImageId()
88+
{
89+
return STATIC_IMAGE_ID;
90+
}
91+
8392
public Button1()
8493
{
8594
Log.d(logTag, "Button instance created from javascript");

0 commit comments

Comments
 (0)