Exemplo n.º 1
0
        private void GenerateWrapperClassConstructors(NodeJSTypeReference classToWrapTypeReference)
        {
            Class classToWrap = classToWrapTypeReference.Declaration as Class;

            string classNameWrap          = NamingHelper.GenerateClassWrapName(classToWrap.Name);
            string classNameWrapperMember = NamingHelper.GenerateClassWrapperMember(classToWrap.Name);

            IEnumerable <Method> constructors = classToWrap.Constructors.OrderByDescending(s => s.Parameters.Count);

            // Supported implementations comment
            PushBlock(BlockKind.Method);
            WriteLine("// Supported implementations");
            foreach (Method constructor in constructors.OrderBy(s => s.Parameters.Count))
            {
                WriteLine("// {0}({1})", classToWrap.Name, nodeJSTypePrinter.VisitParameters(constructor.Parameters, true));
            }

            // Constructor for wrapped class
            WriteLine("{0}::{0}(Nan::NAN_METHOD_ARGS_TYPE info)", classNameWrap);
            WriteLine("  : {0}(NULL)", classNameWrapperMember);
            WriteStartBraceIndent();

            bool firstConstructorCreated = false;

            // Generate check for constructor arguments
            WriteLine("// Check constructor arguments");
            foreach (Method constructor in constructors.OrderBy(s => s.Parameters.Count))
            {
                // Generate other constructors than default
                string generatedCheckStatement = (firstConstructorCreated ? "else " : string.Empty);
                generatedCheckStatement += "if " + nodeJSTypeCheckPrinter.GenerateCheckStatement(constructor.Parameters);

                // Output arguments checker
                WriteLine(generatedCheckStatement);
                WriteStartBraceIndent();

                // Generate wrapper for parameter arguments
                string generatedArgumentsWrapped = nodeJSTypePrinter.GenerateParameterWrapper(this, constructor.Parameters);

                // Generate construction of wrapped member
                PushBlock(BlockKind.MethodBody);
                WriteLine("// {0}({1})", classToWrap.Name, nodeJSTypePrinter.VisitParameters(constructor.Parameters, true));
                WriteLine("{0} = new {1}({2});", classNameWrapperMember, classToWrap.Name, generatedArgumentsWrapped);
                PopBlock(NewLineKind.Never);
                WriteCloseBraceIndent();

                // Remember that we have created an constructor
                firstConstructorCreated = true;
            }

            WriteCloseBraceIndent();
            PopBlock(NewLineKind.BeforeNextBlock);
        }
Exemplo n.º 2
0
        private void GenerateWrapperClassDestructors(NodeJSTypeReference classToWrapTypeReference)
        {
            Class  classToWrap            = classToWrapTypeReference.Declaration as Class;
            string classNameWrap          = NamingHelper.GenerateClassWrapName(classToWrap.Name);
            string classNameWrapperMember = NamingHelper.GenerateClassWrapperMember(classToWrap.Name);

            // Destructor for wrapped class
            PushBlock(BlockKind.Method);
            WriteLine("{0}::~{0}()", classNameWrap);
            WriteStartBraceIndent();
            WriteLine("delete {0};", classNameWrapperMember);
            WriteCloseBraceIndent();
            PopBlock(NewLineKind.BeforeNextBlock);
        }
