Exemple #1
0
 public override void ExitMethodDecl(GoParser.MethodDeclContext context)
 {
     CurrentFunction      = null;
     CurrentFunctionName  = null;
     OriginalFunctionName = null;
     InFunction           = false;
 }
Exemple #2
0
        public override void EnterMethodDecl(GoParser.MethodDeclContext context)
        {
            InFunction           = true;
            OriginalFunctionName = context.IDENTIFIER()?.GetText() ?? "_";
            CurrentFunctionName  = SanitizedIdentifier(OriginalFunctionName);

            GoParser.ParameterDeclContext[] receiverParameters = context.receiver().parameters().parameterDecl();
            string receiverTypeName;

            if (receiverParameters.Length > 0)
            {
                receiverTypeName = receiverParameters[0].type_().GetText();

                // Receiver does not need to handle pointer-to-pointer look ups
                if (receiverTypeName.StartsWith("*"))
                {
                    receiverTypeName = $"ptr<{receiverTypeName.Substring(1)}>";
                }
            }
            else
            {
                receiverTypeName = "object";
            }

            string functionSignature = FunctionSignature.Generate(OriginalFunctionName, new[] { receiverTypeName });

            FunctionInfo currentFunction = null;

            Metadata?.Functions.TryGetValue(functionSignature, out currentFunction);
            CurrentFunction = currentFunction;
        }
        public override void ExitMethodDecl(GoParser.MethodDeclContext context)
        {
            FunctionInfo functionInfo = ExitMethod(context);

            if (Parameters.TryGetValue(context.receiver().parameters(), out List <ParameterInfo> parameters))
            {
                functionInfo.Signature = new MethodSignature(functionInfo.Signature)
                {
                    ReceiverParameters = parameters.ToArray()
                };
            }

            m_functions.Add(GetUniqueIdentifier(m_functions, functionInfo.Signature.Generate()), functionInfo);
        }
Exemple #4
0
        public override void EnterMethodDecl(GoParser.MethodDeclContext 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);

            // 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);

            m_targetFile.AppendLine($"{Spacing()}{m_functionResultTypeMarker} {m_currentFunctionName}{m_functionParametersMarker}{m_functionExecContextMarker}");
        }
