コード例 #1
0
        private Expression convertExpression(ExpressionSyntax expression)
        {
            switch (expression)
            {
            case BinaryExpressionSyntax binaryExpressionSyntax:
                var be = new BinaryExpression();
                be.Kind  = convertBinaryExpressionKind(binaryExpressionSyntax.Kind());
                be.Left  = convertExpression(binaryExpressionSyntax.Left);
                be.Right = convertExpression(binaryExpressionSyntax.Right);
                return(be);

            case IdentifierNameSyntax identifierNameSyntax:
                var id = new IdentifierNameExpression();
                id.Name = identifierNameSyntax.ToString();
                return(id);

            case LiteralExpressionSyntax literalExpressionSyntax:
                var le = convertLiteralExpressionValue(literalExpressionSyntax);
                return(le);

            case AssignmentExpressionSyntax assignmentExpressionSyntax:
                var ae = new AssignmentExpression();
                ae.Left  = convertExpression(assignmentExpressionSyntax.Left);
                ae.Right = convertExpression(assignmentExpressionSyntax.Right);
                return(ae);

            case PostfixUnaryExpressionSyntax postfixUnaryExpressionSyntax:
                var pe = new PostfixUnaryExpression();
                pe.Expression = postfixUnaryExpressionSyntax.Operand;
                return(pe);
            }

            return(null);
        }
コード例 #2
0
 private static void WriteIdentifierNameExperesion(IdentifierNameExpression expression, StreamWriter writer)
 {
     if (expression.isProperty)
     {
         writer.Write(expression.fullNameFlat + "_get()");
     }
     else
     {
         writer.Write(expression.fullNameFlat);
     }
 }
