public override void ExitMethodDecl(GolangParser.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); }
public override void ExitMethodDecl(GolangParser.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.function()?.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)); }