Exemple #5
0
        public override void EnterMethodDecl(GoParser.MethodDeclContext context)
        {
            base.EnterMethodDecl(context);

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


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

            // 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()}{m_functionResultTypeMarker} {CurrentFunctionName}{m_functionParametersMarker}{m_functionExecContextMarker}");
        }
        public override void EnterMethodDecl(GoParser.MethodDeclContext 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 receiverTypeName  = context.receiver().parameters().parameterDecl()[0].type_().GetText().Replace("*", "ref ");
            string functionSignature = FunctionSignature.Generate(m_originalFunctionName, new[] { receiverTypeName });

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

            // 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);

            m_targetFile.AppendLine($"{Spacing()}{m_functionResultTypeMarker} {m_currentFunctionName}{m_functionParametersMarker}{m_functionExecContextMarker}");
        }
        public override void ExitMethodDecl(GoParser.MethodDeclContext context)
        {
            if (!(m_currentFunction.Signature is MethodSignature method))
            {
                throw new InvalidOperationException($"Failed to find signature metadata for method 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 = method.Signature;
            string    receiverParametersSignature = method.GenerateReceiverParametersSignature(useFuncExecutionContext);
            string    parametersSignature         = signature.GenerateParametersSignature(useFuncExecutionContext);
            string    resultSignature             = signature.GenerateResultSignature();

            if (signature.Parameters.Length == 0)
            {
                parametersSignature = $"({receiverParametersSignature})";
            }
            else
            {
                parametersSignature = $"({receiverParametersSignature}, {parametersSignature})";
            }

            // Scope of an extension function is based on scope of the receiver type
            string scope = char.IsUpper(method.ReceiverParameters[0].Type.TypeName[0]) ? "public" : "private";

            resultSignature = $"{scope} static {resultSignature}";

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

            if (useFuncExecutionContext)
            {
                List <string>  funcExecContextByRefParams = new List <string>(method.GetByRefReceiverParameters(false));
                Stack <string> unusedNames = new Stack <string>(new[] { "__", "_" });

                funcExecContextByRefParams.AddRange(signature.GetByRefParameters(false));

                if (funcExecContextByRefParams.Count > 0)
                {
                    List <string> lambdaByRefParameters = new List <string>(method.GetByRefReceiverParameters(true));

                    lambdaByRefParameters.AddRange(signature.GetByRefParameters(true));

                    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, "");
            }

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

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

            m_targetFile.Append(CheckForCommentsRight(context));
        }
 public override void EnterMethodDecl(GoParser.MethodDeclContext context)
 {
     EnterMethod();
 }
Exemple #9
0
        public override void ExitMethodDecl(GoParser.MethodDeclContext context)
        {
            if (!(CurrentFunction.Signature is MethodSignature method))
            {
                throw new InvalidOperationException($"Failed to find signature metadata for method function \"{CurrentFunctionName}\".");
            }

            bool      hasDefer   = CurrentFunction.HasDefer;
            bool      hasPanic   = CurrentFunction.HasPanic;
            bool      hasRecover = CurrentFunction.HasRecover;
            bool      useFuncExecutionContext = hasDefer || hasPanic || hasRecover;
            Signature signature = method.Signature;
            string    receiverParametersSignature = method.GenerateReceiverParametersSignature();
            string    parametersSignature         = signature.GenerateParametersSignature();
            string    resultSignature             = signature.GenerateResultSignature();

            ParameterInfo[] receiverParameters = method.ReceiverParameters ?? Array.Empty <ParameterInfo>();

            if (signature.Parameters.Length == 0)
            {
                parametersSignature = $"({receiverParametersSignature})";
            }
            else
            {
                parametersSignature = $"({receiverParametersSignature}, {parametersSignature})";
            }

            // Scope of an extension function is based on scope of the receiver type
            string receiverType = receiverParameters.Length > 0 ? receiverParameters[0].Type.TypeName : "object";
            string scope        = char.IsUpper(receiverType[0]) ? "public" : "private";

            resultSignature = $"{scope} static {resultSignature}";
            string blockPrefix = "";

            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 receiverParameters.Concat(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 receiverParameters.Concat(signature.Parameters))
                {
                    if (initialParam)
                    {
                        updatedSignature.Append("this ");
                    }
                    else
                    {
                        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(");");
            }

            m_targetFile.Append(CheckForCommentsRight(context));

            base.ExitMethodDecl(context);
        }
Exemple #10
0
        public override void ExitMethodDecl(GoParser.MethodDeclContext context)
        {
            bool signatureOnly = false;

            if (!Parameters.TryGetValue(context.receiver()?.parameters(), out List <ParameterInfo> receiverParameters) || (object)receiverParameters == null)
            {
                receiverParameters = new List <ParameterInfo>();
            }

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

            IEnumerable <ParameterInfo> parameters = receiverParameters.Concat(functionParameters);

            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}\".");
            }

            MethodSignature method = m_currentFunction.Signature as MethodSignature;

            if ((object)method == null)
            {
                throw new InvalidOperationException($"Failed to find signature metadata for method 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 = method.Signature;
            string    receiverParametersSignature = method.GenerateReceiverParametersSignature(useFuncExecutionContext);
            string    parametersSignature         = signature.GenerateParametersSignature(useFuncExecutionContext);
            string    resultSignature             = signature.GenerateResultSignature();

            if (signature.Parameters.Length == 0)
            {
                parametersSignature = $"({receiverParametersSignature})";
            }
            else
            {
                parametersSignature = $"({receiverParametersSignature}, {parametersSignature})";
            }

            // Scope of an extension function is based on scope of the receiver type
            string scope = char.IsUpper(method.ReceiverParameters[0].Type.TypeName[0]) ? "public" : "private";

            resultSignature = $"{scope} static {resultSignature}";

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

            if (useFuncExecutionContext)
            {
                List <string> funcExecContextByRefParams = new List <string>(method.GetByRefReceiverParameters(false));

                funcExecContextByRefParams.AddRange(signature.GetByRefParameters(false));

                if (funcExecContextByRefParams.Count > 0)
                {
                    List <string> lambdaByRefParameters = new List <string>(method.GetByRefReceiverParameters(true));

                    lambdaByRefParameters.AddRange(signature.GetByRefParameters(true));

                    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, "");
            }

            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));
        }