Browse Source

Generating docs

Josh Engebretson 10 years ago
parent
commit
91a70d0e6c

+ 2 - 2
.gitignore

@@ -1,8 +1,8 @@
 
 *.user
 *.log
-Bin/Atomic.d.ts
-Bin/Atomic.js
+Bin/*.d.ts
+Bin/*.js
 Bin/*.pak
 Bin/NativePluginSDK/*
 Source/Atomic/Javascript/Modules/*

+ 1 - 0
Source/ToolCore/JSBind/JSBClass.h

@@ -63,6 +63,7 @@ public:
     const String& GetNativeName() { return nativeName_; }
     JSBClass* GetBaseClass();
     PODVector<JSBClass*>& GetBaseClasses() {return baseClasses_; }
+    PODVector<JSBFunction*>& GetFunctions() { return functions_; }
 
     bool IsAbstract() { return isAbstract_; }
 

+ 307 - 0
Source/ToolCore/JSBind/JSBDoc.cpp

@@ -0,0 +1,307 @@
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// Please see LICENSE.md in repository root for license information
+// https://github.com/AtomicGameEngine/AtomicGameEngine
+
+#include <Atomic/Atomic.h>
+#include <Atomic/IO/Log.h>
+#include <Atomic/Core/ProcessUtils.h>
+#include <Atomic/Resource/ResourceCache.h>
+
+#include "JSBind.h"
+#include "JSBPackage.h"
+#include "JSBModule.h"
+#include "JSBFunction.h"
+#include "JSBDoc.h"
+
+namespace ToolCore
+{
+
+static String GetScriptType(JSBFunctionType* ftype)
+{
+    String scriptType = "number";
+
+    if (ftype->type_->asPrimitiveType())
+    {
+        JSBPrimitiveType* ptype = ftype->type_->asPrimitiveType();
+        if (ptype->kind_ == JSBPrimitiveType::Bool)
+            scriptType = "boolean";
+
+    }
+
+    if (ftype->type_->asStringHashType() || ftype->type_->asStringType())
+        scriptType = "string";
+
+    if (ftype->type_->asEnumType())
+        scriptType = "Atomic." + ftype->type_->asEnumType()->enum_->GetName();
+
+    if (ftype->type_->asEnumType())
+        scriptType = "Atomic." + ftype->type_->asEnumType()->enum_->GetName();
+
+    if (ftype->type_->asClassType())
+        scriptType = "Atomic." + ftype->type_->asClassType()->class_->GetName();
+
+    return scriptType;
+
+}
+
+void JSBDoc::Begin()
+{
+    source_ += "//Atomic JSDoc Definitions\n\n\n";
+
+    source_ += "/**\n * Atomic Game Engine\n * @namespace\n*/\n var Atomic = {}\n\n";
+}
+
+void JSBDoc::End()
+{
+}
+
+String JSBDoc::GenFunctionDoc(JSBFunction* function)
+{
+    if (function->Skip())
+        return "";
+
+    String params;
+
+    Vector<JSBFunctionType*>& parameters = function->GetParameters();
+
+    for (unsigned i = 0; i < parameters.Size(); i++)
+    {
+        JSBFunctionType* ftype = parameters.At(i);
+
+        String scriptType = GetScriptType(ftype);
+
+        if (scriptType == "Atomic.Context")
+            continue;
+
+        // mark as optional
+        if (ftype->initializer_.Length())
+            scriptType += "=";
+
+        params += " * @param {" + scriptType + "} " +  ftype->name_ + "\n";
+    }
+
+    String returns;
+
+    if (function->GetReturnType())
+        returns = " * @returns { " +  GetScriptType(function->GetReturnType()) +  "}\n";
+
+    String docString;
+
+    if (function->IsConstructor())
+    {
+        docString.AppendWithFormat("%s", params.CString());
+
+    }
+    else
+    {
+        docString.AppendWithFormat(" * %s\n * @memberof Atomic.%s.prototype\n%s%s\n",
+                                   function->GetDocString().CString(),
+                                   function->GetClass()->GetName().CString(),
+                                   params.CString(),
+                                   returns.CString());
+
+    }
+
+    return docString;
+}
+
+void JSBDoc::ExportModuleClasses(JSBModule* module)
+{
+    Vector<SharedPtr<JSBClass>> classes = module->GetClasses();
+
+    if (!classes.Size())
+        return;
+
+    source_ += "\n";
+
+    for (unsigned i = 0; i < classes.Size(); i++)
+    {
+        JSBClass* klass = classes.At(i);
+
+        source_ += "/**\n * @class\n* @memberof Atomic\n";
+
+        if (klass->GetBaseClass())
+            source_ += " * @augments Atomic." + klass->GetBaseClass()->GetName()+ "\n";
+
+        // PROPERTIES
+        Vector<String> propertyNames;
+
+        klass->GetPropertyNames(propertyNames);
+
+        for (unsigned j = 0; j < propertyNames.Size(); j++)
+        {
+
+            JSBProperty* prop = klass->GetProperty(propertyNames[j]);
+
+            JSBFunctionType* ftype = NULL;
+
+            String desc;
+
+            if (prop->getter_ && !prop->getter_->Skip())
+            {
+                desc = prop->getter_->GetDocString();
+                ftype = prop->getter_->GetReturnType();
+            }
+            else if (prop->setter_ && !prop->setter_->Skip())
+            {
+                ftype = prop->setter_->GetParameters()[0];
+            }
+
+            if (prop->setter_ && prop->setter_->GetDocString().Length())
+            {
+                // overwrite getter docstring if it exsists
+                desc = prop->setter_->GetDocString();
+
+            }
+
+
+            if (!ftype)
+                continue;
+
+            String scriptType = GetScriptType(ftype);
+
+            String scriptName =  propertyNames[j];
+            scriptName[0] = tolower(scriptName[0]);
+
+            if (desc.Length())
+            {
+                source_ += " * @property {" +  scriptType + "} " + scriptName + " - " + desc + "\n";
+            }
+            else
+            {
+                source_ += " * @property {" +  scriptType + "} " + scriptName + "\n";
+            }
+
+        }
+
+        JSBFunction* constructor = klass->GetConstructor();
+        if (constructor)
+        {
+            String docs = GenFunctionDoc(constructor);
+            source_ += docs;
+        }
+
+        source_ += "*/ \nfunction " + klass->GetName() + "() {};\n\n";
+
+        // FUNCTIONS
+
+        PODVector<JSBFunction*>& functions = klass->GetFunctions();
+
+        for (unsigned j = 0; j < functions.Size(); j++)
+        {
+            JSBFunction* func = functions[j];
+
+            if (func->IsConstructor() || func->IsDestructor() || func->Skip())
+                continue;
+
+            String docs = GenFunctionDoc(func);
+
+            String scriptName =  func->GetName();
+            scriptName[0] = tolower(scriptName[0]);
+
+            if (scriptName == "delete")
+                scriptName = "__delete";
+
+            String docString;
+            docString.AppendWithFormat("/**\n %s */\n function %s() {};\n\n",
+                                       docs.CString(),
+                                       scriptName.CString());
+
+            source_ += docString;
+
+        }
+
+    }
+
+}
+
+void JSBDoc::ExportModuleConstants(JSBModule* module)
+{
+
+    Vector<String>& constants = module->GetConstants();
+
+    if (!constants.Size())
+        return;
+
+    source_ += "\n";
+    for (unsigned i = 0; i < constants.Size(); i++)
+    {
+        const String& cname = constants.At(i);
+
+        source_ += "/**\n * @memberof Atomic\n * @type {number}\n */\nvar " + cname + ";\n";
+    }
+
+    source_ += "\n";
+
+}
+
+void JSBDoc::ExportModuleEnums(JSBModule* module)
+{
+    Vector<SharedPtr<JSBEnum>> enums = module->GetEnums();
+
+    for (unsigned i = 0; i < enums.Size(); i++)
+    {
+        JSBEnum* _enum = enums.At(i);
+
+        source_ += "/**\n * @memberof Atomic\n * @readonly\n * @enum {number}\n */\n";
+
+        source_ += " var " + _enum->GetName() + " =  {\n";
+
+        Vector<String>& values = _enum->GetValues();
+
+        for (unsigned j = 0; j < values.Size(); j++)
+        {
+            source_ += "    " + values[j] + " : undefined";
+
+            if (j !=  values.Size() - 1)
+                source_ += ",\n";
+        }
+
+        source_ += "\n\n};\n\n";
+
+    }
+
+}
+void JSBDoc::WriteToFile(const String &path)
+{
+    File file(package_->GetContext());
+    file.Open(path, FILE_WRITE);
+
+    file.Write(source_.CString(), source_.Length());
+
+    file.Close();
+
+}
+
+void JSBDoc::Emit(JSBPackage* package, const String& path)
+{
+    package_ = package;
+
+    Vector<SharedPtr<JSBModule>>& modules = package->GetModules();
+    Begin();
+
+    for (unsigned i = 0; i < modules.Size(); i++)
+    {
+        ExportModuleEnums(modules[i]);
+    }
+
+    for (unsigned i = 0; i < modules.Size(); i++)
+    {
+        ExportModuleConstants(modules[i]);
+    }
+
+    for (unsigned i = 0; i < modules.Size(); i++)
+    {
+        source_ += "\n//----------------------------------------------------\n";
+        source_ += "// MODULE: " + modules[i]->GetName() + "\n";
+        source_ += "//----------------------------------------------------\n\n";
+        ExportModuleClasses(modules[i]);
+    }
+
+
+    End();
+    WriteToFile(path);
+
+}
+
+}