Exemplo n.º 3
0
        public void GenerateWrapperClass()
        {
            NodeJSTypeReferenceCollector typeReferenceCollector = new NodeJSTypeReferenceCollector(Context.ConfigurationContext, Context.TypeMaps, Context.Options);

            typeReferenceCollector.Process(TranslationUnit);

            List <Function> functions = typeReferenceCollector.TypeReferences
                                        .Where(item => ((item.Declaration is Function) && !(item.Declaration is Method)))
                                        .Select(item => item.Declaration as Function).ToList();

            NodeJSTypeReference classToWrapTypeReference = typeReferenceCollector.TypeReferences
                                                           .Where(item => item.Declaration is Class)
                                                           .Where(item => NamingHelper.GenerateTrimmedClassName(TranslationUnit.FileNameWithoutExtension).ToLower().Equals(NamingHelper.GenerateTrimmedClassName(item.Declaration.Name).ToLower()))
                                                           .FirstOrDefault();

            string className              = string.Empty;
            string classNameWrap          = string.Empty;
            string classNameWrapperMember = string.Empty;

            // Generate wrapper class name
            if (classToWrapTypeReference != null)
            {
                className = (classToWrapTypeReference.Declaration as Class).Name;

                // Generate wrapper and member names
                classNameWrap          = NamingHelper.GenerateClassWrapName(className);
                classNameWrapperMember = NamingHelper.GenerateClassWrapperMember(className);
            }
            else
            {
                TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
                classNameWrap = textInfo.ToTitleCase(TranslationUnit.FileNameWithoutExtension) + "Wrap";
            }

            // Generate class stub
            PushBlock(BlockKind.Class);
            WriteLine("class {0} : public node::ObjectWrap", classNameWrap);
            WriteLine("{");
            WriteLine("public:");
            PushIndent();

            // Write
            WriteLine("static NAN_MODULE_INIT(Initialize);");

            // Check if we have an class to warp
            if (!string.IsNullOrEmpty(className))
            {
                // Generate prototype templates
                WriteLine("static Nan::Persistent<v8::FunctionTemplate> prototype;");
                WriteLine("");

                // Create get wrapped method
                PushBlock(BlockKind.Method);
                WriteLine("{0}* GetWrapped() const", className);
                WriteStartBraceIndent();
                WriteLine("return {0};", classNameWrapperMember);
                PopIndent();
                WriteLine("};");
                PopBlock(NewLineKind.BeforeNextBlock);

                // Create get wrapped method
                PushBlock(BlockKind.Method);
                WriteLine("void SetWrapped({0}* {1})", className, NamingHelper.ConvertToParameterName(className));
                WriteStartBraceIndent();
                WriteLine("{0} = {1};", classNameWrapperMember, NamingHelper.ConvertToParameterName(className));
                PopIndent();
                WriteLine("};");
                PopBlock(NewLineKind.BeforeNextBlock);

                // New instance prototype
                PushBlock(BlockKind.MethodBody);
                WriteLine("static v8::Handle<v8::Value> NewInstance({0}* {1});", className, NamingHelper.ConvertToParameterName(className));
                PopBlock(NewLineKind.Always);
            }
            else
            {
                // Only add empty line when we have static functions
                if (functions.Count > 0)
                {
                    WriteLine("");
                }
            }

            // Check if we have an class to warp
            if (!string.IsNullOrEmpty(className))
            {
                // Private members prototypes
                PopIndent();
                WriteLine("private:");
                PushIndent();

                // Constructor & destructor of wrapper class
                PushBlock(BlockKind.MethodBody);
                WriteLine("static Nan::Persistent<v8::Function> constructor;");
                WriteLine("{0}(Nan::NAN_METHOD_ARGS_TYPE info);", classNameWrap);
                WriteLine("~{0}();", classNameWrap);
                WriteLine("static NAN_METHOD(New);");
                PopBlock(NewLineKind.Always);

                // Check if methods available
                if ((classToWrapTypeReference.Declaration as Class).Methods.Count > 0)
                {
                    // Methods
                    PushBlock(BlockKind.MethodBody);
                    WriteLine("// Wrapped methods");
                    SortedSet <string> methodsProcessed = new SortedSet <string>(StringComparer.InvariantCulture);
                    foreach (Method method in (classToWrapTypeReference.Declaration as Class).Methods)
                    {
                        // Skip constructors
                        if (method.IsConstructor)
                        {
                            continue;
                        }

                        // Skip on other access level than public
                        if (method.Access != AccessSpecifier.Public)
                        {
                            continue;
                        }

                        // Process method only once
                        if (methodsProcessed.Contains(method.Name))
                        {
                            continue;
                        }

                        // Output method declaration
                        WriteLine("static NAN_METHOD({0});", method.Name);
                        methodsProcessed.Add(method.Name);
                    }
                    PopBlock(NewLineKind.BeforeNextBlock);
                }
            }

            // Functions
            if (functions.Count > 0)
            {
                // Private members prototypes
                PopIndent();
                WriteLine("private:");
                PushIndent();

                PushBlock(BlockKind.MethodBody);
                WriteLine("// Wrapped functions");
                SortedSet <string> functionsProcessed = new SortedSet <string>(StringComparer.InvariantCulture);
                foreach (Function function in functions)
                {
                    // Skip on other access level than public
                    if (function.Access != AccessSpecifier.Public)
                    {
                        continue;
                    }

                    // Process method only once
                    if (functionsProcessed.Contains(function.Name))
                    {
                        continue;
                    }

                    // Output method declaration
                    WriteLine("static NAN_METHOD({0});", function.Name);
                    functionsProcessed.Add(function.Name);
                }
                PopBlock(NewLineKind.BeforeNextBlock);
            }

            // Wrapped object
            if (!string.IsNullOrEmpty(className))
            {
                // Wrapped object
                PushBlock(BlockKind.MethodBody);
                WriteLine("// Wrapped object");
                WriteLine("{0}* {1};", className, classNameWrapperMember);
                PopBlock();
            }

            PopIndent();
            WriteLine("};");

            PopBlock(NewLineKind.BeforeNextBlock);
        }