public void WriteSignature(StringBuilder text, SignatureType type) { if (type == SignatureType.PInvoke) { if ((ParameterType.Value == "bool") || (ParameterType.Value == "bool*")) { text.Append("[MarshalAs (UnmanagedType.U1)] "); } if (Annotations.ContainsKey("IsOut")) { text.Append("out "); } if (Annotations.ContainsKey("IsRef")) { text.Append("ref "); } } if (type == SignatureType.PInvoke && Annotations.ContainsKey("MarshalAs")) { text.Append(Annotations ["MarshalAs"].Value); } else if (type == SignatureType.NativeC && ParameterType.Value == "GCHandle") { text.Append("void *"); } else { ParameterType.Write(text, type, GlobalInfo); } if ((type != SignatureType.Native && type != SignatureType.NativeC) || !ParameterType.IsPointer) { text.Append(" "); } text.Append(Name); }
static bool ParseMembers (MemberInfo parent, Tokenizer tokenizer) { Annotations properties = new Annotations (); TypeInfo parent_type = parent as TypeInfo; string accessibility; TypeReference returntype; bool is_dtor; bool is_ctor; bool is_virtual; bool is_static; bool is_const; bool is_extern; string name; //Console.WriteLine ("ParseMembers ({0})", type.Name); do { returntype = null; is_dtor = is_ctor = is_virtual = is_static = false; is_extern = is_const = false; name = null; properties = new Annotations (); if (parent_type != null) accessibility = parent_type.IsStruct ? "public" : "private"; else accessibility = "public"; try { if (tokenizer.Accept (Token2Type.Punctuation, ";")) continue; } catch { return false; } if (tokenizer.CurrentToken.value == "}") return true; while (tokenizer.CurrentToken.type == Token2Type.CommentProperty) { properties.Add (tokenizer.CurrentToken.value); tokenizer.Advance (true); } //Console.WriteLine ("ParseMembers: Current token: {0}", tokenizer.CurrentToken); if (tokenizer.CurrentToken.type == Token2Type.Identifier) { string v = tokenizer.CurrentToken.value; switch (v) { case "public": case "protected": case "private": accessibility = v; tokenizer.Advance (true); tokenizer.Accept (Token2Type.Punctuation, ":"); continue; case "enum": ParseEnum (properties, parent, tokenizer); continue; case "friend": while (!tokenizer.Accept (Token2Type.Punctuation, ";")) { tokenizer.Advance (true); } continue; case "struct": case "class": case "union": if (!ParseClassOrStruct (properties, parent, tokenizer)) return false; continue; case "typedef": StringBuilder requisite = new StringBuilder (); requisite.Append (tokenizer.CurrentToken.value); requisite.Append (' '); tokenizer.Advance (true); while (!tokenizer.Accept (Token2Type.Punctuation, ";")) { requisite.Append (tokenizer.CurrentToken.value); requisite.Append (' '); if (tokenizer.CurrentToken.value == "{") { tokenizer.Advance (true); while (!tokenizer.Accept (Token2Type.Punctuation, "}")) { requisite.Append (tokenizer.CurrentToken.value); requisite.Append (' '); tokenizer.Advance (true); } requisite.Append (tokenizer.CurrentToken.value); requisite.Append (' '); } tokenizer.Advance (true); } requisite.Append (";"); if (properties.ContainsKey ("CBindingRequisite")) cbinding_requisites.AppendLine (requisite.ToString ()); continue; case "EVENTHANDLER": while (!tokenizer.Accept (Token2Type.Punctuation, ";")) tokenizer.Advance (true); continue; case "template": tokenizer.Advance (true); tokenizer.AcceptOrThrow (Token2Type.Punctuation, "<"); tokenizer.AcceptOrThrow (Token2Type.Identifier, "typename"); tokenizer.GetIdentifier (); tokenizer.AcceptOrThrow (Token2Type.Punctuation, ">"); continue; case "using": tokenizer.Advance (true); continue; case "namespace": tokenizer.Advance (true); tokenizer.GetIdentifier (); tokenizer.Accept (Token2Type.Punctuation, "{"); continue; case "mutable": tokenizer.Advance (true); continue; } } do { if (tokenizer.Accept (Token2Type.Identifier, "virtual")) { is_virtual = true; continue; } if (tokenizer.Accept (Token2Type.Identifier, "static")) { is_static = true; continue; } if (tokenizer.Accept (Token2Type.Identifier, "const")) { is_const = true; continue; } if (tokenizer.Accept (Token2Type.Identifier, "extern")) { is_extern = true; continue; } if (tokenizer.Accept (Token2Type.Identifier, "volatile")) { continue; } if (tokenizer.Accept (Token2Type.Identifier, "G_GNUC_INTERNAL")) { continue; } break; } while (true); if (is_extern && tokenizer.Accept (Token2Type.Literal, "C")) { tokenizer.SyncWithEndBrace (); continue; } if (tokenizer.Accept (Token2Type.Punctuation, "~")) { is_dtor = true; if (!is_virtual) { TypeInfo ti = parent as TypeInfo; if (ti != null && ti.Base != null) Console.WriteLine ("The class {0} has a non-virtual destructor, and it's base class is {2} ({1}).", parent.Name, parent.Header, ti != null && ti.Base != null ? ti.Base.Value : "<none>"); } } if (is_dtor) { name = "~" + tokenizer.GetIdentifier (); returntype = new TypeReference ("void"); } else { returntype = ParseTypeReference (tokenizer); if (tokenizer.CurrentToken.value == "<") { tokenizer.Advance (true); while (!tokenizer.Accept (Token2Type.Punctuation, ">")) tokenizer.Advance (true); } if (returntype.Value == parent.Name && tokenizer.CurrentToken.value == "(") { is_ctor = true; name = returntype.Value; returntype.Value += "*"; } else { name = tokenizer.GetIdentifier (); } } returntype.IsConst = is_const; returntype.IsReturnType = true; //Console.WriteLine ("ParseMembers: found member '{0}' is_ctor: {1}", name, is_ctor); if (tokenizer.Accept (Token2Type.Punctuation, "(")) { // Method MethodInfo method = new MethodInfo (); method.Header = tokenizer.CurrentFile; method.Parent = parent; method.Annotations = properties; method.Name = name; method.IsConstructor = is_ctor; method.IsDestructor = is_dtor; method.IsVirtual = is_virtual; method.IsStatic = is_static; method.IsPublic = accessibility == "public"; method.IsPrivate = accessibility == "private"; method.IsProtected = accessibility == "protected"; method.ReturnType = returntype; //Console.WriteLine ("ParseMembers: found method '{0}' is_ctor: {1}", name, is_ctor); if (!tokenizer.Accept (Token2Type.Punctuation, ")")) { string param_value = null; do { ParameterInfo parameter = new ParameterInfo (method); while (tokenizer.CurrentToken.type == Token2Type.CommentProperty) { parameter.Annotations.Add (tokenizer.CurrentToken.value); tokenizer.Advance (true); } if (tokenizer.Accept (Token2Type.Punctuation, ".") && tokenizer.Accept (Token2Type.Punctuation, ".") && tokenizer.Accept (Token2Type.Punctuation, ".")) { // ... variable argument declaration parameter.ParameterType = new TypeReference ("..."); } else { if (tokenizer.CurrentToken.type == Token2Type.Identifier) { if (tokenizer.Accept (Token2Type.Identifier, "Moonlight")) { tokenizer.Accept (Token2Type.Punctuation, ":"); tokenizer.Accept (Token2Type.Punctuation, ":"); } } parameter.ParameterType = ParseTypeReference (tokenizer); } if (tokenizer.CurrentToken.value != "," && tokenizer.CurrentToken.value != ")") { parameter.Name = tokenizer.GetIdentifier (); if (tokenizer.Accept (Token2Type.Punctuation, "[")) { if (tokenizer.CurrentToken.type == Token2Type.Identifier) tokenizer.Advance (true); tokenizer.AcceptOrThrow (Token2Type.Punctuation, "]"); } if (tokenizer.Accept (Token2Type.Punctuation, "=")) { param_value = string.Empty; if (tokenizer.Accept (Token2Type.Punctuation, "-")) param_value = "-"; param_value += tokenizer.GetIdentifier (); if (tokenizer.Accept (Token2Type.Punctuation, ":")) { tokenizer.AcceptOrThrow (Token2Type.Punctuation, ":"); param_value += "::" + tokenizer.GetIdentifier (); } } } method.Parameters.Add (parameter); //Console.WriteLine ("ParseMember: got parameter, type: '{0}' name: '{1}' value: '{2}'", parameter.ParameterType.Value, parameter.Name, param_value); } while (tokenizer.Accept (Token2Type.Punctuation, ",")); tokenizer.AcceptOrThrow (Token2Type.Punctuation, ")"); } parent.Children.Add (method); //Allow const member functions, ignore the const keyword tokenizer.Accept (Token2Type.Identifier, "const"); if (tokenizer.CurrentToken.value == "{") { //Console.WriteLine ("ParseMember: member has body, skipping it"); tokenizer.SyncWithEndBrace (); } else if (is_ctor && tokenizer.Accept (Token2Type.Punctuation, ":")) { // ctor method implemented in header with field initializers and/or base class ctor call tokenizer.FindStartBrace (); tokenizer.SyncWithEndBrace (); //Console.WriteLine ("ParseMember: skipped ctor method implementation"); } else if (tokenizer.Accept (Token2Type.Punctuation, "=")) { // pure virtual method tokenizer.AcceptOrThrow (Token2Type.Identifier, "0"); tokenizer.AcceptOrThrow (Token2Type.Punctuation, ";"); method.IsAbstract = true; } else { if (tokenizer.Accept (Token2Type.Identifier, "__attribute__")) { tokenizer.AcceptOrThrow (Token2Type.Punctuation, "("); tokenizer.AcceptOrThrow (Token2Type.Punctuation, "("); if (tokenizer.CurrentToken.type == Token2Type.Identifier) tokenizer.Advance (true); tokenizer.AcceptOrThrow (Token2Type.Punctuation, ")"); tokenizer.AcceptOrThrow (Token2Type.Punctuation, ")"); } tokenizer.AcceptOrThrow (Token2Type.Punctuation, ";"); } } else { if (is_ctor || is_dtor) throw new Exception (string.Format ("Expected '(', not '{0}'", tokenizer.CurrentToken.value)); if (name == "operator") { while (true) { if (tokenizer.CurrentToken.value == ";") { // End of operator break; } else if (tokenizer.CurrentToken.value == "{") { // In-line implementation tokenizer.SyncWithEndBrace (); break; } tokenizer.Advance (true); } //Console.WriteLine ("ParseMembers: skipped operator"); } else { FieldInfo field = new FieldInfo (); field.IsConst = is_const; field.IsStatic = is_static; field.IsExtern = is_extern; field.Name = name; field.FieldType = returntype; field.IsPublic = accessibility == "public"; field.IsPrivate = accessibility == "private"; field.IsProtected = accessibility == "protected"; field.Annotations = properties; // Field do { //Console.WriteLine ("ParseMembers: found field '{0}'", name); field.Parent = parent; parent.Children.Add (field); if (tokenizer.Accept (Token2Type.Punctuation, "[")) { while (!tokenizer.Accept (Token2Type.Punctuation, "]")) { tokenizer.Advance (true); } } if (tokenizer.Accept (Token2Type.Punctuation, ":")) { field.BitField = tokenizer.GetIdentifier (); } if (tokenizer.Accept (Token2Type.Punctuation, ",")) { field = new FieldInfo (); if (tokenizer.Accept (Token2Type.Punctuation, "*")) { // ok } field.Name = tokenizer.GetIdentifier (); field.FieldType = returntype; continue; } if (tokenizer.Accept (Token2Type.Punctuation, "=")) { tokenizer.Advance (true); /* this can be an arbitrary long expression, sync with the ';'? */ } break; } while (true); tokenizer.Accept (Token2Type.Punctuation, ";"); } } } while (true); }