private SyntaxNode GenerateMethodBody(ProxyClassGenContext context, IMethodSymbol methodSymbol, SyntaxGenerator syntaxGen, bool delegateCall) { var variableIdentifier = syntaxGen.IdentifierName(GetPrivateVariableNameForGeneration(context, methodSymbol)); var conditionStatement = syntaxGen.ValueNotEqualsExpression(variableIdentifier, syntaxGen.LiteralExpression(SyntaxKind.NullLiteralExpression)); var falseStatement = syntaxGen.ThrowStatement(syntaxGen.ObjectCreationExpression(syntaxGen.TypeExpression(mSystemExceptionTypeSymbol), syntaxGen.LiteralExpression(variableIdentifier.ToString() + " NULL"))); SyntaxNode invocationExpression = null; if (!delegateCall) { var genericName = GenerateLuaFunctionGenericName(methodSymbol, syntaxGen); var memberAccessExpression = syntaxGen.MemberAccessExpression(variableIdentifier, genericName); invocationExpression = syntaxGen.InvocationExpression(memberAccessExpression, GetMethodArgumentsForGeneration(methodSymbol, syntaxGen, false, true)); } else { invocationExpression = syntaxGen.InvocationExpression(variableIdentifier, GetMethodArgumentsForGeneration(methodSymbol, syntaxGen, true, true)); } SyntaxNode trueStatement = null; if (!methodSymbol.ReturnsVoid) { trueStatement = syntaxGen.ReturnStatement(invocationExpression); } else { trueStatement = invocationExpression; } var ifStatement = syntaxGen.IfStatement(conditionStatement, new SyntaxNode[] { trueStatement }, new SyntaxNode[] { falseStatement }); return(ifStatement); }
private SyntaxNode GenerateGetXLuaAdapterFunction(ProxyClassGenContext context, SyntaxGenerator syntaxGen) { List <SyntaxNode> statements = new List <SyntaxNode>(); statements.Add(syntaxGen.ReturnStatement(syntaxGen.IdentifierName("mXLuaClassProxyAdapter"))); return(syntaxGen.MethodDeclaration("getXLuaClassProxyAdapter", null, null, syntaxGen.TypeExpression(mXLuaClassProxyAdapterTypeSymbol), Accessibility.Public, DeclarationModifiers.None, statements)); }
public SyntaxNode GenerateDelegateCallMethod(ProxyClassGenContext context, IMethodSymbol methodSymbol) { SyntaxNode statements = GenerateMethodBody(context, methodSymbol, context.SyntaxGenerator, true); var methodDeclaration = context.SyntaxGenerator.MethodDeclaration(methodSymbol, new SyntaxNode[] { statements }); return(methodDeclaration); }
public SyntaxNode GenerateNormalMethod(ProxyClassGenContext context, IMethodSymbol methodSymbol, INamedTypeSymbol typeSymbol, SyntaxGenerator syntaxGen) { SyntaxNode statements = GenerateMethodBody(context, methodSymbol, syntaxGen, false); var methodDeclaration = syntaxGen.MethodDeclaration(methodSymbol, new SyntaxNode[] { statements }); return(methodDeclaration); }
private SyntaxNode GeneraterConstructFunction(ProxyClassGenContext context, SyntaxGenerator syntaxGen) { List <SyntaxNode> augurments = new List <SyntaxNode>(); augurments.Add(syntaxGen.ThisExpression()); List <SyntaxNode> statements = new List <SyntaxNode>(); statements.Add(syntaxGen.AssignmentStatement(syntaxGen.IdentifierName("mXLuaClassProxyAdapter"), syntaxGen.ObjectCreationExpression(SyntaxFactory.IdentifierName("XLuaClassProxyAdapter"), augurments))); return(syntaxGen.ConstructorDeclaration(context.TargetName, null, Accessibility.Public, DeclarationModifiers.None, null, statements)); }
private SyntaxNode GenerateUninitLuaFunction(ProxyClassGenContext context, INamedTypeSymbol typeSymbol, SyntaxGenerator syntaxGen, List <Tuple <SyntaxNode, SyntaxNode, IMethodSymbol> > delegateNodes) { var statements = new List <SyntaxNode>(); foreach (var method in context.MethodSymbols.Except(context.DelegateCallMethodSymbols)) { var variableIdentifier = syntaxGen.IdentifierName(GetPrivateVariableNameForGeneration(context, method)); var conditionStatement = syntaxGen.ValueNotEqualsExpression(variableIdentifier, syntaxGen.LiteralExpression(SyntaxKind.NullLiteralExpression)); var memberAccessExpression = syntaxGen.MemberAccessExpression(variableIdentifier, syntaxGen.IdentifierName("Dispose")); var invocationExpression = syntaxGen.InvocationExpression(memberAccessExpression); var ifStatement = syntaxGen.IfStatement(conditionStatement, new SyntaxNode[] { invocationExpression }); statements.Add(ifStatement); } return(syntaxGen.MethodDeclaration("UninitLuaFunction", null, null, null, Accessibility.Public, DeclarationModifiers.None, statements)); }
public void GenCode() { bool reGenXLuaCode = false; foreach (var item in mCodeGenConfig.ProxyClassItems) { Console.WriteLine("生成{0}代理类中", item.TargetName); ProxyClassGenContext context = new ProxyClassGenContext(); if (InitProxyClassGenContext(context, item)) { PerformProxyClassGeneration(context); if (context.DelegateCallMethodSymbols.Count != 0) { reGenXLuaCode = true; } } } foreach (var item in mCodeGenConfig.InterfaceItems) { Console.WriteLine("生成{0} Interface中", item.TargetName); InterfaceGenContext context = new InterfaceGenContext(); if (InitInterfaceGenContext(context, item)) { PerformInterfaceGeneration(context); } } Console.Write("代码生成完毕"); if (reGenXLuaCode) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(",注意,请在UnityEditor中执行XLua/Generate Code"); Console.ResetColor(); } else { Console.WriteLine(); } }
public SyntaxNode[] GeneratePrivateFields(ProxyClassGenContext context, SyntaxGenerator syntaxGen, INamedTypeSymbol typeSymbol, List <Tuple <SyntaxNode, SyntaxNode, IMethodSymbol> > delegateNodes) { List <SyntaxNode> nodes = new List <SyntaxNode>(); foreach (var method in context.MethodSymbols.Except(context.DelegateCallMethodSymbols)) { nodes.Add(syntaxGen.FieldDeclaration(GetPrivateVariableNameForGeneration(context, method), syntaxGen.TypeExpression(mLuaFunctionTypeSymbol), Accessibility.Private)); } foreach (var node in delegateNodes) { nodes.Add(syntaxGen.FieldDeclaration(GetPrivateVariableNameForGeneration(context, node.Item3), syntaxGen.IdentifierName(GetDelegateNameForGeneration(context, node.Item3)), Accessibility.Private)); } return(nodes.ToArray()); }
public SyntaxNode GenerateDelegateNode(ProxyClassGenContext context, IMethodSymbol method) { var delegateName = GetDelegateNameForGeneration(context, method); var typeParameters = (method.TypeParameters != null && method.TypeParameters.Length > 0) ? method.TypeParameters.Select(a => a.Name) : null; var parameters = new List <SyntaxNode>(); parameters.Add(context.SyntaxGenerator.ParameterDeclaration("self", context.SyntaxGenerator.TypeExpression(mLuaTableTypeSymbol))); parameters.AddRange(context.SyntaxGenerator.GetParameters(method.DeclaringSyntaxReferences.First().GetSyntax())); var delegateNode = context.SyntaxGenerator.DelegateDeclaration(delegateName, parameters: parameters, typeParameters: typeParameters, returnType: context.SyntaxGenerator.TypeExpression(method.ReturnType), accessibility: method.DeclaredAccessibility); delegateNode = context.SyntaxGenerator.AddAttributes(delegateNode, context.SyntaxGenerator.Attribute(context.SyntaxGenerator.IdentifierName("CSharpCallLua"))); return(delegateNode); }
public SyntaxNode GenerateProperty(ProxyClassGenContext context, IPropertySymbol propertySymbol, SyntaxGenerator syntaxGen) { SyntaxNode getMethodNode = null; SyntaxNode setMethodNode = null; if (propertySymbol.GetMethod != null) { getMethodNode = GenerateMethodBody(context, propertySymbol.GetMethod, syntaxGen, false); } if (propertySymbol.SetMethod != null) { setMethodNode = GenerateMethodBody(context, propertySymbol.SetMethod, syntaxGen, false); } var propertyNode = syntaxGen.PropertyDeclaration(propertySymbol, (getMethodNode != null ? new SyntaxNode[] { getMethodNode } : null), (setMethodNode != null ? new SyntaxNode[] { setMethodNode } : null)); return(propertyNode); }
private SyntaxNode GenerateInitLuaFunction(ProxyClassGenContext context, INamedTypeSymbol typeSymbol, SyntaxGenerator syntaxGen, List <Tuple <SyntaxNode, SyntaxNode, IMethodSymbol> > delegateNodes) { List <SyntaxNode> statements = new List <SyntaxNode>(); foreach (var method in context.MethodSymbols.Except(context.DelegateCallMethodSymbols)) { var genericName = syntaxGen.GenericName("GetInPath", mLuaFunctionTypeSymbol); var memberAccessExpression = syntaxGen.MemberAccessExpression(getSelfField(syntaxGen), genericName); var invocationExpression = syntaxGen.InvocationExpression(memberAccessExpression, syntaxGen.LiteralExpression(context.NameDic[method])); var assignExpression = syntaxGen.AssignmentStatement(syntaxGen.IdentifierName(GetPrivateVariableNameForGeneration(context, method)), invocationExpression); statements.Add(assignExpression); } foreach (var node in delegateNodes) { var genericName = syntaxGen.GenericName("Get", syntaxGen.IdentifierName(GetDelegateNameForGeneration(context, node.Item3))); var memberAccessExpression = syntaxGen.MemberAccessExpression(getSelfField(syntaxGen), genericName); var invocationExpression = syntaxGen.InvocationExpression(memberAccessExpression, syntaxGen.LiteralExpression(context.NameDic[node.Item3])); var assignExpression = syntaxGen.AssignmentStatement(syntaxGen.IdentifierName(GetPrivateVariableNameForGeneration(context, node.Item3)), invocationExpression); statements.Add(assignExpression); } return(syntaxGen.MethodDeclaration("InitLuaFunction", null, null, null, Accessibility.Public, DeclarationModifiers.None, statements)); }
private string GetDelegateNameForGeneration(ProxyClassGenContext context, IMethodSymbol symbol) { return("Delegate_" + context.NameDic[symbol]); }
private string GetPrivateVariableNameForGeneration(ProxyClassGenContext context, IMethodSymbol symbol) { return("m_" + context.NameDic[symbol]); }
public void PerformProxyClassGeneration(ProxyClassGenContext context) { var typeSymbol = context.TypeSymbol; var syntaxGen = context.SyntaxGenerator; // Generate using var usingDirectives = new SyntaxNode[] { syntaxGen.NamespaceImportDeclaration("System"), syntaxGen.NamespaceImportDeclaration("XLua") }; // Generate normal method var normalMethodNodes = new List <SyntaxNode>(context.NormalMethodSymbols.Count); foreach (IMethodSymbol method in context.NormalMethodSymbols) { normalMethodNodes.Add(GenerateNormalMethod(context, method, typeSymbol, syntaxGen)); } // Generate delegate call var delegateNodes = new List <Tuple <SyntaxNode, SyntaxNode, IMethodSymbol> >(); foreach (var method in context.DelegateCallMethodSymbols) { var delegateNode = GenerateDelegateNode(context, method); var delegateCallMethodNode = GenerateDelegateCallMethod(context, method); delegateNodes.Add(new Tuple <SyntaxNode, SyntaxNode, IMethodSymbol>(delegateNode, delegateCallMethodNode, method)); } // Generate property List <SyntaxNode> propertyNodes = new List <SyntaxNode>(context.PropertySymbols.Count); foreach (var propertySymbol in context.PropertySymbols) { propertyNodes.Add(GenerateProperty(context, propertySymbol, syntaxGen)); } // Generate InitLuaFunction/UninitLuaFunction normalMethodNodes.Add(GenerateInitLuaFunction(context, typeSymbol, syntaxGen, delegateNodes)); normalMethodNodes.Add(GenerateUninitLuaFunction(context, typeSymbol, syntaxGen, delegateNodes)); normalMethodNodes.Add(GenerateGetLuaClassName(typeSymbol, syntaxGen)); // Generate private fields var privateFields = GeneratePrivateFields(context, syntaxGen, typeSymbol, delegateNodes); //Generate XLuaClassProxyAdapter var luaAdpaterPublicField = syntaxGen.FieldDeclaration("mXLuaClassProxyAdapter", syntaxGen.TypeExpression(mXLuaClassProxyAdapterTypeSymbol), Accessibility.Private); var getXLuaProxyAdatperFunction = GenerateGetXLuaAdapterFunction(context, syntaxGen); var generaterConstructFunction = GeneraterConstructFunction(context, syntaxGen); // Union all syntax node var members = new List <SyntaxNode>(); members.Add(luaAdpaterPublicField); members.Add(generaterConstructFunction); members.Add(getXLuaProxyAdatperFunction); members.AddRange(delegateNodes.Select(a => a.Item1)); members.AddRange(delegateNodes.Select(a => a.Item2)); members.AddRange(propertyNodes); members.AddRange(normalMethodNodes); members.AddRange(privateFields); // Class var classDefinition = syntaxGen.ClassDeclaration(context.TargetName, typeParameters: null, accessibility: typeSymbol.DeclaredAccessibility, modifiers: DeclarationModifiers.From(typeSymbol), baseType: null, interfaceTypes: null, members: members); // Add base class //classDefinition = syntaxGen.AddBaseType(classDefinition, GetBaseNodeForGeneration(typeSymbol, syntaxGen)); //Implements custom Interface IXLuaSystemAction classDefinition = syntaxGen.AddInterfaceType(classDefinition, syntaxGen.IdentifierName("IXLuaSystemAction")); if (typeSymbol.Interfaces != null) { var interfaceTypes = GetInterfaceNodeForGeneration(typeSymbol, syntaxGen); foreach (var @interface in interfaceTypes) { classDefinition = syntaxGen.AddInterfaceType(classDefinition, @interface); } } classDefinition = syntaxGen.AddAttributes(classDefinition, syntaxGen.Attribute(syntaxGen.QualifiedName(syntaxGen.IdentifierName("Cs2Lua"), syntaxGen.IdentifierName("Ignore")))); SyntaxNode namespaceDeclaration = null; if (!string.IsNullOrEmpty(typeSymbol.ContainingNamespace.Name)) { namespaceDeclaration = syntaxGen.NamespaceDeclaration(typeSymbol.ContainingNamespace.Name, classDefinition); } // add comment usingDirectives[0] = AddComment(usingDirectives[0]); var finalNode = syntaxGen.CompilationUnit(usingDirectives.Union(new SyntaxNode[] { namespaceDeclaration ?? classDefinition })).NormalizeWhitespace(); var path = Path.Combine(context.TargetDir, context.TargetName); path = Path.ChangeExtension(path, ".cs"); var str = SimplifyGeneratedCode(context.TargetName, finalNode); using (var sw = File.CreateText(path)) { sw.Write(str); } }
public bool InitProxyClassGenContext(ProxyClassGenContext context, GenProxyClass item) { context.TargetName = item.TargetName; context.TargetDir = item.TargetDir; context.TypeSymbol = mCompilation.GetTypeByMetadataName(item.FullyQualifiedMetadataName); if (context.TypeSymbol == null) { Console.WriteLine("Cannot get type from FullyQualifiedMetadataName " + item.FullyQualifiedMetadataName); return(false); } context.SyntaxGenerator = SyntaxGenerator.GetGenerator(mProject); context.MethodSymbols.AddRange(GetPublicMethodForGeneration(context.TypeSymbol)); context.NormalMethodSymbols = context.MethodSymbols.Where((sym) => { if (sym.MethodKind == MethodKind.Ordinary) { foreach (var p in sym.Parameters) { if (p.RefKind == RefKind.Out || p.RefKind == RefKind.Ref) { return(false); } } return(true); } else { return(false); } }).ToList(); context.PropertySymbols = context.MethodSymbols.Where((sym) => { return(sym.MethodKind == MethodKind.PropertyGet || sym.MethodKind == MethodKind.PropertySet); }) .Select((a) => a.AssociatedSymbol) .Distinct() .OfType <IPropertySymbol>() .ToList(); context.DelegateCallMethodSymbols = context.MethodSymbols.Where((sym) => { if (sym.MethodKind == MethodKind.Ordinary) { foreach (var p in sym.Parameters) { if (p.RefKind == RefKind.Out || p.RefKind == RefKind.Ref) { return(true); } } } return(false); }).ToList(); foreach (var sym in context.MethodSymbols) { context.NameDic[sym] = GetCs2LuaFunctionName(sym); } return(true); }