public override void EnterFunctionDecl(GoParser.FunctionDeclContext context)
        {
            m_inFunction           = true; // May need to scope certain objects, like consts, to current function
            m_originalFunctionName = context.IDENTIFIER().GetText();
            m_currentFunctionName  = SanitizedIdentifier(m_originalFunctionName);

            string scope = char.IsUpper(m_originalFunctionName[0]) ? "public" : "private";

            // Handle Go "main" function as a special case, in C# this should be capitalized "Main"
            if (m_currentFunctionName.Equals("main"))
            {
                m_currentFunctionName = "Main";

                // Track file names that contain main function in main package
                if (Package.Equals("main"))
                {
                    s_mainPackageFiles.Add(TargetFileName);
                }
            }

            // Function signature containing result type and parameters have not been visited yet,
            // so we mark their desired positions and replace once the visit has occurred
            m_functionResultTypeMarker  = string.Format(FunctionResultTypeMarker, m_currentFunctionName);
            m_functionParametersMarker  = string.Format(FunctionParametersMarker, m_currentFunctionName);
            m_functionExecContextMarker = string.Format(FunctionExecContextMarker, m_currentFunctionName);
            PushInnerBlockPrefix(string.Format(FunctionBlockPrefixMarker, m_currentFunctionName));

            m_targetFile.AppendLine($"{Spacing()}{scope} static {m_functionResultTypeMarker} {m_currentFunctionName}{m_functionParametersMarker}{m_functionExecContextMarker}");
        }
Beispiel #2
0
 public override void ExitFunctionDecl(GoParser.FunctionDeclContext context)
 {
     CurrentFunction      = null;
     CurrentFunctionName  = null;
     OriginalFunctionName = null;
     InFunction           = false;
 }
Beispiel #3
0
        public override void EnterFunctionDecl(GoParser.FunctionDeclContext context)
        {
            InFunction           = true;
            OriginalFunctionName = context.IDENTIFIER()?.GetText() ?? "_";
            CurrentFunctionName  = SanitizedIdentifier(OriginalFunctionName);

            string functionSignature = FunctionSignature.Generate(OriginalFunctionName);

            FunctionInfo currentFunction = null;

            Metadata?.Functions.TryGetValue(functionSignature, out currentFunction);
            CurrentFunction = currentFunction;
        }
Beispiel #4
0
        public override void ExitFunctionDecl(GoParser.FunctionDeclContext context)
        {
            FunctionInfo functionInfo = ExitMethod(context);

            if (functionInfo is null)
            {
                return;
            }

            m_functions.Add(GetUniqueIdentifier(m_functions, functionInfo.Signature.GenerateLookup()), functionInfo);

            base.ExitFunctionDecl(context);
        }
        public override void EnterFunctionDecl(GoParser.FunctionDeclContext context)
        {
            m_inFunction           = true; // May need to scope certain objects, like consts, to current function
            m_originalFunctionName = context.IDENTIFIER().GetText();
            m_currentFunctionName  = SanitizedIdentifier(m_originalFunctionName);
            m_variableIdentifiers.Clear();
            m_variableTypes.Clear();

            string functionSignature = FunctionSignature.Generate(m_originalFunctionName);

            if (!Metadata.Functions.TryGetValue(functionSignature, out m_currentFunction))
            {
                throw new InvalidOperationException($"Failed to find metadata for method function \"{functionSignature}\".");
            }

            FunctionSignature function = m_currentFunction.Signature;

            if (function is null)
            {
                throw new InvalidOperationException($"Failed to find signature metadata for function \"{m_currentFunctionName}\".");
            }

            string scope = char.IsUpper(m_originalFunctionName[0]) ? "public" : "private";

            // Handle Go "main" function as a special case, in C# this should be capitalized "Main"
            if (m_currentFunctionName.Equals("main"))
            {
                m_currentFunctionName = "Main";

                // Track file names that contain main function in main package
                if (Package.Equals("main"))
                {
                    s_mainPackageFiles.Add(TargetFileName);
                }
            }

            // Function signature containing result type and parameters have not been visited yet,
            // so we mark their desired positions and replace once the visit has occurred
            m_functionResultTypeMarker  = string.Format(FunctionResultTypeMarker, m_currentFunctionName);
            m_functionParametersMarker  = string.Format(FunctionParametersMarker, m_currentFunctionName);
            m_functionExecContextMarker = string.Format(FunctionExecContextMarker, m_currentFunctionName);
            PushInnerBlockPrefix(string.Format(FunctionBlockPrefixMarker, m_currentFunctionName));

            m_targetFile.AppendLine($"{Spacing()}{scope} static {m_functionResultTypeMarker} {m_currentFunctionName}{m_functionParametersMarker}{m_functionExecContextMarker}");
        }
