MemberDeclarationSyntax GenErrorCopy(@errorcopy e) { if (e.name == null) { throw new InvalidOperationException("Name cannot be null"); } return (ClassDeclaration(typeMap.NewTypeToCs(GeneratorUtil.ToCs(e.name) + "Error")). AddAttributeLists(BuildSingleAttributeList("Error", e.number)). AddBaseListTypes(SimpleBaseType(IdentifierName(GeneratorUtil.ToCs(e.@ref) + "Error")))); }
MemberDeclarationSyntax GenRequest(@request r) { if (r.name == null) { return; } string inherits = isExtension ? "ExtensionRequest" : "Request"; cwt.WriteLine("[Request (" + r.opcode + ")]"); GenClass(cwt, typeMap.NewTypeToCs(GeneratorUtil.ToCs(r.name) + "Request"), r.Items); if (r.reply != null) { cwt.WriteLine("[Reply (" + r.opcode + ")]"); GenClass(cwt, typeMap.NewTypeToCs(GeneratorUtil.ToCs(r.name) + "Reply"), r.reply.Items); } }
MemberDeclarationSyntax GenEvent(@event e) { if (e.name == null) { throw new Exception("Can't have null name"); // FIXME: handle this } string name = GeneratorUtil.ToCs(e.name); return(EventFieldDeclaration( VariableDeclaration( GenericName(Identifier("EventHandler"), TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName(name + "Event")))), SingletonSeparatedList(VariableDeclarator(Identifier(name + "Event"))))). WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))); }
MemberDeclarationSyntax GenEnum(@enum e) { if (e.name == null) { return; } cwt.WriteLine("public enum " + GeneratorUtil.ToCs(e.name) + " : uint"); cwt.WriteLine("{"); foreach (item it in e.item) { cwt.WriteLine(GeneratorUtil.ToCs(it.name) + ","); } cwt.WriteLine("}"); cwt.WriteLine(); }
Tuple <MemberDeclarationSyntax, int> GenClassData(string sName, object[] sItems, string suffix, bool withOffsets) { string sizeString = ""; //FIXME: EndsWith hack bool isRequest = sName.EndsWith("RequestData"); bool isEvent = sName.EndsWith("EventData"); bool isError = sName.EndsWith("ErrorData"); //FIXME: Rep shouldn't have offsets/inherits bool isReply = sName.EndsWith("ReplyData"); bool isStruct = (!isRequest && !isEvent && !isError && !isReply && !sName.EndsWith("RepData")); if (sName.EndsWith("EventData") || sName.EndsWith("ErrorData")) { sizeString = ", Size=" + 28; } Dictionary <string, int> sizeParams = new Dictionary <string, int>(); int offset = 0; if (sItems != null) { if (isRequest) { offset += 4; } if (isError || isEvent) { offset += 4; } if (isReply && !sName.EndsWith("RepData")) { offset += 8; } bool first = true; foreach (object ob in sItems) { bool isData = first && (isReply || (isRequest && !isExtension)); first = false; if (ob is field) { field f = ob as field; if (f.name == null) { continue; } string fName = GeneratorUtil.ToCs(f.name); if (fName == sName || fName + "Data" == sName) { Console.Error.WriteLine("Warning: field renamed: " + fName); fName = "Value"; } string fType = typeMap.TypeToCs(f.type); //in non-extension requests, the data field carries the first element if (withOffsets) { if (isData) { cwt.WriteLine("[FieldOffset (" + 1 + ")]"); } else { cwt.WriteLine("[FieldOffset (" + offset + ")]"); offset += typeMap.SizeOfType(fType); } } if (withOffsets) { cwt.WriteLine("public " + fType + " @" + fName + ";"); } else { cwt.WriteLine("public " + fType + " @" + fName); cwt.WriteLine("{"); cwt.WriteLine("get {"); cwt.WriteLine("return MessageData.@" + fName + ";"); cwt.WriteLine("} set {"); cwt.WriteLine("MessageData.@" + fName + " = value;"); cwt.WriteLine("}"); cwt.WriteLine("}"); } } else if (ob is pad) { if (!withOffsets) { continue; } pad p = ob as pad; int padding = Int32.Parse(p.bytes); if (isData) { padding--; } if (padding > 0) { cwt.WriteLine("//byte[" + padding + "]"); offset += padding; } } } } return(offset); }
ClassDeclarationSyntax GenClass(string sName, object[] sItems, string suffix) { Dictionary <string, int> sizeParams = new Dictionary <string, int>(); bool basicStruct = basic; if (sName == "GContext") { basicStruct = true; } if (sName == "Drawable") { basicStruct = true; } if (sName == "Fontable") { basicStruct = true; } //if (sName == "ClientMessageData") // basicStruct = true; bool isRequest = sName.EndsWith("Request"); bool isEvent = sName.EndsWith("Event"); if (!basicStruct) { int structSize = StructSize(sItems); cwt.WriteLine("[StructLayout (LayoutKind.Explicit, Pack=1, CharSet=CharSet.Ansi, Size=" + structSize + ")]"); cwt.WriteLine("public struct @" + sName + "Data"); cwt.WriteLine("{"); if (isRequest) { //TODO: generate one or the other cwt.WriteLine("[FieldOffset (0)]"); cwt.WriteLine("public Request Header;"); cwt.WriteLine("[FieldOffset (0)]"); cwt.WriteLine("public ExtensionRequest ExtHeader;"); } GenClassData(cwt, sName + "Data", sItems, "", true); cwt.WriteLine("}"); cwt.WriteLine(); } if (basicStruct) { int structSize = StructSize(sItems); cwt.WriteLine("[StructLayout (LayoutKind.Explicit, Pack=1, CharSet=CharSet.Ansi, Size=" + structSize + ")]"); cwt.WriteLine("public struct @" + sName + suffix); } else { //TODO: clean up hack if (suffix == "") { suffix += " : "; } else { suffix += ", "; } suffix += "IMessagePart"; cwt.WriteLine("public class @" + sName + suffix); } cwt.WriteLine("{"); if (!basicStruct) { cwt.WriteLine("public " + sName + "Data" + " MessageData;"); } int offset = GenClassData(cwt, sName, sItems, "", basicStruct); if (!basicStruct) { cwt.WriteLine("public int Read (IntPtr ptr)"); cwt.WriteLine("{"); cwt.WriteLine("int offset = 0;"); cwt.WriteLine("unsafe {"); cwt.WriteLine("MessageData = *(" + sName + "Data" + "*)ptr;"); cwt.WriteLine("offset += sizeof (" + sName + "Data" + ");"); cwt.WriteLine("}"); if (sItems != null) { foreach (object ob in sItems) { if (ob is list) { list l = ob as list; string lName = GeneratorUtil.ToCs(l.name); string lType = typeMap.TypeToCs(l.type); if (lName == sName) { Console.Error.WriteLine("Warning: list field renamed: " + lName); lName = "Values"; } if (l.type == "CHAR2B" || lType == "sbyte") { cwt.WriteLine("//if (@" + lName + " != null)"); cwt.WriteLine("//yield return XMarshal.Do (@" + lName + ");"); //cwt.WriteLine (lName + " = Marshal.PtrToStringAnsi (new IntPtr ((int)ptr + offset), " // "MessageData.@" + ToCs (l.fieldref) + ");"); cwt.WriteLine("//" + lName + " = Marshal.PtrToStringAnsi (new IntPtr ((int)ptr + offset), MessageData.@" + (lName + "Len") + ");"); cwt.WriteLine("//offset += " + (lName + "Len") + ";"); } } else if (ob is valueparam) { valueparam v = ob as valueparam; string vName = (v.valuelistname == null) ? "Values" : GeneratorUtil.ToCs(v.valuelistname); string vType = typeMap.TypeToCs(v.valuemasktype); if (vType == "uint") { cwt.WriteLine("//if (@" + vName + " != null)"); cwt.WriteLine("//yield return XMarshal.Do (ref @" + vName + ");"); } } } } cwt.WriteLine("return offset;"); cwt.WriteLine("}"); cwt.WriteLine(); cwt.WriteLine("IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator (); }"); cwt.WriteLine(); cwt.WriteLine("public IEnumerator<IOVector> GetEnumerator ()"); cwt.WriteLine("{"); cwt.WriteLine("yield return XMarshal.Do (ref MessageData);"); if (sItems != null) { foreach (object ob in sItems) { if (ob is list) { list l = ob as list; string lName = GeneratorUtil.ToCs(l.name); string lType = typeMap.TypeToCs(l.type); if (lName == sName) { Console.Error.WriteLine("Warning: list field renamed: " + lName); lName = "Values"; } if (l.type == "CHAR2B" || lType == "sbyte" || lType == "byte") { cwt.WriteLine("if (@" + lName + " != null)"); cwt.WriteLine("yield return XMarshal.Do (ref @" + lName + ");"); } } else if (ob is valueparam) { valueparam v = ob as valueparam; string vName = (v.valuelistname == null) ? "Values" : GeneratorUtil.ToCs(v.valuelistname); string vType = typeMap.TypeToCs(v.valuemasktype); if (vType == "uint") { cwt.WriteLine("if (@" + vName + " != null)"); cwt.WriteLine("yield return XMarshal.Do (ref @" + vName + ");"); } } } } cwt.WriteLine("}"); cwt.WriteLine(); } if (sItems != null) { foreach (object ob in sItems) { if (ob is list) { list l = ob as list; string lName = GeneratorUtil.ToCs(l.name); if (lName == sName) { Console.Error.WriteLine("Warning: list field renamed: " + lName); lName = "Values"; } string lType = typeMap.TypeToCs(l.type); if (!sizeParams.ContainsKey(l.name)) { Console.Error.WriteLine("Warning: No length given for " + lName); cwt.WriteLine("//FIXME: No length given"); } else if (l.type == "CHAR2B" || lType == "sbyte") { cwt.WriteLine("//[MarshalAs (UnmanagedType.LPStr, SizeParamIndex=" + sizeParams[l.name] + ")]"); } else { cwt.WriteLine("[MarshalAs (UnmanagedType.LPArray, SizeParamIndex=" + sizeParams[l.name] + ")]"); } if (l.type == "CHAR2B" || lType == "sbyte") { cwt.WriteLine("public string @" + lName + ";"); } else { cwt.WriteLine("public " + lType + "[] @" + lName + ";"); } offset += 4; } else if (ob is valueparam) { valueparam v = ob as valueparam; string vName = (v.valuelistname == null) ? "Values" : GeneratorUtil.ToCs(v.valuelistname); string vType = typeMap.TypeToCs(v.valuemasktype); cwt.WriteLine("//public ValueList<" + vType + "> @" + vName + ";"); cwt.WriteLine("public " + vType + "[] @" + vName + ";"); offset += 4; } } } cwt.WriteLine("}"); cwt.WriteLine(); }
MemberDeclarationSyntax GenFunction(@request r) { // TODO: we should be able to share a lot of this with InterfaceGenerator if (r.name == null) { throw new Exception("Can't have null name"); // FIXME: handle this } //TODO: share code with struct List <ParameterSyntax> methodParameters = new List <ParameterSyntax>(); List <StatementSyntax> methodBody = new List <StatementSyntax>(); //cw.WriteLine(GeneratorUtil.ToCs(r.name) + "Request req = new " + GeneratorUtil.ToCs(r.name) + "Request ();"); var requestType = IdentifierName(GeneratorUtil.ToCs(r.name) + "Request"); methodBody.Add( LocalDeclarationStatement( VariableDeclaration( requestType, SingletonSeparatedList( VariableDeclarator(Identifier("req"), null, EqualsValueClause( ObjectCreationExpression( requestType). WithArgumentList(ArgumentList()))))))); var messageDataAccess = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("req"), IdentifierName("MessageData")); if (isExtension) { var extHeaderAccess = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, messageDataAccess, IdentifierName("ExtHeader")); methodBody.Add(ExpressionStatement( AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, extHeaderAccess, IdentifierName("MajorOpcode")), IdentifierName("GlobalId")))); methodBody.Add(ExpressionStatement( AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, extHeaderAccess, IdentifierName("MajorOpcode")), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(int.Parse(r.opcode)))))); } else { var headerAccess = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, messageDataAccess, IdentifierName("Header")); methodBody.Add(ExpressionStatement( AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, headerAccess, IdentifierName("Opcode")), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(int.Parse(r.opcode)))))); } if (r.Items != null) { foreach (object ob in r.Items) { if (ob is field) { field f = ob as field; if (f.name == null) { continue; } string paramName = "@" + GeneratorUtil.ToParm(GeneratorUtil.ToCs(f.name)); methodParameters.Add(Parameter(Identifier(paramName)). WithType(IdentifierName(typeMap.TypeToCs(f.type)))); methodBody.Add(ExpressionStatement( AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, messageDataAccess, IdentifierName("@" + GeneratorUtil.ToCs(f.name))), IdentifierName(paramName)))); } else if (ob is list) { list l = ob as list; if (l.name == null) { continue; } string paramName = "@" + GeneratorUtil.ToParm(GeneratorUtil.ToCs(l.name)); TypeSyntax paramType; if (l.type == "char") { paramType = PredefinedType(Token(SyntaxKind.StringKeyword)); } else if (l.type == "CARD32") { paramType = ArrayType(PredefinedType(Token(SyntaxKind.UIntKeyword))). WithRankSpecifiers(SingletonList( ArrayRankSpecifier( SingletonSeparatedList <ExpressionSyntax>( OmittedArraySizeExpression())))); } else { // FIXME: handle these continue; } methodParameters.Add(Parameter(Identifier(paramName)). WithType(paramType)); methodBody.Add(ExpressionStatement( AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("req"), IdentifierName("@" + GeneratorUtil.ToCs(l.name))), IdentifierName(paramName)))); } else if (ob is valueparam) { valueparam v = ob as valueparam; string vName = (v.valuelistname == null) ? "Values" : GeneratorUtil.ToCs(v.valuelistname); string vType = typeMap.TypeToCs(v.valuemasktype); string paramName = "@" + GeneratorUtil.ToParm(vName); if (vType == "uint") { methodParameters.Add(Parameter(Identifier(paramName)). WithType(ArrayType(PredefinedType(Token(SyntaxKind.UIntKeyword))). WithRankSpecifiers(SingletonList( ArrayRankSpecifier( SingletonSeparatedList <ExpressionSyntax>( OmittedArraySizeExpression())))))); methodBody.Add(ExpressionStatement( AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("req"), IdentifierName("@" + vName)), IdentifierName(paramName)))); } } } } //cw.WriteLine("c.xw.Send (req);"); methodBody.Add(ExpressionStatement( InvocationExpression( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("c"), IdentifierName("xw")), IdentifierName("Send"))). WithArgumentList(ArgumentList( SingletonSeparatedList(Argument(IdentifierName("req"))))))); if (r.reply != null) { //cw.WriteLine("return c.xrr.GenerateCookie<" + GeneratorUtil.ToCs(r.name) + "Reply> ();"); var xrrAccess = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("c"), IdentifierName("xrr")); methodBody.Add( ReturnStatement( InvocationExpression( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, xrrAccess, GenericName("GenerateCookie"). WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName( GeneratorUtil.ToCs(r.name) + "Reply")))))))); } if (r.reply != null) { //cw.WriteLine("public Cookie<" + GeneratorUtil.ToCs(r.name) + "Reply> " + GeneratorUtil.ToCs(r.name) + // " (" + parms + ");"); return(MethodDeclaration( GenericName("Cookie"). WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList <TypeSyntax>( IdentifierName(GeneratorUtil.ToCs(r.name) + "Reply")))), GeneratorUtil.ToCs(r.name)). WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))). WithParameterList(ParameterList(SeparatedList(methodParameters))). WithBody(Block(methodBody))); } else { //cw.WriteLine("public void " + GeneratorUtil.ToCs(r.name) + " (" + parms + ");"); return(MethodDeclaration( PredefinedType(Token(SyntaxKind.VoidKeyword)), GeneratorUtil.ToCs(r.name)). WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))). WithParameterList(ParameterList(SeparatedList(methodParameters))). WithBody(Block(methodBody))); } }
private MethodDeclarationSyntax GenFunction(@request r, string name) { if (r.name == null) { return(null); } //TODO: share code with struct List <ParameterSyntax> parameters = new List <ParameterSyntax>(); if (r.Items != null) { foreach (object ob in r.Items) { if (ob is field) { field f = ob as field; if (f.name == null) { continue; } parameters.Add(Parameter(Identifier("@" + f.name)).WithType(IdentifierName(f.type))); } else if (ob is list) { list l = ob as list; if (l.name == null) { continue; } string listName = "@" + GeneratorUtil.ToParm(GeneratorUtil.ToCs(l.name)); if (l.type == "char") { parameters.Add(Parameter(Identifier(listName)). WithType(PredefinedType(Token(SyntaxKind.StringKeyword)))); } else if (l.type == "CARD32") { parameters.Add(Parameter(Identifier(listName)). WithType(ArrayType(PredefinedType(Token(SyntaxKind.UIntKeyword))). WithRankSpecifiers(SingletonList( ArrayRankSpecifier( SingletonSeparatedList <ExpressionSyntax>( OmittedArraySizeExpression())))))); } } else if (ob is valueparam) { valueparam v = ob as valueparam; string vName = (v.valuelistname == null) ? "Values" : "@" + GeneratorUtil.ToParm(GeneratorUtil.ToCs(v.valuelistname)); string vType = typeMap.TypeToCs(v.valuemasktype); if (vType == "uint") { parameters.Add(Parameter(Identifier(vName)). WithType(ArrayType(PredefinedType(Token(SyntaxKind.UIntKeyword))). WithRankSpecifiers(SingletonList( ArrayRankSpecifier( SingletonSeparatedList <ExpressionSyntax>( OmittedArraySizeExpression())))))); } } } } if (r.reply != null) { TypeSyntax returnType = GenericName(Identifier("Cookie"), TypeArgumentList(SingletonSeparatedList <TypeSyntax>( IdentifierName(GeneratorUtil.ToCs(r.name))))); return(MethodDeclaration(returnType, Identifier(GeneratorUtil.ToCs(r.name))). WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))). WithParameterList(ParameterList(SeparatedList(parameters))). WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); } else { return(MethodDeclaration(PredefinedType(Token(SyntaxKind.VoidKeyword)), Identifier(GeneratorUtil.ToCs(r.name))). WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))). WithParameterList(ParameterList(SeparatedList(parameters))). WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); } }