| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- //
- // Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- #include <Atomic/IO/FileSystem.h>
- #include "../JSBind.h"
- #include "../JSBModule.h"
- #include "../JSBPackage.h"
- #include "../JSBEnum.h"
- #include "../JSBClass.h"
- #include "../JSBFunction.h"
- #include "JSClassWriter.h"
- #include "JSFunctionWriter.h"
- namespace ToolCore
- {
- JSClassWriter::JSClassWriter(JSBClass *klass) : JSBClassWriter(klass)
- {
- }
- void JSClassWriter::WriteFunctions(String& source)
- {
- for (unsigned i = 0; i < klass_->functions_.Size(); i++)
- {
- JSBFunction* function = klass_->functions_.At(i);
- if (function->Skip(BINDINGLANGUAGE_JAVASCRIPT) || OmitFunction(function))
- continue;
- if (function->IsDestructor())
- continue;
- JSFunctionWriter writer(function);
- writer.GenerateSource(source);
- }
- }
- void JSClassWriter::GenerateSource(String& sourceOut)
- {
- String source = "";
- if (klass_->IsNumberArray())
- return;
- WriteFunctions(source);
- String packageName = klass_->GetModule()->GetPackage()->GetName();
- source.AppendWithFormat("static void jsb_class_define_%s(JSVM* vm)\n{\n", klass_->GetName().CString());
- source.Append("duk_context* ctx = vm->GetJSContext();\n");
- GenerateStaticFunctionsSource(source, packageName);
- GenerateNonStaticFunctionsSource(source, packageName);
- source.Append("}\n");
- sourceOut += source;
- }
- void JSClassWriter::GenerateStaticFunctionsSource(String& source, String& packageName)
- {
- // Store function on both the constructor and prototype
- // so can access static functions from both the class constructor and an instance
- source.AppendWithFormat("js_class_get_constructor(ctx, \"%s\", \"%s\");\n", packageName.CString(), klass_->GetName().CString());
- source.AppendWithFormat("js_class_get_prototype(ctx, \"%s\", \"%s\");\n", packageName.CString(), klass_->GetName().CString());
- for (unsigned i = 0; i < klass_->functions_.Size(); i++)
- {
- JSBFunction* function = klass_->functions_.At(i);
- if (function->Skip(BINDINGLANGUAGE_JAVASCRIPT) || OmitFunction(function))
- continue;
- if (function->IsConstructor() || function->IsDestructor())
- continue;
- if (!function->IsStatic())
- continue;
- if (function->FirstDefaultParameter() != -1)
- {
- source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, DUK_VARARGS);\n", klass_->GetName().CString(), function->GetName().CString());
- }
- else
- {
- source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, %i);\n", klass_->GetName().CString(), function->GetName().CString(), (int)function->GetParameters().Size());
- }
- String scriptName = function->GetName();
- scriptName[0] = tolower(scriptName[0]);
- source.Append("duk_dup(ctx, -1);\n");
- source.AppendWithFormat("duk_put_prop_string(ctx, -3, \"%s\");\n", scriptName.CString());
- source.AppendWithFormat("duk_put_prop_string(ctx, -3, \"%s\");\n", scriptName.CString());
- }
- source.Append("duk_pop_2(ctx);\n");
- }
- void JSClassWriter::GenerateNonStaticFunctionsSource(String& source, String& packageName)
- {
- source.AppendWithFormat("js_class_get_prototype(ctx, \"%s\", \"%s\");\n", packageName.CString(), klass_->GetName().CString());
- for (unsigned i = 0; i < klass_->functions_.Size(); i++)
- {
- JSBFunction* function = klass_->functions_.At(i);
- if (function->Skip(BINDINGLANGUAGE_JAVASCRIPT) || OmitFunction(function))
- continue;
- if (function->IsConstructor() || function->IsDestructor())
- continue;
- if (function->IsStatic())
- continue;
- if (function->FirstDefaultParameter() != -1)
- {
- source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, DUK_VARARGS);\n", klass_->GetName().CString(), function->GetName().CString());
- }
- else
- {
- source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, %i);\n", klass_->GetName().CString(), function->GetName().CString(), (int)function->GetParameters().Size());
- }
- String scriptName = function->GetName();
- scriptName[0] = tolower(scriptName[0]);
- source.AppendWithFormat("duk_put_prop_string(ctx, -2, \"%s\");\n", scriptName.CString());
- }
- source.Append("duk_pop(ctx);\n");
- }
- bool JSClassWriter::OmitFunction(JSBFunction* function)
- {
- if (function->GetSkipLanguage(BINDINGLANGUAGE_JAVASCRIPT))
- return true;
- Vector<JSBFunctionType*>& parameters = function->GetParameters();
- if (function->GetReturnType() && function->GetReturnType()->type_->asVectorType())
- {
- if (!function->GetReturnType()->isConst_ || function->GetReturnType()->type_->asVectorType()->isPODVector_)
- {
- function->SetSkipLanguage(BINDINGLANGUAGE_JAVASCRIPT);
- return true;
- }
- }
- for (unsigned i = 0; i < parameters.Size(); i++)
- {
- JSBFunctionType* ptype = parameters[i];
- if (ptype->type_->asVectorType())
- {
- if (!ptype->isConst_ || ptype->type_->asVectorType()->isPODVector_)
- {
- function->SetSkipLanguage(BINDINGLANGUAGE_JAVASCRIPT);
- return true;
- }
- }
- }
- return false;
- }
- }
|