+ 44 - 0
Source/ToolCore/JSBind/JSBDoc.h

@@ -0,0 +1,44 @@
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// Please see LICENSE.md in repository root for license information
+// https://github.com/AtomicGameEngine/AtomicGameEngine
+
+#pragma once
+
+#include <Atomic/Container/Str.h>
+
+using namespace Atomic;
+
+namespace ToolCore
+{
+
+class JSBFunction;
+class JSBPackage;
+class JSBModule;
+
+class JSBDoc
+{
+
+public:
+
+    void Emit(JSBPackage* package, const String& path);
+
+private:
+
+    void Begin();
+
+    void End();
+
+    String GenFunctionDoc(JSBFunction* function);
+
+    void ExportModuleEnums(JSBModule* module);
+    void ExportModuleConstants(JSBModule* module);
+    void ExportModuleClasses(JSBModule* module);
+
+    void WriteToFile(const String& path);
+
+    String source_;
+    JSBPackage* package_;
+
+};
+
+}

+ 1 - 1
Source/ToolCore/JSBind/JSBFunction.h

@@ -96,8 +96,8 @@ public:
     bool IsOverride() { return isOverride_; }
     bool Skip() { return skip_; }
 
+    JSBClass* GetClass() { return class_; }
     const String& GetPropertyName() { return propertyName_; }
