Esempio n. 1
0
        public override void ExitPrimaryExpr(GolangParser.PrimaryExprContext context)
        {
            // primaryExpr
            //     : operand
            //     | conversion
            //     | primaryExpr selector
            //     | primaryExpr index
            //     | primaryExpr slice
            //     | primaryExpr typeAssertion
            //     | primaryExpr arguments

            PrimaryExpressions.TryGetValue(context.primaryExpr(), out string primaryExpression);

            if (!string.IsNullOrEmpty(primaryExpression))
            {
                primaryExpression = SanitizedIdentifier(primaryExpression);
            }

            if (Operands.TryGetValue(context.operand(), out string operand))
            {
                PrimaryExpressions[context] = SanitizedIdentifier(operand);
            }
            else if (context.conversion() != null)
            {
                // conversion
                //     : type '(' expression ',' ? ')'

                if (Types.TryGetValue(context.conversion().type(), out TypeInfo typeInfo) && Expressions.TryGetValue(context.conversion().expression(), out string expression))
                {
                    if (typeInfo.TypeName.StartsWith("*(*"))
                    {
                        // TODO: Complex pointer expression needs special handling consideration - could opt for unsafe implementation
                        PrimaryExpressions[context] = $"{typeInfo.TypeName}{expression}";
                    }
                    else
                    {
                        if (typeInfo.IsPointer)
                        {
                            PrimaryExpressions[context] = $"new Ptr<{typeInfo.TypeName}>({expression})";
                        }
                        else if (typeInfo.TypeClass == TypeClass.Struct)
                        {
                            PrimaryExpressions[context] = $"{typeInfo.TypeName}_cast({expression})";
                        }
                        else if (typeInfo.TypeClass == TypeClass.Simple)
                        {
                            PrimaryExpressions[context] = $"{typeInfo.TypeName}({expression})";
                        }
                        else
                        {
                            PrimaryExpressions[context] = $"({typeInfo.TypeName}){expression}";
                        }
                    }
                }
                else
                {
                    AddWarning(context, $"Failed to find type or sub-expression for the conversion expression in \"{context.GetText()}\"");
                }
            }
            else if (context.selector() != null)
            {
                // selector
                //     : '.' IDENTIFIER

                PrimaryExpressions[context] = $"{primaryExpression}.{SanitizedIdentifier(context.selector().IDENTIFIER().GetText())}";
            }
            else if (context.index() != null)
            {
                // index
                //     : '[' expression ']'

                if (Expressions.TryGetValue(context.index().expression(), out string expression))
                {
                    PrimaryExpressions[context] = $"{primaryExpression}[{expression}]";
                }
                else
                {
                    AddWarning(context, $"Failed to find index expression for \"{context.GetText()}\"");
                }
            }
            else if (context.slice() != null)
            {
                // slice
                //     : '['((expression ? ':' expression ? ) | (expression ? ':' expression ':' expression)) ']'

                GolangParser.SliceContext sliceContext = context.slice();

                if (sliceContext.children.Count == 3)
                {
                    // primaryExpr[:]
                    PrimaryExpressions[context] = $"{primaryExpression}.slice()";
                }
                else if (sliceContext.children.Count == 4)
                {
                    bool expressionIsLeft = sliceContext.children[1] is GolangParser.ExpressionContext;

                    // primaryExpr[low:] or primaryExpr[:high]
                    if (Expressions.TryGetValue(sliceContext.expression(0), out string expression))
                    {
                        PrimaryExpressions[context] = $"{primaryExpression}.slice({(expressionIsLeft ? expression : $"high:{expression}")})";
                    }
                    else
                    {
                        AddWarning(context, $"Failed to find slice expression for \"{context.GetText()}\"");
                    }
                }
                else if (sliceContext.children.Count == 5)
                {
                    if (sliceContext.children[1] is GolangParser.ExpressionContext && sliceContext.children[3] is GolangParser.ExpressionContext)
                    {
                        // primaryExpr[low:high]
                        if (Expressions.TryGetValue(sliceContext.expression(0), out string lowExpression) && Expressions.TryGetValue(sliceContext.expression(1), out string highExpression))
                        {
                            PrimaryExpressions[context] = $"{primaryExpression}.slice({lowExpression}, {highExpression})";
                        }
                        else
                        {
                            AddWarning(context, $"Failed to find one of the slice expressions for \"{context.GetText()}\"");
                        }
                    }
                    else
                    {
                        AddWarning(context, $"Failed to find slice expression for \"{context.GetText()}\"");
                    }
                }
                else if (sliceContext.children.Count == 6)
                {
                    // primaryExpr[:high:max]
                    if (Expressions.TryGetValue(sliceContext.expression(0), out string highExpression) && Expressions.TryGetValue(sliceContext.expression(1), out string maxExpression))
                    {
                        PrimaryExpressions[context] = $"{primaryExpression}.slice(-1, {highExpression}, {maxExpression})";
                    }
                    else
                    {
                        AddWarning(context, $"Failed to find one of the slice expressions for \"{context.GetText()}\"");
                    }
                }
                else if (sliceContext.children.Count == 7)
                {
                    // primaryExpr[low:high:max]
                    if (Expressions.TryGetValue(sliceContext.expression(0), out string lowExpression) && Expressions.TryGetValue(sliceContext.expression(1), out string highExpression) && Expressions.TryGetValue(sliceContext.expression(2), out string maxExpression))
                    {
                        PrimaryExpressions[context] = $"{primaryExpression}.slice({lowExpression}, {highExpression}, {maxExpression})";
                    }
                    else
                    {
                        AddWarning(context, $"Failed to find one of the slice expressions for \"{context.GetText()}\"");
                    }
                }
            }
            else if (context.typeAssertion() != null)
            {
                // typeAssertion
                //     : '.' '(' type ')'

                if (Types.TryGetValue(context.typeAssertion().type(), out TypeInfo typeInfo))
                {
                    PrimaryExpressions[context] = $"{primaryExpression}.TypeAssert<{typeInfo.TypeName}>()";
                }
                else
                {
                    AddWarning(context, $"Failed to find type for the type assertion expression in \"{context.GetText()}\"");
                }
            }
            else if (context.arguments() != null)
            {
                // arguments
                //     : '('((expressionList | type(',' expressionList) ? ) '...' ? ',' ? ) ? ')'

                GolangParser.ArgumentsContext argumentsContext = context.arguments();
                List <string> arguments = new List <string>();

                if (Types.TryGetValue(argumentsContext.type(), out TypeInfo typeInfo))
                {
                    arguments.Add($"typeof({typeInfo.TypeName})");
                }

                if (ExpressionLists.TryGetValue(argumentsContext.expressionList(), out string[] expressions))
Esempio n. 2
0
 public override Base VisitArguments([NotNull] GolangParser.ArgumentsContext context)
 {
     return(base.VisitArguments(context));
 }