Beispiel #6
0
        public override void EnterFunctionDecl(GoParser.FunctionDeclContext context)
        {
            base.EnterFunctionDecl(context);

            m_variableIdentifiers.Clear();
            m_variableTypes.Clear();

            if (CurrentFunction is null)
            {
                throw new InvalidOperationException($"Failed to find metadata for function \"{CurrentFunctionName}\".");
            }

            FunctionSignature function = CurrentFunction.Signature;

            if (function is null)
            {
                throw new InvalidOperationException($"Failed to find signature metadata for function \"{CurrentFunctionName}\".");
            }

            string scope = char.IsUpper(OriginalFunctionName[0]) ? "public" : "private";

            // Handle Go "main" function as a special case, in C# this should be capitalized "Main"
            if (CurrentFunctionName.Equals("main"))
            {
                CurrentFunctionName = "Main";

                // Track file names that contain main function in main package
                if (Package.Equals("main"))
                {
                    s_mainPackageFiles.Add(TargetFileName);
                }
            }

            // Function signature containing result type and parameters have not been visited yet,
            // so we mark their desired positions and replace once the visit has occurred
            m_functionResultTypeMarker  = string.Format(FunctionResultTypeMarker, CurrentFunctionName);
            m_functionParametersMarker  = string.Format(FunctionParametersMarker, CurrentFunctionName);
            m_functionExecContextMarker = string.Format(FunctionExecContextMarker, CurrentFunctionName);
            PushInnerBlockPrefix(string.Format(FunctionBlockPrefixMarker, CurrentFunctionName));

            m_targetFile.AppendLine($"{Spacing()}{scope} static {m_functionResultTypeMarker} {CurrentFunctionName}{m_functionParametersMarker}{m_functionExecContextMarker}");
        }
        public override void ExitFunctionDecl(GoParser.FunctionDeclContext context)
        {
            bool signatureOnly = false;

            if (Parameters.TryGetValue(context.signature()?.parameters(), out List <ParameterInfo> parameters) && (object)parameters != null)
            {
                signatureOnly = true;
            }
            else if (!Parameters.TryGetValue(context.signature()?.parameters(), out parameters) || (object)parameters == null)
            {
                parameters = new List <ParameterInfo>();
            }

            string functionSignature = FunctionSignature.Generate(m_originalFunctionName, parameters);

            if (!Metadata.Functions.TryGetValue(functionSignature, out m_currentFunction))
            {
                throw new InvalidOperationException($"Failed to find metadata for method function \"{functionSignature}\".");
            }

            FunctionSignature function = m_currentFunction.Signature;

            if ((object)function == null)
            {
                throw new InvalidOperationException($"Failed to find signature metadata for function \"{m_currentFunctionName}\".");
            }

            bool      hasDefer   = m_currentFunction.HasDefer;
            bool      hasPanic   = m_currentFunction.HasPanic;
            bool      hasRecover = m_currentFunction.HasRecover;
            bool      useFuncExecutionContext = hasDefer || hasPanic || hasRecover;
            Signature signature           = function.Signature;
            string    parametersSignature = $"({signature.GenerateParametersSignature(useFuncExecutionContext)})";
            string    resultSignature     = signature.GenerateResultSignature();

            // Replace function markers
            m_targetFile.Replace(m_functionResultTypeMarker, resultSignature);
            m_targetFile.Replace(m_functionParametersMarker, parametersSignature);

            if (useFuncExecutionContext)
            {
                string[] funcExecContextByRefParams = signature.GetByRefParameters(false).ToArray();

                if (funcExecContextByRefParams.Length > 0)
                {
                    string[] lambdaByRefParameters = signature.GetByRefParameters(true).ToArray();

                    m_targetFile.Replace(m_functionExecContextMarker, $" => func({string.Join(", ", funcExecContextByRefParams)}, ({string.Join(", ", lambdaByRefParameters)}, Defer {(hasDefer ? "defer" : "_")}, Panic {(hasPanic ? "panic" : "_")}, Recover {(hasRecover ? "recover" : "_")}) =>");
                }
                else
                {
                    m_targetFile.Replace(m_functionExecContextMarker, $" => func(({(hasDefer ? "defer" : "_")}, {(hasPanic ? "panic" : "_")}, {(hasRecover ? "recover" : "_")}) =>");
                }
            }
            else
            {
                m_targetFile.Replace(m_functionExecContextMarker, "");
            }

            string blockPrefix = "";

            if (!signatureOnly)
            {
                // For any array parameters, Go copies the array by value
                StringBuilder arrayClones = new StringBuilder();

                foreach (ParameterInfo parameter in signature.Parameters)
                {
                    if (parameter.Type.TypeClass == TypeClass.Array)
                    {
                        arrayClones.AppendLine($"{Spacing(1)}{parameter.Name} = {parameter.Name}.Clone();");
                    }
                }

                if (arrayClones.Length > 0)
                {
                    arrayClones.Insert(0, Environment.NewLine);
                    blockPrefix = arrayClones.ToString();
                }
            }

            m_targetFile.Replace(string.Format(FunctionBlockPrefixMarker, m_currentFunctionName), blockPrefix);

            m_currentFunction      = null;
            m_currentFunctionName  = null;
            m_originalFunctionName = null;
            m_inFunction           = false;

            if (useFuncExecutionContext)
            {
                m_targetFile.Append(");");
            }
            else if (signatureOnly)
            {
                m_targetFile.Append(";");
            }

            m_targetFile.Append(CheckForCommentsRight(context));
        }
        public override void ExitFunctionDecl(GoParser.FunctionDeclContext context)
        {
            FunctionInfo functionInfo = ExitMethod(context);

            m_functions.Add(GetUniqueIdentifier(m_functions, functionInfo.Signature.Generate()), functionInfo);
        }
 public override void EnterFunctionDecl(GoParser.FunctionDeclContext context)
 {
     EnterMethod();
 }