-
     JSBFunctionType* GetReturnType() { return returnType_; }
     Vector<JSBFunctionType*>& GetParameters() { return parameters_; }
 

+ 10 - 0
Source/ToolCore/JSBind/JSBModule.cpp

@@ -27,6 +27,16 @@ JSBModule::~JSBModule()
 
 }
 
+Vector<SharedPtr<JSBClass>> JSBModule::GetClasses()
+{
+    return classes_.Values();
+}
+
+Vector<SharedPtr<JSBEnum>> JSBModule::GetEnums()
+{
+    return enums_.Values();
+}
+
 void JSBModule::PreprocessHeaders()
 {
     for (unsigned i = 0; i < headers_.Size(); i++)

+ 3 - 0
Source/ToolCore/JSBind/JSBModule.h

@@ -33,6 +33,9 @@ public:
     JSBPackage* GetPackage() { return package_; }
 
     JSBClass* GetClass(const String& name);
+    Vector<SharedPtr<JSBClass>> GetClasses();
+    Vector<SharedPtr<JSBEnum>> GetEnums();
+    Vector<String>& GetConstants() { return constants_; }
 
     void RegisterClass(String name);
 

+ 10 - 0
Source/ToolCore/JSBind/JSBPackage.cpp

@@ -8,6 +8,8 @@
 #include "JSBPackage.h"
 
 #include "JSBPackageWriter.h"
+#include "JSBDoc.h"
+#include "JSBTypeScript.h"
 
 namespace ToolCore
 {
@@ -72,6 +74,14 @@ void JSBPackage::GenerateSource(const String &outPath)
     {
         modules_[i]->GenerateSource(outPath);
     }
+
+    JSBind* jsbind = GetSubsystem<JSBind>();
+
+    JSBDoc jdoc;
+    jdoc.Emit(this, jsbind->GetSourceRootFolder() + "Bin/" + name_ + ".js");
+
+    JSBTypeScript ts;
+    ts.Emit(this, jsbind->GetSourceRootFolder() + "Bin/" + name_ + ".d.ts");
 }
 
 JSBClass* JSBPackage::GetClass(const String& name)

+ 2 - 0
Source/ToolCore/JSBind/JSBPackage.h

@@ -26,6 +26,8 @@ public:
 
     bool Load(const String& packageFolder);
 
+    Vector<SharedPtr<JSBModule>>& GetModules() {return modules_;}
+
     void PreprocessModules();
 
     void ProcessModules();

+ 292 - 0
Source/ToolCore/JSBind/JSBTypeScript.cpp

@@ -0,0 +1,292 @@
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// Please see LICENSE.md in repository root for license information
+// https://github.com/AtomicGameEngine/AtomicGameEngine
+
+#include <Atomic/Atomic.h>
+#include <Atomic/IO/Log.h>
+#include <Atomic/Core/ProcessUtils.h>
+#include <Atomic/Resource/ResourceCache.h>
+
+#include "JSBind.h"
+#include "JSBPackage.h"
+#include "JSBModule.h"
+#include "JSBFunction.h"
+#include "JSBTypeScript.h"
+
+namespace ToolCore
+{
+
+static String GetScriptType(JSBFunctionType* ftype)
+{
+    String scriptType = "number";
+
+    if (ftype->type_->asPrimitiveType())
+    {
+        JSBPrimitiveType* ptype = ftype->type_->asPrimitiveType();
+        if (ptype->kind_ == JSBPrimitiveType::Bool)
+            scriptType = "boolean";
+
+    }
+
+    if (ftype->type_->asStringHashType() || ftype->type_->asStringType())
+        scriptType = "string";
+
+    if (ftype->type_->asEnumType())
+        scriptType = ftype->type_->asEnumType()->enum_->GetName();
+
+    if (ftype->type_->asEnumType())
+        scriptType = ftype->type_->asEnumType()->enum_->GetName();
+
+    if (ftype->type_->asClassType())
+        scriptType = ftype->type_->asClassType()->class_->GetName();
+
+    return scriptType;
+
+}
+
+void JSBTypeScript::Begin()
+{
+    source_ += "//Atomic TypeScript Definitions\n\n\n";
+    source_ += "declare module Atomic {\n\n";
+}
+
+void JSBTypeScript::End()
+{
+    source_ += "\n}\n";
+}
+
+void JSBTypeScript::ExportFunction(JSBFunction* function)
+{
+    if (function->Skip())
+        return;
+
+    String scriptName = "constructor";
+
+    //constructor(width?: number, height?: number, options?: PixiRendererOptions);
+
+    if (!function->IsConstructor())
+    {
+        scriptName =  function->GetName();
+        scriptName[0] = tolower(scriptName[0]);
+    }
+
+    if (function->GetDocString().Length())
+        source_ += "      //" + function->GetDocString() + "\n";
+
+    source_ += "      " + scriptName + "(";
+
+    Vector<JSBFunctionType*>& parameters = function->GetParameters();
+
+    for (unsigned i = 0; i < parameters.Size(); i++)
+    {
+        JSBFunctionType* ftype = parameters.At(i);
+
+        String scriptType = GetScriptType(ftype);
+
+        if (scriptType == "Context")
+            continue;
+
+        source_ += ftype->name_;
+
+        if (ftype->initializer_.Length())
+            source_ += "?";
+
+        source_ += ": " + scriptType;
+
+        if (i < parameters.Size() - 1)
+            source_ += ", ";
+    }
+
+    if (function->IsConstructor())
+        source_ += ");\n";
+    else
+    {
+        if (!function->GetReturnType())
+            source_ += "): void;\n";
+        else
+            source_ += "): " + GetScriptType(function->GetReturnType()) + ";\n";
+
+    }
+
+
+
+}
+
+void JSBTypeScript::ExportModuleClasses(JSBModule* module)
+{
+    Vector<SharedPtr<JSBClass>> classes = module->GetClasses();
+
+    if (!classes.Size())
+        return;
+
+    source_ += "\n";
+
+    for (unsigned i = 0; i < classes.Size(); i++)
+    {
+        JSBClass* klass = classes.At(i);
+
+        source_ += "   export class " + klass->GetName();
+        if (klass->GetBaseClass())
+            source_ += " extends " + klass->GetBaseClass()->GetName();
+
+        source_ += " {\n\n";
+
+        Vector<String> propertyNames;
+
+        klass->GetPropertyNames(propertyNames);
+
+        for (unsigned j = 0; j < propertyNames.Size(); j++)
+        {
+
+            JSBProperty* prop = klass->GetProperty(propertyNames[j]);
+
+            JSBFunctionType* ftype = NULL;
+
+            if (prop->getter_ && !prop->getter_->Skip())
+            {
+                ftype = prop->getter_->GetReturnType();
+            }
+            else if (prop->setter_ && !prop->setter_->Skip())
+                ftype = prop->setter_->GetParameters()[0];
+
+            if (!ftype)
+                continue;
+
+            String scriptType = GetScriptType(ftype);
+
+            String scriptName =  propertyNames[j];
+            scriptName[0] = tolower(scriptName[0]);
+
+            source_ += "      " + scriptName + ": " + scriptType + ";\n";
+
+        }
+
+        if (propertyNames.Size())
+            source_ += "\n";
+
+        JSBFunction* constructor = klass->GetConstructor();
+        if (constructor)
+        {
+            ExportFunction(constructor);
+            source_ += "\n";
+        }
+
+        PODVector<JSBFunction*>& functions = klass->GetFunctions();
+
+        for (unsigned j = 0; j < functions.Size(); j++)
+        {
+
+            JSBFunction* func = functions[j];
+
+            if (func->IsConstructor() || func->IsDestructor() || func->Skip())
+                continue;
+
+            ExportFunction(func);
+
+
+        }
+
+
+
+        source_ += "\n   }\n\n";
+
+    }
+
+    source_ += "\n";
+
+}
+
+
+void JSBTypeScript::ExportModuleConstants(JSBModule* module)
+{
+    Vector<String>& constants = module->GetConstants();
+
+    if (!constants.Size())
+        return;
+
+    source_ += "\n";
+
+    for (unsigned i = 0; i < constants.Size(); i++)
+    {
+        const String& cname = constants.At(i);
+
+        source_ += "   export var " + cname + ": number;\n";
+    }
+
+    source_ += "\n";
+
+}
+
+void JSBTypeScript::ExportModuleEnums(JSBModule* module)
+{
+
+    Vector<SharedPtr<JSBEnum>> enums = module->GetEnums();
+
+    for (unsigned i = 0; i <enums.Size(); i++)
+    {
+        JSBEnum* _enum =enums[i];
+
+        source_ += "   export enum " + _enum->GetName();
+        source_ += " {\n\n";
+
+        Vector<String>& values = _enum->GetValues();
+
+        for (unsigned j = 0; j < values.Size(); j++)
+        {
+            source_ += "      " + values[j];
+            if (j !=  values.Size() - 1)
+                source_ += ",\n";
+        }
+
+        source_ += "\n\n   }\n\n";
+
+
+
+    }
+
+}
+
+void JSBTypeScript::WriteToFile(const String &path)
+{
+    File file(package_->GetContext());
+    file.Open(path, FILE_WRITE);
+
+    file.Write(source_.CString(), source_.Length());
+
+    file.Close();
+
+}
+
+void JSBTypeScript::Emit(JSBPackage* package, const String& path)
+{
+    package_ = package;
+
+    Vector<SharedPtr<JSBModule>>& modules = package->GetModules();
+
+    Begin();
+
+    for (unsigned i = 0; i < modules.Size(); i++)
+    {
+        ExportModuleEnums(modules[i]);
+    }
+
+    for (unsigned i = 0; i < modules.Size(); i++)
+    {
+        ExportModuleConstants(modules[i]);
+    }
+
+    for (unsigned i = 0; i < modules.Size(); i++)
+    {
+        source_ += "\n//----------------------------------------------------\n";
+        source_ += "// MODULE: " + modules[i]->GetName() + "\n";
+        source_ += "//----------------------------------------------------\n\n";
+        ExportModuleClasses(modules[i]);
+    }
+
+
+    End();
+    WriteToFile(path);
+
+}
+
+}

+ 45 - 0
Source/ToolCore/JSBind/JSBTypeScript.h

@@ -0,0 +1,45 @@
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// Please see LICENSE.md in repository root for license information
+// https://github.com/AtomicGameEngine/AtomicGameEngine
+
+#pragma once
+
+#include <Atomic/Container/Str.h>
+
+using namespace Atomic;
+
+class JSBFunction;
+class JSBPackage;
+class JSBModule;
+
+namespace ToolCore
+{
+
+class JSBTypeScript
+{
+public:
+
+    void Emit(JSBPackage* package, const String& path);
+
+private:
+
+    String source_;
+
+    void Begin();
+
+    void End();
+
+    void ExportFunction(JSBFunction* function);
+
+    void ExportModuleEnums(JSBModule* moduleName);
+    void ExportModuleConstants(JSBModule*  moduleName);
+    void ExportModuleClasses(JSBModule*  moduleName);
+
+    void WriteToFile(const String& path);
+
+    JSBPackage* package_;
+
+
+};
+
+}