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); }
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); }
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); }