コード例 #3
0
        /// <summary>
        /// 式中のメンバアクセス、定数等を解析する。
        /// </summary>
        /// <param name="syntax"></param>
        /// <param name="semanticModel"></param>
        /// <returns></returns>
        Expression ParseExpression(ExpressionSyntax syntax, SemanticModel semanticModel)
        {
            if (syntax == null)
            {
                return(null);
            }

            var mae = syntax as MemberAccessExpressionSyntax;
            var gns = syntax as GenericNameSyntax;

            var le    = syntax as LiteralExpressionSyntax;
            var ie    = syntax as InvocationExpressionSyntax;
            var oce   = syntax as ObjectCreationExpressionSyntax;
            var ce    = syntax as CastExpressionSyntax;
            var thise = syntax as ThisExpressionSyntax;
            var ae    = syntax as AssignmentExpressionSyntax;
            var pe    = syntax as ParenthesizedExpressionSyntax;

            var ine = syntax as IdentifierNameSyntax;

            var eae   = syntax as ElementAccessExpressionSyntax;
            var be    = syntax as BinaryExpressionSyntax;
            var preue = syntax as PrefixUnaryExpressionSyntax;
            var poue  = syntax as PostfixUnaryExpressionSyntax;
            var basee = syntax as BaseExpressionSyntax;

            var ace  = syntax as ArrayCreationExpressionSyntax;
            var sace = syntax as StackAllocArrayCreationExpressionSyntax;

            var iee = syntax as InitializerExpressionSyntax;

            /*
             * var coe = syntax as ConditionalExpressionSyntax;
             * var sle = syntax as SimpleLambdaExpressionSyntax;
             * var ple = syntax as ParenthesizedLambdaExpressionSyntax;
             * var oase = syntax as OmittedArraySizeExpressionSyntax;
             * var iace = syntax as ImplicitArrayCreationExpressionSyntax;
             *
             * var qua = syntax as QualifiedNameSyntax;
             * var predf = syntax as PredefinedTypeSyntax;
             */

            // 自己の型を解析
            TypeInfo?selfTypeInfo = null;

            selfTypeInfo = semanticModel.GetTypeInfo(syntax);
            var selfType = ParseType(syntax, selfTypeInfo, semanticModel);

            if (mae != null)
            {
                MemberAccessExpression exp = new MemberAccessExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                exp.Name = mae.Name.ToString();

                if (mae.Name is GenericNameSyntax)
                {
                    var gns_ = mae.Name as GenericNameSyntax;
                    exp.Types = gns_.TypeArgumentList.Arguments.Select(_ => ParseType(_, semanticModel)).ToArray();
                }

                TypeInfo?parentType = null;
                if (mae.Expression != null)
                {
                    parentType = semanticModel.GetTypeInfo(mae.Expression);
                }

                // 種類を取得
                var symbol         = semanticModel.GetSymbolInfo(mae);
                var methodSymbol   = symbol.Symbol as IMethodSymbol;
                var propertySymbol = symbol.Symbol as IPropertySymbol;

                // 親の種類を探索
                List <ClassDef> classDefPs = new List <ClassDef>();

                EnumDef      enumDefP      = null;
                InterfaceDef interfaceDefP = null;
                StructDef    structDefP    = null;

                // プロパティである
                if (propertySymbol != null)
                {
                    exp.IsProperty = true;
                }

                if (parentType.HasValue && parentType.Value.Type != null)
                {
                    if (parentType.Value.Type.TypeKind == TypeKind.Interface)
                    {
                        var memName    = mae.Name.ToString();
                        var sym        = semanticModel.GetSymbolInfo(mae);
                        var name_      = parentType.Value.Type.Name;
                        var namespace_ = Utils.ToStr(parentType.Value.Type.ContainingNamespace);
                        interfaceDefP = definitions.Interfaces.Where(_ => _.Namespace == namespace_ && _.Name == name_).FirstOrDefault();
                    }
                    else if (parentType.Value.Type.TypeKind == TypeKind.Class)
                    {
                        var memName    = mae.Name.ToString();
                        var sym        = semanticModel.GetSymbolInfo(mae);
                        var name_      = parentType.Value.Type.Name;
                        var namespace_ = Utils.ToStr(parentType.Value.Type.ContainingNamespace);

                        classDefPs = definitions.FindTypeWithBases(namespace_, name_).OfType <ClassDef>().ToList();
                    }
                    else if (parentType.Value.Type.TypeKind == TypeKind.Enum)
                    {
                        var enumName   = selfTypeInfo.Value.Type.Name;
                        var namespace_ = Utils.ToStr(selfTypeInfo.Value.Type.ContainingNamespace);
                        enumDefP = definitions.Enums.Where(_ => _.Namespace == namespace_ && _.Name == enumName).FirstOrDefault();
                    }
                    else if (parentType.Value.Type.TypeKind == TypeKind.Struct)
                    {
                        var memName    = mae.Name.ToString();
                        var sym        = semanticModel.GetSymbolInfo(mae);
                        var name_      = parentType.Value.Type.Name;
                        var namespace_ = Utils.ToStr(parentType.Value.Type.ContainingNamespace);
                        structDefP = definitions.Structs.Where(_ => _.Namespace == namespace_ && _.Name == name_).FirstOrDefault();
                    }
                }

                // 親から子を探索
                if (interfaceDefP != null)
                {
                    if (methodSymbol != null)
                    {
                        var method = interfaceDefP.Methods.Where(_ =>
                        {
                            if (_.Name != methodSymbol.Name)
                            {
                                return(false);
                            }
                            if (_.Parameters.Count() != methodSymbol.Parameters.Count())
                            {
                                return(false);
                            }

                            for (int i = 0; i < _.Parameters.Count(); i++)
                            {
                                if (_.Parameters[i].Name != methodSymbol.Parameters[i].Name)
                                {
                                    return(false);
                                }

                                // TODO 正しい変換
                                //if(_.Parameters[i].Type != methodSymbol.Parameters[i].Type)
                            }

                            return(true);
                        }).FirstOrDefault();

                        if (method != null)
                        {
                            exp.Name   = null;
                            exp.Method = method;
                        }
                    }
                    else if (propertySymbol != null)
                    {
                        var prop = interfaceDefP.Properties.Where(_ =>
                        {
                            if (_.Name != propertySymbol.Name)
                            {
                                return(false);
                            }
                            return(true);
                        }).FirstOrDefault();

                        if (prop != null)
                        {
                            exp.Name     = null;
                            exp.Property = prop;
                        }
                    }
                }
                else if (classDefPs.Count > 0)
                {
                    if (methodSymbol != null)
                    {
                        foreach (var classDefP in classDefPs)
                        {
                            var method = classDefP.Methods.Where(_ =>
                            {
                                if (_.Name != methodSymbol.Name)
                                {
                                    return(false);
                                }
                                if (_.Parameters.Count() != methodSymbol.Parameters.Count())
                                {
                                    return(false);
                                }

                                for (int i = 0; i < _.Parameters.Count(); i++)
                                {
                                    if (_.Parameters[i].Name != methodSymbol.Parameters[i].Name)
                                    {
                                        return(false);
                                    }

                                    // TODO 正しい変換
                                    //if(_.Parameters[i].Type != methodSymbol.Parameters[i].Type)
                                }

                                return(true);
                            }).FirstOrDefault();

                            if (method != null)
                            {
                                exp.Name   = null;
                                exp.Class  = classDefP;
                                exp.Method = method;

                                // staticの場合走査停止
                                if (method.IsStatic)
                                {
                                    return(exp);
                                }
                                break;
                            }
                        }
                    }
                    else if (propertySymbol != null)
                    {
                        foreach (var classDefP in classDefPs)
                        {
                            var prop = classDefP.Properties.Where(_ =>
                            {
                                if (_.Name != propertySymbol.Name)
                                {
                                    return(false);
                                }
                                return(true);
                            }).FirstOrDefault();

                            if (prop != null)
                            {
                                exp.Name     = null;
                                exp.Class    = classDefP;
                                exp.Property = prop;
                                break;
                            }
                        }
                    }
                }
                else if (structDefP != null)
                {
                    if (propertySymbol != null)
                    {
                        var prop = structDefP.Properties.Where(_ =>
                        {
                            if (_.Name != propertySymbol.Name)
                            {
                                return(false);
                            }
                            return(true);
                        }).FirstOrDefault();

                        if (prop != null)
                        {
                            exp.Name     = null;
                            exp.Struct   = structDefP;
                            exp.Property = prop;
                        }
                    }
                }
                else if (enumDefP != null)
                {
                    var name = mae.Name.ToString();
                    exp.EnumMember = enumDefP.Members.Where(_ => _.Name == name).FirstOrDefault();
                    if (exp.EnumMember != null)
                    {
                        exp.Enum = enumDefP;
                        exp.Name = null;
                    }
                }
                else
                {
                    // 代替処理
                    if (propertySymbol != null)
                    {
                        exp.Property      = new PropertyDef();
                        exp.Property.Name = exp.Name;
                    }
                }

                if (exp.EnumMember != null)
                {
                    // enumのメンバーだった場合、親は必ずenumなのでこれ以上走査しない
                }
                else if (mae.Expression != null)
                {
                    exp.Expression = ParseExpression(mae.Expression, semanticModel);
                }

                return(exp);
            }
            else if (gns != null)
            {
                var symbol         = semanticModel.GetSymbolInfo(gns);
                var methodSymbol   = symbol.Symbol as IMethodSymbol;
                var fieldSymbol    = symbol.Symbol as IFieldSymbol;
                var propertySymbol = symbol.Symbol as IPropertySymbol;

                var exp = new GenericNameExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;


                exp.Name = gns.Identifier.ValueText;

                if (methodSymbol != null)
                {
                    exp.IsMethod = true;
                }

                if (propertySymbol != null)
                {
                    exp.IsProperty = true;
                }

                exp.Types = gns.TypeArgumentList.Arguments.Select(_ => ParseType(_, semanticModel)).ToArray();
                return(exp);
            }
            else if (le != null)
            {
                var text = le.GetText().ToString();
                var exp  = new LiteralExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;


                exp.Text = text;

                return(exp);
            }
            else if (ie != null)
            {
                var exp = new InvocationExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;


                exp.Method = ParseExpression(ie.Expression, semanticModel);
                exp.Args   = ie.ArgumentList.Arguments.Select(_ => ParseExpression(_.Expression, semanticModel)).ToArray();

                return(exp);
            }
            else if (oce != null)
            {
                var exp = new ObjectCreationExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                exp.Type = ParseType(oce.Type, semanticModel);

                if (oce.ArgumentList != null)
                {
                    exp.Args = oce.ArgumentList.Arguments.Select(_ => ParseExpression(_.Expression, semanticModel)).ToArray();
                }
                else
                {
                    exp.Args = new Expression[0];
                }

                return(exp);
            }
            else if (ce != null)
            {
                var exp = new CastExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                exp.Type       = ParseType(ce.Type, semanticModel);
                exp.Expression = ParseExpression(ce.Expression, semanticModel);
                return(exp);
            }
            else if (thise != null)
            {
                var exp = new ThisExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                return(exp);
            }
            else if (ae != null)
            {
                var exp = new AssignmentExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                if (ae.Kind() == SyntaxKind.AddAssignmentExpression)
                {
                    exp.Type = AssignmentExpression.OperatorType.Add;
                }
                if (ae.Kind() == SyntaxKind.SubtractAssignmentExpression)
                {
                    exp.Type = AssignmentExpression.OperatorType.Substract;
                }
                if (ae.Kind() == SyntaxKind.SimpleAssignmentExpression)
                {
                    exp.Type = AssignmentExpression.OperatorType.Simple;
                }
                if (ae.Kind() == SyntaxKind.DivideAssignmentExpression)
                {
                    exp.Type = AssignmentExpression.OperatorType.Divide;
                }
                if (ae.Kind() == SyntaxKind.ModuloAssignmentExpression)
                {
                    exp.Type = AssignmentExpression.OperatorType.Modulo;
                }

                exp.Temp       = ae.Kind();
                exp.Target     = ParseExpression(ae.Left, semanticModel);
                exp.Expression = ParseExpression(ae.Right, semanticModel);

                return(exp);
            }
            else if (pe != null)
            {
                // ()の構文
                return(ParseExpression(pe.Expression, semanticModel));
            }
            else if (ine != null)
            {
                var symbol         = semanticModel.GetSymbolInfo(ine);
                var methodSymbol   = symbol.Symbol as IMethodSymbol;
                var fieldSymbol    = symbol.Symbol as IFieldSymbol;
                var propertySymbol = symbol.Symbol as IPropertySymbol;

                var exp = new IdentifierNameExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                exp.Name = ine.Identifier.Text;

                if (selfTypeInfo?.Type != null)
                {
                    exp.Type = ParseType(selfTypeInfo.Value.Type);
                }

                if (methodSymbol != null)
                {
                    exp.IsMethod = true;
                }

                if (propertySymbol != null)
                {
                    exp.IsProperty = true;
                }

                return(exp);
            }
            else if (eae != null)
            {
                if (eae.ArgumentList.Arguments.Count() != 1)
                {
                    throw new ParseException("多次元配列は使用禁止です。");
                }

                var value_ = eae.Expression;

                var arg = eae.ArgumentList.Arguments[0].Expression;

                var exp = new ElementAccessExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                exp.Value = ParseExpression(value_, semanticModel);
                exp.Arg   = ParseExpression(arg, semanticModel);

                return(exp);
            }
            else if (be != null)
            {
                var exp = new BinaryExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                exp.Left  = ParseExpression(be.Left, semanticModel);
                exp.Right = ParseExpression(be.Right, semanticModel);

                if (be.Kind() == SyntaxKind.AddExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.Add;
                }
                if (be.Kind() == SyntaxKind.SubtractExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.Subtract;
                }
                if (be.Kind() == SyntaxKind.IsExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.Is;
                }
                if (be.Kind() == SyntaxKind.AsExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.As;
                }
                if (be.Kind() == SyntaxKind.EqualsExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.Equals;
                }
                if (be.Kind() == SyntaxKind.NotEqualsExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.NotEquals;
                }

                if (be.Kind() == SyntaxKind.LogicalAndExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.LogicalAnd;
                }
                if (be.Kind() == SyntaxKind.LogicalOrExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.LogicalOr;
                }

                if (be.Kind() == SyntaxKind.GreaterThanExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.GreaterThan;
                }
                if (be.Kind() == SyntaxKind.GreaterThanOrEqualExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.GreaterThanOrEqual;
                }

                if (be.Kind() == SyntaxKind.LessThanExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.LessThan;
                }
                if (be.Kind() == SyntaxKind.LessThanOrEqualExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.LessThanOrEqual;
                }

                if (be.Kind() == SyntaxKind.MultiplyExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.Multiply;
                }
                if (be.Kind() == SyntaxKind.DivideExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.Divide;
                }

                if (be.Kind() == SyntaxKind.ModuloExpression)
                {
                    exp.Operator = BinaryExpression.OperatorType.Modulo;
                }

                if (exp.Operator == BinaryExpression.OperatorType.None)
                {
                    var span_ = syntax.SyntaxTree.GetLineSpan(syntax.Span);
                    Console.WriteLine(string.Format("{0} : {1} には未対応です。", span_, be.Kind()));
                }

                return(exp);
            }
            else if (preue != null)
            {
                var exp = new PrefixUnaryExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                exp.Expression = ParseExpression(preue.Operand, semanticModel);

                switch (preue.Kind())
                {
                case SyntaxKind.LogicalNotExpression:
                    exp.Type = PrefixUnaryExpression.OperatorType.LogicalNot;
                    break;

                case SyntaxKind.UnaryPlusExpression:
                    exp.Type = PrefixUnaryExpression.OperatorType.UnaryPlus;
                    break;

                case SyntaxKind.UnaryMinusExpression:
                    exp.Type = PrefixUnaryExpression.OperatorType.UnaryMinus;
                    break;

                case SyntaxKind.PreIncrementExpression:
                    exp.Type = PrefixUnaryExpression.OperatorType.PreIncrement;
                    break;

                default:
                    throw new Exception();
                    break;
                }

                return(exp);
            }
            else if (poue != null)
            {
                var exp = new PostfixUnaryExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                exp.Operand = ParseExpression(poue.Operand, semanticModel);

                if (poue.Kind() == SyntaxKind.PostIncrementExpression)
                {
                    exp.Type = PostfixUnaryExpression.OperatorType.PostIncrement;
                }
                if (poue.Kind() == SyntaxKind.PostDecrementExpression)
                {
                    exp.Type = PostfixUnaryExpression.OperatorType.PostDecrement;
                }

                return(exp);
            }
            else if (basee != null)
            {
                var exp = new BaseExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                return(exp);
            }
            else if (iee != null)
            {
                var exp = new InitializerExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                var expressions = iee.Expressions.Select(_ => _).ToArray();
                exp.Expressions = expressions.Select(_ => ParseExpression(_, semanticModel)).ToArray();

                return(exp);
            }
            else if (ace != null || sace != null)
            {
                // stackallocも含め、配列の確保として扱う。

                ArrayTypeSyntax ats = null;
                if (ace != null)
                {
                    ats = ace.Type;
                }
                if (sace != null)
                {
                    ats = sace.Type as ArrayTypeSyntax;
                }

                var exp = new ObjectArrayCreationExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;

                exp.Type = ParseType(ats.ElementType, semanticModel);
                exp.Args = ats.RankSpecifiers.Select(_ => ParseExpression(_.Sizes.FirstOrDefault(), semanticModel)).ToArray();

                return(exp);
            }
            else if (syntax is PredefinedTypeSyntax)
            {
                var s   = syntax as PredefinedTypeSyntax;
                var exp = new TypeExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;
                return(exp);
            }
            else if (syntax is QualifiedNameSyntax)
            {
                var s = syntax as QualifiedNameSyntax;

                var exp = new TypeExpression();
                exp.SelfType = selfType;
                exp.Internal = syntax;
                return(exp);
            }

            var span = syntax.SyntaxTree.GetLineSpan(syntax.Span);

            Console.WriteLine(string.Format("{0} : {1} には未対応です。", span, syntax.GetType()));
            return(null);
        }