Beispiel #10
0
        public override void ExitFunctionDecl(GoParser.FunctionDeclContext context)
        {
            bool signatureOnly = context.block() is null;

            FunctionSignature function        = CurrentFunction.Signature;
            bool      hasDefer                = CurrentFunction.HasDefer;
            bool      hasPanic                = CurrentFunction.HasPanic;
            bool      hasRecover              = CurrentFunction.HasRecover;
            bool      useFuncExecutionContext = hasDefer || hasPanic || hasRecover;
            Signature signature               = function.Signature;
            string    parametersSignature     = $"({signature.GenerateParametersSignature()})";
            string    resultSignature         = signature.GenerateResultSignature();
            string    blockPrefix             = "";

            if (!signatureOnly)
            {
                StringBuilder resultParameters = new StringBuilder();
                StringBuilder arrayClones      = new StringBuilder();
                StringBuilder implicitPointers = new StringBuilder();

                foreach (ParameterInfo parameter in signature.Result)
                {
                    if (!string.IsNullOrEmpty(parameter.Name))
                    {
                        resultParameters.AppendLine($"{Spacing(1)}{parameter.Type.TypeName} {parameter.Name} = default{(parameter.Type is PointerTypeInfo || parameter.Type.TypeClass == TypeClass.Interface ? "!" : "")};");
                    }
                }

                foreach (ParameterInfo parameter in signature.Parameters)
                {
                    // For any array parameters, Go copies the array by value
                    if (parameter.Type.TypeClass == TypeClass.Array)
                    {
                        arrayClones.AppendLine($"{Spacing(1)}{parameter.Name} = {parameter.Name}.Clone();");
                    }

                    // All pointers in Go can be implicitly dereferenced, so setup a "local ref" instance to each
                    if (parameter.Type is PointerTypeInfo pointer)
                    {
                        implicitPointers.AppendLine($"{Spacing(1)}ref {pointer.TargetTypeInfo.TypeName} {parameter.Name} = ref {AddressPrefix}{parameter.Name}.val;");
                    }
                }

                if (resultParameters.Length > 0)
                {
                    resultParameters.Insert(0, Environment.NewLine);
                    blockPrefix += resultParameters.ToString();
                }

                if (arrayClones.Length > 0)
                {
                    if (blockPrefix.Length == 0)
                    {
                        arrayClones.Insert(0, Environment.NewLine);
                    }

                    blockPrefix += arrayClones.ToString();
                }

                if (implicitPointers.Length > 0)
                {
                    if (blockPrefix.Length == 0)
                    {
                        implicitPointers.Insert(0, Environment.NewLine);
                    }

                    blockPrefix += implicitPointers.ToString();

                    StringBuilder updatedSignature = new StringBuilder();
                    bool          initialParam     = true;

                    foreach (ParameterInfo parameter in signature.Parameters)
                    {
                        if (!initialParam)
                        {
                            updatedSignature.Append(", ");
                        }

                        initialParam = false;
                        updatedSignature.Append($"{(parameter.IsVariadic ? "params " : "")}{parameter.Type.TypeName} ");

                        if (parameter.Type is PointerTypeInfo)
                        {
                            updatedSignature.Append(AddressPrefix);
                        }

                        updatedSignature.Append(parameter.Name);
                    }

                    parametersSignature = $"({updatedSignature})";
                }
            }

            // Replace function markers
            m_targetFile.Replace(m_functionResultTypeMarker, resultSignature);
            m_targetFile.Replace(m_functionParametersMarker, parametersSignature);

            if (useFuncExecutionContext)
            {
                Stack <string> unusedNames = new Stack <string>(new[] { "__", "_" });
                m_targetFile.Replace(m_functionExecContextMarker, $" => func(({(hasDefer ? "defer" : unusedNames.Pop())}, {(hasPanic ? "panic" : unusedNames.Pop())}, {(hasRecover ? "recover" : unusedNames.Pop())}) =>");
            }
            else
            {
                m_targetFile.Replace(m_functionExecContextMarker, "");
            }

            m_targetFile.Replace(string.Format(FunctionBlockPrefixMarker, CurrentFunctionName), blockPrefix);

            if (useFuncExecutionContext)
            {
                m_targetFile.Append(");");
            }
            else if (signatureOnly)
            {
                m_targetFile.Append(";");
            }

            m_targetFile.Append(CheckForCommentsRight(context));

            base.ExitFunctionDecl(context);
        }
        public override void ExitFunctionDecl(GoParser.FunctionDeclContext context)
        {
            bool signatureOnly = context.block() is null;

            FunctionSignature function        = m_currentFunction.Signature;
            bool      hasDefer                = m_currentFunction.HasDefer;
            bool      hasPanic                = m_currentFunction.HasPanic;
            bool      hasRecover              = m_currentFunction.HasRecover;
            bool      useFuncExecutionContext = hasDefer || hasPanic || hasRecover;
            Signature signature               = function.Signature;
            string    parametersSignature     = $"({signature.GenerateParametersSignature(useFuncExecutionContext)})";
            string    resultSignature         = signature.GenerateResultSignature();

            // Replace function markers
            m_targetFile.Replace(m_functionResultTypeMarker, resultSignature);
            m_targetFile.Replace(m_functionParametersMarker, parametersSignature);

            if (useFuncExecutionContext)
            {
                string[]       funcExecContextByRefParams = signature.GetByRefParameters(false).ToArray();
                Stack <string> unusedNames = new Stack <string>(new[] { "__", "_" });

                if (funcExecContextByRefParams.Length > 0)
                {
                    string[] lambdaByRefParameters = signature.GetByRefParameters(true).ToArray();
                    m_targetFile.Replace(m_functionExecContextMarker, $" => func({string.Join(", ", funcExecContextByRefParams)}, ({string.Join(", ", lambdaByRefParameters)}, Defer {(hasDefer ? "defer" : unusedNames.Pop())}, Panic {(hasPanic ? "panic" : unusedNames.Pop())}, Recover {(hasRecover ? "recover" : unusedNames.Pop())}) =>");
                }
                else
                {
                    m_targetFile.Replace(m_functionExecContextMarker, $" => func(({(hasDefer ? "defer" : unusedNames.Pop())}, {(hasPanic ? "panic" : unusedNames.Pop())}, {(hasRecover ? "recover" : unusedNames.Pop())}) =>");
                }
            }
            else
            {
                m_targetFile.Replace(m_functionExecContextMarker, "");
            }

            string blockPrefix = "";

            if (!signatureOnly)
            {
                // TODO: Double check if any other types need clone-type copy operations
                // For any array parameters, Go copies the array by value
                StringBuilder arrayClones = new StringBuilder();

                foreach (ParameterInfo parameter in signature.Parameters)
                {
                    if (parameter.Type.TypeClass == TypeClass.Array)
                    {
                        arrayClones.AppendLine($"{Spacing(1)}{parameter.Name} = {parameter.Name}.Clone();");
                    }
                }

                if (arrayClones.Length > 0)
                {
                    arrayClones.Insert(0, Environment.NewLine);
                    blockPrefix = arrayClones.ToString();
                }
            }

            m_targetFile.Replace(string.Format(FunctionBlockPrefixMarker, m_currentFunctionName), blockPrefix);

            m_currentFunction      = null;
            m_currentFunctionName  = null;
            m_originalFunctionName = null;
            m_inFunction           = false;

            if (useFuncExecutionContext)
            {
                m_targetFile.Append(");");
            }
            else if (signatureOnly)
            {
                m_targetFile.Append(";");
            }

            m_targetFile.Append(CheckForCommentsRight(context));
        }