Example #1
0
        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);
        }
Example #2
0
        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));
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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));
        }
Example #6
0
        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));
        }
Example #7
0
        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();
            }
        }
Example #8
0
        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());
        }
Example #9
0
        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);
        }
Example #10
0
        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);
        }
Example #11
0
        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));
        }
Example #12
0
 private string GetDelegateNameForGeneration(ProxyClassGenContext context, IMethodSymbol symbol)
 {
     return("Delegate_" + context.NameDic[symbol]);
 }
Example #13
0
 private string GetPrivateVariableNameForGeneration(ProxyClassGenContext context, IMethodSymbol symbol)
 {
     return("m_" + context.NameDic[symbol]);
 }
Example #14
0
        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);
            }
        }
Example #15
0
        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);
        }