@@ -483,23 +483,86 @@ void MetadataNode::SuperAccessorGetterCallback(Local<Name> property, const Prope
483483 }
484484}
485485
486- std::vector<MetadataNode::MethodCallbackData*> MetadataNode::SetInstanceMembers (Isolate* isolate, Local<FunctionTemplate>& ctorFuncTemplate, Local<ObjectTemplate>& prototypeTemplate, vector<MethodCallbackData*>& instanceMethodsCallbackData, const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode* treeNode) {
486+ class MetadataNode ::PrototypeTemplateFiller {
487+ public:
488+ explicit PrototypeTemplateFiller (Local<ObjectTemplate> protoTemplate)
489+ : m_protoTemplate(protoTemplate) {}
490+
491+ void FillPrototypeMethod (Isolate *isolate, const std::string& name,
492+ MethodCallbackData* methodInfo) {
493+ if (m_addedNames.count (name) != 0 ) {
494+ DEBUG_WRITE (" Not defining method prototype.%s which has already been added" , name.c_str ());
495+ return ;
496+ }
497+
498+ Local<External> funcData = External::New (isolate, methodInfo);
499+ Local<FunctionTemplate> funcTemplate = FunctionTemplate::New (isolate, MetadataNode::MethodCallback, funcData);
500+ Local<String> nameString = ArgConverter::ConvertToV8String (isolate, name);
501+ m_protoTemplate->Set (nameString, funcTemplate);
502+ m_addedNames.insert (name);
503+ }
504+
505+ void FillPrototypeField (Isolate* isolate, const std::string& name, FieldCallbackData* fieldInfo,
506+ AccessControl access = AccessControl::DEFAULT) {
507+ if (m_addedNames.count (name) != 0 ) {
508+ DEBUG_WRITE (" Not defining field prototype.%s which already exists" , name.c_str ());
509+ return ;
510+ }
511+
512+ Local<External> fieldData = External::New (isolate, fieldInfo);
513+ Local<Name> nameString = ArgConverter::ConvertToV8String (isolate, name);
514+ m_protoTemplate->SetAccessor (nameString, MetadataNode::FieldAccessorGetterCallback,
515+ MetadataNode::FieldAccessorSetterCallback, fieldData, access,
516+ PropertyAttribute::DontDelete);
517+ m_addedNames.insert (name);
518+ }
519+
520+ void FillPrototypeProperty (Isolate* isolate, const std::string& name,
521+ PropertyCallbackData* propertyInfo) {
522+ if (m_addedNames.count (name) != 0 ) {
523+ DEBUG_WRITE (" Not defining property prototype.%s which already exists" , name.c_str ());
524+ return ;
525+ }
526+
527+ Local<External> propertyData = External::New (isolate, propertyInfo);
528+ Local<Name> nameString = ArgConverter::ConvertToV8String (isolate, name);
529+ m_protoTemplate->SetAccessor (nameString, MetadataNode::PropertyAccessorGetterCallback,
530+ MetadataNode::PropertyAccessorSetterCallback, propertyData,
531+ AccessControl::DEFAULT, PropertyAttribute::DontDelete);
532+ m_addedNames.insert (name);
533+ }
534+
535+ private:
536+ Local<ObjectTemplate> m_protoTemplate;
537+ std::unordered_set<std::string> m_addedNames;
538+ };
539+
540+ std::vector<MetadataNode::MethodCallbackData*> MetadataNode::SetInstanceMembers (
541+ Isolate* isolate, Local<FunctionTemplate>& ctorFuncTemplate,
542+ PrototypeTemplateFiller& protoFiller,
543+ vector<MethodCallbackData*>& instanceMethodsCallbackData,
544+ const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData,
545+ MetadataTreeNode* treeNode) {
487546 auto hasCustomMetadata = treeNode->metadata != nullptr ;
488547
489548 if (hasCustomMetadata) {
490- return SetInstanceMembersFromRuntimeMetadata (isolate, ctorFuncTemplate, prototypeTemplate, instanceMethodsCallbackData, baseInstanceMethodsCallbackData, treeNode);
491- } else {
492- SetInstanceFieldsFromStaticMetadata (isolate, ctorFuncTemplate, prototypeTemplate, instanceMethodsCallbackData, baseInstanceMethodsCallbackData, treeNode);
493- return SetInstanceMethodsFromStaticMetadata (isolate, ctorFuncTemplate, prototypeTemplate, instanceMethodsCallbackData, baseInstanceMethodsCallbackData, treeNode);
549+ return SetInstanceMembersFromRuntimeMetadata (
550+ isolate, protoFiller, instanceMethodsCallbackData,
551+ baseInstanceMethodsCallbackData, treeNode);
494552 }
553+
554+ SetInstanceFieldsFromStaticMetadata (isolate, protoFiller, treeNode);
555+ return SetInstanceMethodsFromStaticMetadata (
556+ isolate, ctorFuncTemplate, protoFiller, instanceMethodsCallbackData,
557+ baseInstanceMethodsCallbackData, treeNode);
495558}
496559
497- vector<MetadataNode::MethodCallbackData *> MetadataNode::SetInstanceMethodsFromStaticMetadata (Isolate *isolate,
498- Local<FunctionTemplate> &ctorFuncTemplate,
499- Local<ObjectTemplate> &prototypeTemplate ,
500- vector<MethodCallbackData *> &instanceMethodsCallbackData,
501- const vector<MethodCallbackData *> &baseInstanceMethodsCallbackData,
502- MetadataTreeNode *treeNode) {
560+ vector<MetadataNode::MethodCallbackData *> MetadataNode::SetInstanceMethodsFromStaticMetadata (
561+ Isolate *isolate, Local<FunctionTemplate> &ctorFuncTemplate,
562+ PrototypeTemplateFiller& protoFiller ,
563+ vector<MethodCallbackData *> &instanceMethodsCallbackData,
564+ const vector<MethodCallbackData *> &baseInstanceMethodsCallbackData,
565+ MetadataTreeNode *treeNode) {
503566 SET_PROFILER_FRAME ();
504567
505568 std::vector<MethodCallbackData *> instanceMethodData;
@@ -520,7 +583,6 @@ vector<MetadataNode::MethodCallbackData *> MetadataNode::SetInstanceMethodsFromS
520583 MethodCallbackData *callbackData = nullptr ;
521584
522585 auto context = isolate->GetCurrentContext ();
523- auto origin = Constants::APP_ROOT_FOLDER_PATH + GetOrCreateInternal (treeNode)->m_name ;
524586
525587 std::unordered_map<std::string, MethodCallbackData *> collectedExtensionMethodDatas;
526588
@@ -535,10 +597,7 @@ vector<MetadataNode::MethodCallbackData *> MetadataNode::SetInstanceMethodsFromS
535597 entry.name );
536598 if (callbackData == nullptr ) {
537599 callbackData = new MethodCallbackData (this );
538- auto funcData = External::New (isolate, callbackData);
539- auto funcTemplate = FunctionTemplate::New (isolate, MethodCallback, funcData);
540- auto funcName = ArgConverter::ConvertToV8String (isolate, entry.name );
541- prototypeTemplate->Set (funcName, funcTemplate);
600+ protoFiller.FillPrototypeMethod (isolate, entry.name , callbackData);
542601
543602 lastMethodName = entry.name ;
544603 std::pair<std::string, MethodCallbackData *> p (entry.name , callbackData);
@@ -581,25 +640,24 @@ vector<MetadataNode::MethodCallbackData *> MetadataNode::SetInstanceMethodsFromS
581640 callbackData->parent = *itFound;
582641 }
583642
584- auto funcData = External::New (isolate, callbackData);
585- auto funcTemplate = FunctionTemplate::New (isolate, MethodCallback, funcData);
586-
587- auto funcName = ArgConverter::ConvertToV8String (isolate, entry.name );
588-
589643 if (s_profilerEnabled) {
644+ Local<External> funcData = External::New (isolate, callbackData);
645+ Local<FunctionTemplate> funcTemplate = FunctionTemplate::New (isolate, MethodCallback, funcData);
590646 auto func = funcTemplate->GetFunction (context).ToLocalChecked ();
647+ std::string origin = Constants::APP_ROOT_FOLDER_PATH + GetOrCreateInternal (treeNode)->m_name ;
591648 Local<Function> wrapperFunc = Wrap (isolate, func, entry.name , origin,
592649 false /* isCtorFunc */ );
593650 Local<Function> ctorFunc = ctorFuncTemplate->GetFunction (context).ToLocalChecked ();
594651 Local<Value> protoVal;
595652 ctorFunc->Get (context,
596653 ArgConverter::ConvertToV8String (isolate, " prototype" )).ToLocal (
597654 &protoVal);
655+ Local<String> funcName = ArgConverter::ConvertToV8String (isolate, entry.name );
598656 if (!protoVal.IsEmpty () && !protoVal->IsUndefined () && !protoVal->IsNull ()) {
599657 protoVal.As <Object>()->Set (context, funcName, wrapperFunc);
600658 }
601659 } else {
602- prototypeTemplate-> Set (funcName, funcTemplate );
660+ protoFiller. FillPrototypeMethod (isolate, entry. name , callbackData );
603661 }
604662
605663 lastMethodName = entry.name ;
@@ -628,7 +686,8 @@ MetadataNode::MethodCallbackData *MetadataNode::tryGetExtensionMethodCallbackDat
628686 return nullptr ;
629687}
630688
631- void MetadataNode::SetInstanceFieldsFromStaticMetadata (Isolate* isolate, Local<FunctionTemplate>& ctorFuncTemplate, Local<ObjectTemplate>& prototypeTemplate, vector<MethodCallbackData*>& instanceMethodsCallbackData, const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode* treeNode) {
689+ void MetadataNode::SetInstanceFieldsFromStaticMetadata (
690+ Isolate* isolate, PrototypeTemplateFiller& prototypeTemplate, MetadataTreeNode* treeNode) {
632691 SET_PROFILER_FRAME ();
633692
634693 Local<Function> ctorFunction;
@@ -665,12 +724,9 @@ void MetadataNode::SetInstanceFieldsFromStaticMetadata(Isolate* isolate, Local<F
665724 curPtr += sizeof (uint16_t );
666725 for (auto i = 0 ; i < instanceFieldCout; i++) {
667726 auto entry = s_metadataReader.ReadInstanceFieldEntry (&curPtr);
668-
669- auto fieldName = ArgConverter::ConvertToV8String (isolate, entry.name );
670727 auto fieldInfo = new FieldCallbackData (entry);
671728 fieldInfo->declaringType = curType;
672- auto fieldData = External::New (isolate, fieldInfo);
673- prototypeTemplate->SetAccessor (fieldName, FieldAccessorGetterCallback, FieldAccessorSetterCallback, fieldData, AccessControl::DEFAULT, PropertyAttribute::DontDelete);
729+ prototypeTemplate.FillPrototypeField (isolate, entry.name , fieldInfo);
674730 }
675731
676732 auto kotlinPropertiesCount = *reinterpret_cast <uint16_t *>(curPtr);
@@ -699,12 +755,15 @@ void MetadataNode::SetInstanceFieldsFromStaticMetadata(Isolate* isolate, Local<F
699755 }
700756
701757 auto propertyInfo = new PropertyCallbackData (propertyName, getterMethodName, setterMethodName);
702- auto propertyData = External::New (isolate, propertyInfo);
703- prototypeTemplate->SetAccessor (ArgConverter::ConvertToV8String (isolate, propertyName), PropertyAccessorGetterCallback, PropertyAccessorSetterCallback, propertyData, AccessControl::DEFAULT, PropertyAttribute::DontDelete);
758+ prototypeTemplate.FillPrototypeProperty (isolate, propertyName, propertyInfo);
704759 }
705760}
706761
707- vector<MetadataNode::MethodCallbackData*> MetadataNode::SetInstanceMembersFromRuntimeMetadata (Isolate* isolate, Local<FunctionTemplate>& ctorFuncTemplate, Local<ObjectTemplate>& prototypeTemplate, vector<MethodCallbackData*>& instanceMethodsCallbackData, const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode* treeNode) {
762+ vector<MetadataNode::MethodCallbackData*> MetadataNode::SetInstanceMembersFromRuntimeMetadata (
763+ Isolate* isolate, PrototypeTemplateFiller& protoFiller,
764+ vector<MethodCallbackData*>& instanceMethodsCallbackData,
765+ const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData,
766+ MetadataTreeNode* treeNode) {
708767 SET_PROFILER_FRAME ();
709768
710769 assert (treeNode->metadata != nullptr );
@@ -757,18 +816,14 @@ vector<MetadataNode::MethodCallbackData*> MetadataNode::SetInstanceMembersFromRu
757816 callbackData->parent = *itFound;
758817 }
759818
760- auto funcData = External::New (isolate, callbackData);
761- auto funcTemplate = FunctionTemplate::New (isolate, MethodCallback, funcData);
762- auto funcName = ArgConverter::ConvertToV8String (isolate, entry.name );
763- prototypeTemplate->Set (funcName, funcTemplate);
819+ protoFiller.FillPrototypeMethod (isolate, entry.name , callbackData);
764820 lastMethodName = entry.name ;
765821 }
766822 callbackData->candidates .push_back (entry);
767823 } else if (chKind == ' F' ) {
768- auto fieldName = ArgConverter::ConvertToV8String (isolate, entry.name );
769- auto fieldData = External::New (isolate, new FieldCallbackData (entry));
824+ auto * fieldInfo = new FieldCallbackData (entry);
770825 auto access = entry.isFinal ? AccessControl::ALL_CAN_READ : AccessControl::DEFAULT;
771- prototypeTemplate-> SetAccessor (fieldName, FieldAccessorGetterCallback, FieldAccessorSetterCallback, fieldData, access, PropertyAttribute::DontDelete );
826+ protoFiller. FillPrototypeField (isolate, entry. name , fieldInfo, access);
772827 }
773828 }
774829 return instanceMethodData;
@@ -974,11 +1029,13 @@ Local<FunctionTemplate> MetadataNode::GetConstructorFunctionTemplate(Isolate* is
9741029 break ;
9751030 }
9761031
977- auto prototypeTemplate = ctorFuncTemplate->PrototypeTemplate ();
1032+ PrototypeTemplateFiller protoFiller{ ctorFuncTemplate->PrototypeTemplate ()} ;
9781033
979- auto instanceMethodData = node->SetInstanceMembers (isolate, ctorFuncTemplate, prototypeTemplate, instanceMethodsCallbackData, baseInstanceMethodsCallbackData, treeNode);
1034+ auto instanceMethodData = node->SetInstanceMembers (
1035+ isolate, ctorFuncTemplate, protoFiller, instanceMethodsCallbackData,
1036+ baseInstanceMethodsCallbackData, treeNode);
9801037 if (!skippedBaseTypes.empty ()) {
981- node->SetMissingBaseMethods (isolate, skippedBaseTypes, instanceMethodData, prototypeTemplate );
1038+ node->SetMissingBaseMethods (isolate, skippedBaseTypes, instanceMethodData, protoFiller );
9821039 }
9831040
9841041 auto context = isolate->GetCurrentContext ();
@@ -2075,7 +2132,10 @@ bool MetadataNode::CheckClassHierarchy(JEnv& env, jclass currentClass, MetadataT
20752132 * This method handles scenrios like Bundle/BaseBundle class hierarchy change in API level 21.
20762133 * See https://github.com/NativeScript/android-runtime/issues/628
20772134 */
2078- void MetadataNode::SetMissingBaseMethods (Isolate* isolate, const vector<MetadataTreeNode*>& skippedBaseTypes, const vector<MethodCallbackData*>& instanceMethodData, Local<ObjectTemplate>& prototypeTemplate) {
2135+ void MetadataNode::SetMissingBaseMethods (
2136+ Isolate* isolate, const vector<MetadataTreeNode*>& skippedBaseTypes,
2137+ const vector<MethodCallbackData*>& instanceMethodData,
2138+ PrototypeTemplateFiller& protoFiller) {
20792139 for (auto treeNode: skippedBaseTypes) {
20802140 uint8_t * curPtr = s_metadataReader.GetValueData () + treeNode->offsetValue + 1 ;
20812141
@@ -2111,11 +2171,7 @@ void MetadataNode::SetMissingBaseMethods(Isolate* isolate, const vector<Metadata
21112171
21122172 if (callbackData == nullptr ) {
21132173 callbackData = new MethodCallbackData (this );
2114-
2115- auto funcData = External::New (isolate, callbackData);
2116- auto funcTemplate = FunctionTemplate::New (isolate, MethodCallback, funcData);
2117- auto funcName = ArgConverter::ConvertToV8String (isolate, entry.name );
2118- prototypeTemplate->Set (funcName, funcTemplate);
2174+ protoFiller.FillPrototypeMethod (isolate, entry.name , callbackData);
21192175 }
21202176
21212177 bool foundSameSig = false ;
0 commit comments