public void Init(TypeSyntax typeSyntax, string name, string className, int index, Dictionary <string, MethodDeclarationSyntax> methods, SourceBuilder sb) { Type = typeSyntax.ToString(); this.Name = name; this.className = className; this.index = index; this.methods = methods; this.sb = sb; foreach (var innerType in typeSyntax.DescendantNodes().OfType <TypeSyntax>()) { var s = innerType.ToString(); typeArgs.Add(s); capitalizedTypeArgs.Add(s.First().ToString().ToUpper() + s.Substring(1)); } }
protected void ReadToVal(int parameterIndex = 0) { var attributeType = DeltaCore.GetAttributeType(typeArgs[parameterIndex]); if (attributeType == typeof(ResourceTypeAttribute)) { sb += $"var guid = buf.ReadGuid();"; sb += $"var p{parameterIndex} = {typeof(DeltaCore).Name}.Get<{typeArgs[parameterIndex]}>(guid);"; } else if (attributeType == typeof(SimpleTypeAttribute)) { sb += $"var p{parameterIndex} = buf.Read{capitalizedTypeArgs[parameterIndex]}();"; } else { sb += $"var p{parameterIndex} = ({capitalizedTypeArgs[parameterIndex]})buf.ReadNode(node);"; } }
public string Generate(string source) { var sb = new SourceBuilder(); foreach (var name in DeltaCore.GetNamespaces()) { sb += $"using {name};"; } var startLength = sb.Length; var root = CSharpSyntaxTree.ParseText(source).GetCompilationUnitRoot(); var classDeclarations = root.DescendantNodes().OfType <ClassDeclarationSyntax>(); foreach (var classDeclaration in classDeclarations) { GenerateClass(classDeclaration, sb); } return(startLength == sb.Length ? null : sb.ToString()); }
public void Generate() { SetEntry(); WriteEntry(); sb += $"static void ReadAssign{index}(Node node, BinaryBuffer buf) {{"; sb += $"var derived = ({className})node;"; ReadAssign(); sb += "}"; sb += $"static void Invoke{index}(Node node) {{"; sb += $"var derived = ({className})node;"; Invoke(); sb += "}"; sb += $"static void ReadAssignInvoke{index}(Node node, BinaryBuffer buf, bool initial) {{"; sb += $"var derived = ({className})node;"; ReadAssignInvoke(); sb += "}"; sb += $"static void ReadAuth{index}(Node node, BinaryBuffer buf) {{"; sb += $"var derived = ({className})node;"; ReadAuth(); sb += "}"; sb += $"static void Write{index}(Node node, BinaryBuffer buf) {{"; sb += $"var derived = ({className})node;"; Write(); sb += "}"; sb += $"static void StringWrite{index}(Node node, StringBuffer buf) {{"; sb += $"var derived = ({className})node;"; Write(); sb += "}"; sb += $"static void StringRead{index}(Node node, StringBuffer buf) {{"; sb += $"var derived = ({className})node;"; ReadAssignInvoke(); sb += "}"; }
void GenerateClass(ClassDeclarationSyntax classDeclaration, SourceBuilder sb) { if (classDeclaration.BaseList?.Types.First()?.ToString() != typeof(Node).Name) { return; } var isPartial = false; foreach (var token in classDeclaration.Modifiers) { if (token.IsKind(SyntaxKind.PartialKeyword)) { isPartial = true; } } var className = classDeclaration.Identifier.ToString(); if (isPartial == false) { throw new Exception($"{className} must be declared as public partial"); } var namespaceName = (classDeclaration.Parent as NamespaceDeclarationSyntax)?.Name; if (namespaceName != null) { sb += $"namespace {namespaceName} {{"; } sb += $"public partial class {className} {{"; var methods = new Dictionary <string, MethodDeclarationSyntax>(); foreach (var member in classDeclaration.Members) { if (member is MethodDeclarationSyntax method) { var methodName = method.Identifier.ToString().ToLower(); if (!methods.ContainsKey(methodName)) { methods.Add(methodName, method); } } } var fields = new List <GeneratorBase>(); foreach (var fieldSyntax in classDeclaration.Members.OfType <FieldDeclarationSyntax>()) { var typeSyntax = fieldSyntax.Declaration.Type; var genericType = typeSyntax.ChildTokens().FirstOrDefault().ToString(); if (fieldGenerators.TryGetValue(genericType, out Type generatorType)) { var fieldName = fieldSyntax.Declaration.ChildNodes().OfType <VariableDeclaratorSyntax>().First().Identifier.ToString(); var generator = (GeneratorBase)Activator.CreateInstance(generatorType); generator.Init(typeSyntax, fieldName, className, fields.Count, methods, sb); fields.Add(generator); generator.Generate(); } } //Construct sb += $"public static Node Construct(NodeBindings bindings) {{"; sb += $"var node = new {className}();"; sb += "node.Bindings = bindings;"; for (int i = 0; i < fields.Count; i++) { sb += $"node.{fields[i].Name} = new {fields[i].Type}(node, {i});"; } sb += "return node;"; sb += "}"; //Destruct sb += "public static void Destruct(Node node) {"; sb += "if(!node.Initialized)"; sb += $"\tthrow new System.InvalidOperationException(\"Destroying an uninitialized {className} node\");"; sb += $"var derived = ({className})node;"; sb += "derived.Initialized = false;"; sb += "for(int i = 0; i < derived.ChildCount; i++) {"; sb += "var child = derived[i];"; sb += "if(child != null) {"; sb += "child.Bindings.Destruct(child);"; sb += "}"; sb += "}"; methods.TryGetValue($"SyncDispose", out MethodDeclarationSyntax disposeMethod); if (disposeMethod != null) { sb += $"var derived = ({className})node;"; sb += "derived.SyncDispose();"; } //TODO update resource ref counts sb += "}"; sb += "}"; //Class if (namespaceName != null) { sb += "}"; } }