/// <summary> /// Promotes types of arguments to match signature if possible. /// </summary> /// <param name="signature">The signature to match the types to.</param> /// <param name="argumentNodes">The types to promote.</param> internal static void TypePromoteArguments(FunctionSignature signature, List<QueryNode> argumentNodes) { // Convert all argument nodes to the best signature argument type Debug.Assert(signature.ArgumentTypes.Length == argumentNodes.Count, "The best signature match doesn't have the same number of arguments."); for (int i = 0; i < argumentNodes.Count; i++) { Debug.Assert(argumentNodes[i] is SingleValueNode, "We should have already verified that all arguments are single values."); SingleValueNode argumentNode = (SingleValueNode)argumentNodes[i]; IEdmTypeReference signatureArgumentType = signature.ArgumentTypes[i]; Debug.Assert(signatureArgumentType.IsODataPrimitiveTypeKind(), "Only primitive types should be able to get here."); argumentNodes[i] = MetadataBindingUtils.ConvertToTypeIfNeeded(argumentNode, signatureArgumentType); } }
public void FinalizeGeneration() { TypeBuilder.CreateType(); FunctionSignature main = new FunctionSignature(); main.Ident = "Main"; main.ParamList = new List<VariableNode>(); main.ReturnType = "Void"; if (!FunctionTable.Keys.Contains(main)) { ErrorHandler.RaiseError(new Error(0, "No Main function found.")); return; } Console.WriteLine("Code generation successful; finalizing types.."); AsmBuilder.SetEntryPoint(FunctionTable[main]); AsmBuilder.Save(path); Console.WriteLine("Compilation successful! Program can be found at {0}", path); }
public void ValidateFunctionBindingArguments_ReturnBinding_Succeeds() { Collection <FunctionParameter> parameters = new Collection <FunctionParameter>() { new FunctionParameter("input", "String", false, RefKind.None) }; FunctionSignature signature = new FunctionSignature("Test", "Test", ImmutableArray.CreateRange <FunctionParameter>(parameters), "Test", false); var host = new HostBuilder().ConfigureDefaultTestWebScriptHost(b => { b.AddAzureStorage(); }).Build(); Collection <FunctionBinding> inputBindings = new Collection <FunctionBinding>() { TestHelpers.CreateBindingFromHost(host, new JObject { { "type", "blobTrigger" }, { "name", "input" }, { "direction", "in" }, { "path", "test" } }) }; Collection <FunctionBinding> outputBindings = new Collection <FunctionBinding>() { TestHelpers.CreateBindingFromHost(host, new JObject { { "type", "blob" }, { "name", ScriptConstants.SystemReturnParameterBindingName }, { "direction", "out" }, { "path", "test/test" } }) }; var diagnostics = DotNetFunctionInvoker.ValidateFunctionBindingArguments(signature, "input", inputBindings, outputBindings); Assert.Equal(0, diagnostics.Count()); }
private static Node GetRegisterServer(string typeName) { var logParamName = "log"; var func = FunctionSignature.Generate(null, "RegisterServer", new[] { new FuncParamSig(logParamName, TypeModifier.ByReference, "log.Logger") }, null); var funcBody = new OpenDelimiter(BinaryDelimiterType.Brace); funcBody.AddChild(BinaryOpSequence.Generate(BinaryOperatorType.Assignment, new Identifier(LoggerVarName), new Identifier(logParamName))); funcBody.AddChild(new Terminal()); funcBody.AddChild(FunctionCall.Generate("rpc.Register", new[] { new FuncCallParam(StructLiteral.Generate(typeName, null), TypeModifier.ByReference) })); funcBody.AddClosingDelimiter(); func.AddChild(funcBody); return(func); }
public void FunctionSignatureKnowsHowToParseRetardedSignatures() { //function retarded_func(b: strings = "thing","", c: integer) :: string var ctx = ParseContext.FromCode( "function retarded_func(b: strings = \"thing\",\"\", c: integer) :: string"); var signature = FunctionSignature.TryParse(ctx); Assert.NotNull(signature); Assert.Equal(2, signature.Parameters.Count); var firstParam = signature.Parameters[0]; Assert.Equal("b", firstParam.Name); Assert.Equal("strings", firstParam.Type.FinalTypeName); Assert.Equal("thing", firstParam.DefaultValue.GetExplicitValue <string>(0).GenericValue); Assert.Equal(string.Empty, firstParam.DefaultValue.GetExplicitValue <string>(1).GenericValue); var secondParam = signature.Parameters[1]; Assert.Equal("c", secondParam.Name); Assert.Equal("integer", secondParam.Type.FinalTypeName); }
/// <inheritdoc/> public IEnumerable <FunctionSignature> CreateOverloads(FunctionSignature function) { var arrayParameter = function.Parameters.Last(); var arrayParameterType = arrayParameter.Type; var newName = function.Name.Singularize(false); var newParameters = SkipLastExtension.SkipLast(new List <ParameterSignature>(function.Parameters), 2).ToList(); var newArrayParameterType = new TypeSignatureBuilder(arrayParameterType) .WithArrayDimensions(0) .WithIndirectionLevel(0) .Build(); var newArrayParameter = new ParameterSignatureBuilder(arrayParameter) .WithType(newArrayParameterType) .Build(); newParameters.Add(newArrayParameter); yield return(new FunctionSignatureBuilder(function) .WithName(newName) .WithParameters(newParameters) .Build()); }
public FunctionSignature GetEntryPointSignature(IFunctionEntryPointResolver entryPointResolver) { EnsureAssemblyOption(); // Scrape the compiled assembly for entry points IList<MethodReference<MethodInfo>> methods = _assemblyOption.Value.GetTypes().SelectMany(t => t.GetMethods().Select(m => new MethodReference<MethodInfo>(m.Name, m.IsPublic, m))).ToList(); MethodInfo entryPointReference = entryPointResolver.GetFunctionEntryPoint(methods).Value; // For F#, this currently creates a malformed signautre with fewer parameter symbols than parameter names. // For validation we only need the parameter names. The implementation of DotNetFunctionSignature copes with the // lists having different lengths. var parameters = entryPointReference.GetParameters().Select(x => new FunctionParameter(x.Name, x.ParameterType.FullName, x.IsOptional, GetParameterRefKind(x))); // For F#, we always set this to true for now. bool hasLocalTypeReference = true; var signature = new FunctionSignature(entryPointReference.DeclaringType.Name, entryPointReference.Name, parameters.ToImmutableArray(), entryPointReference.ReturnType.Name, hasLocalTypeReference); return signature; }
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}"); }
/// <inheritdoc/> public bool IsApplicable(FunctionSignature function) { return(function.ReturnType.IsVoidPointer()); }
public FunctionSignatureStartState(Variable functionName) { _functionSignature = new FunctionSignature(functionName); }
private void WriteDocumentation([NotNull] SourceWriter sw, [NotNull] FunctionSignature function) { if (!_documentation.TryGetDocumentation(function, out var documentation)) { Debug.WriteLine ( $"The function \"{function.Name}\" lacks documentation. Consider adding a documentation file for " + $"the function." ); WritePlaceholderDocumentation(sw, function); return; } sw.WriteLine("/// <summary>"); var summaryLines = documentation.Purpose.TrimEnd().Split('\n'); foreach (var summaryLine in summaryLines) { sw.WriteLine($"/// {summaryLine}"); } sw.WriteLine("/// </summary>"); for (int i = 0; i < function.Parameters.Count; ++i) { var parameter = function.Parameters[i]; var parameterDocumentation = documentation.Parameters.FirstOrDefault(dp => dp.Name == parameter.Name); if (parameterDocumentation is null) { sw.WriteLine($"/// <param name=\"{parameter.Name}\">This parameter lacks documentation.</param>"); continue; } // XML documentation doesn't require keyword escaping. if (parameter.Name.TrimStart('@') != parameterDocumentation.Name) { Debug.WriteLine ( $"Parameter {parameter.Name} in function {function.Name} has incorrect documentation name " + $"{parameterDocumentation.Name}." ); } sw.WriteLine($"/// <param name=\"{parameterDocumentation.Name}\">"); if (!(parameter.Count is null)) { if (parameter.Count.IsStatic) { sw.WriteLine($"/// This parameter contains {parameter.Count.Count} elements."); sw.WriteLine("///"); } if (parameter.Count.IsComputed) { var parameterList = parameter.Count.ComputedFrom.Select(cf => cf.Name).Humanize(); sw.WriteLine($"/// This parameter's element count is computed from {parameterList}."); sw.WriteLine("///"); } if (parameter.Count.IsReference) { // ReSharper disable once PossibleNullReferenceException sw.WriteLine($"/// This parameter's element count is taken from {parameter.Count.ValueReference.Name}."); sw.WriteLine("///"); } } var descriptionLines = parameterDocumentation.Description.TrimEnd().Split('\n'); foreach (var descriptionLine in descriptionLines) { sw.WriteLine($"/// {descriptionLine}"); } sw.WriteLine("/// </param>"); } foreach (var genericTypeParameter in function.GenericTypeParameters) { var referencingParameter = function.Parameters.First(f => f.Type.Name == genericTypeParameter.Name); sw.WriteLine ( $"/// <typeparam name=\"{genericTypeParameter.Name}\">The generic type of " + $"{referencingParameter.Name}.</typeparam>" ); } if (!function.ReturnType.Name.Equals(typeof(void).Name, StringComparison.OrdinalIgnoreCase)) { sw.WriteLine("/// <returns>See online documentation.</returns>"); } }
public override void ExitFunctionDecl(GolangParser.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.function()?.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, ""); } 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(CheckForBodyCommentsRight(context)); }
private static (FunctionSignature, StringBuilder) ToPointer(FunctionSignature function, FunctionSignature old) { var sb = new StringBuilder(); if (function.ReturnType.ToString() != "void") { sb.Append("return "); } sb.Append(function.Name + "("); var list = new List <string>(); foreach (var param in old.Parameters) { var nm = Utilities.CSharpKeywords.Contains(param.Name) ? "@" + param.Name : param.Name; if (param.Type.IsVoidPointer()) { list.Add(nm + ".ToPointer()"); } else { list.Add(nm); } } sb.Append(string.Join(", ", list)); sb.AppendLine(");"); return(function, sb); }
internal static ImmutableArray<Diagnostic> ValidateFunctionBindingArguments(FunctionSignature functionSignature, string triggerInputName, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings, ImmutableArray<Diagnostic>.Builder builder = null, bool throwIfFailed = false) { var resultBuilder = builder ?? ImmutableArray<Diagnostic>.Empty.ToBuilder(); if (!functionSignature.Parameters.Any(p => string.Compare(p.Name, triggerInputName, StringComparison.Ordinal) == 0)) { string message = string.Format(CultureInfo.InvariantCulture, "Missing a trigger argument named '{0}'.", triggerInputName); var descriptor = new DiagnosticDescriptor(DotNetConstants.MissingTriggerArgumentCompilationCode, "Missing trigger argument", message, "AzureFunctions", DiagnosticSeverity.Error, true); resultBuilder.Add(Diagnostic.Create(descriptor, Location.None)); } var bindings = inputBindings.Where(b => !b.Metadata.IsTrigger).Union(outputBindings); foreach (var binding in bindings) { if (string.Compare("http", binding.Metadata.Type, StringComparison.OrdinalIgnoreCase) == 0) { continue; } if (binding.Metadata.IsReturn) { continue; } if (!functionSignature.Parameters.Any(p => string.Compare(p.Name, binding.Metadata.Name, StringComparison.Ordinal) == 0)) { string message = string.Format(CultureInfo.InvariantCulture, "Missing binding argument named '{0}'. Mismatched binding argument names may lead to function indexing errors.", binding.Metadata.Name); var descriptor = new DiagnosticDescriptor(DotNetConstants.MissingBindingArgumentCompilationCode, "Missing binding argument", message, "AzureFunctions", DiagnosticSeverity.Warning, true); resultBuilder.Add(Diagnostic.Create(descriptor, Location.None)); } } ImmutableArray<Diagnostic> result = resultBuilder.ToImmutable(); if (throwIfFailed && result.Any(d => d.Severity == DiagnosticSeverity.Error)) { throw new CompilationErrorException("Function compilation failed.", result); } return resultBuilder.ToImmutable(); }
public FunctionOpBinding(Func <Op> builder, FunctionSignature signature) : base(builder) { Signature = signature; }
/// <summary> /// Determines whether or not the given function has any generic enum parameters, including the return /// parameter. /// </summary> /// <param name="f">The function.</param> /// <returns>true if the function has generic enum parameters; otherwise, false.</returns> private bool HasGenericEnumParameters([NotNull] FunctionSignature f) { return(f.Parameters.Any(p => p.Type.Name == "GLenum") || f.ReturnType.Name == "GLenum"); }
public FunctionSignatureEndState(FunctionSignature functionSignature) { _functionSignature = functionSignature; }
internal FunctionEmitter(IR.Function function, MethodFactory methodFactory, FunctionLookup functionLookup) { Contract.Requires(function != null); Contract.Requires(methodFactory != null); Contract.Requires(functionLookup != null); this.declaration = function; this.functionLookup = functionLookup; var signature = new FunctionSignature(function.Inputs.Select(i => i.StaticRepr), function.Outputs.Select(o => o.StaticRepr)); // Determine the method signature var parameterDescriptors = new List <ParameterDescriptor>(); foreach (var input in function.Inputs) { locals.Add(input, VariableLocation.Parameter(parameterDescriptors.Count)); parameterDescriptors.Add(new ParameterDescriptor(input.StaticCliType, ParameterAttributes.None, input.Name)); } Type returnType = typeof(void); if (function.Outputs.Length == 1) { returnType = function.Outputs[0].StaticCliType; // 1 output, use return value } else if (function.Outputs.Length >= 2) { // 2 or more outputs, use 'out' parameters foreach (var output in function.Outputs) { string name = output.Name; if (locals.ContainsKey(output)) { // inout parameter, rename not to clash with input name += "$out"; } else { locals.Add(output, VariableLocation.Parameter(parameterDescriptors.Count)); } var parameterType = output.StaticCliType.MakeByRefType(); parameterDescriptors.Add(new ParameterDescriptor(parameterType, ParameterAttributes.Out, name)); } } // Create the method and get its IL generator ILGenerator ilGenerator; var methodInfo = methodFactory(function.Name, parameterDescriptors, returnType, out ilGenerator); this.method = new FunctionMethod(methodInfo, signature); cil = new ILGeneratorMethodBodyWriter(ilGenerator); cil = new MethodBodyVerifier(new MethodBodyVerificationContext { Method = methodInfo, ParameterTypes = parameterDescriptors.Select(p => p.Type).ToArray(), ReturnType = returnType, HasInitLocals = true, MaxStackSize = ushort.MaxValue }, cil); temporaryPool = new TemporaryLocalPool(cil, "$temp"); if (function.Outputs.Length == 1) { // Declare a local variable for the return value var output = function.Outputs[0]; var localIndex = cil.DeclareLocal(output.StaticCliType, output.Name); if (!function.Inputs.Contains(output)) { locals.Add(output, VariableLocation.Local(localIndex)); } } }
public IntermediateConverter(WasmModule wasmModule, FunctionBody function, FunctionSignature signature) { this.wasmModule = wasmModule; this.function = function; this.signature = signature; }
public FunctionArgumentReadingState(FunctionSignature functionSignature, Symbol symbol) { _functionSignature = functionSignature; _bracketsBalance = 1; _argumentBuilder = new LexemeBuilder(symbol); }
public FunctionDocumentation GetDocumentation([NotNull] FunctionSignature function) { return(_documentedFunctions[function.NativeEntrypoint]); }
public Call(FunctionSignature signature) { Signature = signature; }
/// <summary> /// Determines whether or not a given function is documented. /// </summary> /// <param name="function">The function.</param> /// <returns>true if the function has documentation; otherwise, false.</returns> public bool HasDocumentation([NotNull] FunctionSignature function) { return(_documentedFunctions.ContainsKey(function.NativeEntrypoint)); }
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)); }
private async Task<MethodInfo> CreateFunctionTarget(CancellationToken cancellationToken) { try { await VerifyPackageReferencesAsync(); string eventName = string.Format(MetricEventNames.FunctionCompileLatencyByLanguageFormat, _compilationService.Language); using (_metricsLogger.LatencyEvent(eventName)) { ICompilation compilation = _compilationService.GetFunctionCompilation(Metadata); Assembly assembly = compilation.EmitAndLoad(cancellationToken); _assemblyLoader.CreateOrUpdateContext(Metadata, assembly, _metadataResolver, TraceWriter); FunctionSignature functionSignature = compilation.GetEntryPointSignature(_functionEntryPointResolver); ImmutableArray<Diagnostic> bindingDiagnostics = ValidateFunctionBindingArguments(functionSignature, _triggerInputName, _inputBindings, _outputBindings, throwIfFailed: true); TraceCompilationDiagnostics(bindingDiagnostics); // Set our function entry point signature _functionSignature = functionSignature; System.Reflection.TypeInfo scriptType = assembly.DefinedTypes .FirstOrDefault(t => string.Compare(t.Name, functionSignature.ParentTypeName, StringComparison.Ordinal) == 0); return _functionEntryPointResolver.GetFunctionEntryPoint(scriptType.DeclaredMethods.ToList()); } } catch (CompilationErrorException exc) { ImmutableArray<Diagnostic> diagnostics = AddFunctionDiagnostics(exc.Diagnostics); // Here we only need to trace to system logs TraceCompilationDiagnostics(diagnostics, LogTargets.System); throw new CompilationErrorException(exc.Message, diagnostics); } }
public FunctionInfo(FunctionSignature signature, SprakType returnType) { Signature = signature; ReturnType = returnType; }
public FunctionDefinition(FunctionExec exec, FunctionSignature signature) { Exec = exec; Signature = signature; }
/// <summary> /// Determines whether or not a given function signature has an applicable stage. /// </summary> /// <param name="signature">The signature.</param> /// <returns>True if the function has an applicable stage; otherwise, false.</returns> public bool HasApplicableStage(FunctionSignature signature) { return(_pipeline.Any(s => s.IsApplicable(signature))); }
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 InterfaceMethod(InterfaceTypeDefinition typeDef, FunctionSignature sig) { _def = new InterfaceMethodDefinition(typeDef, sig.FunctionName, sig, sig.ReturnDataType); }
public FunctionSignature MakeBindingFor(FunctionDefinitionSyntax syntax, FunctionSignature value) { FunctionSignaturesBindings[syntax] = value; return(value); }
public ItemWrapper(int location, FunctionSignature signature) { Location = location.ToString(); Signature = signature.ToString(); }
/// <inheritdoc/> public IEnumerable <(FunctionSignature, StringBuilder)> CreateOverloads(FunctionSignature function) { if (!function.Parameters.Any(p => p.Type.IsVoidPointer())) { yield break; } var baseParameters = function.Parameters; var newIntPtrParameters = new List <ParameterSignature>(baseParameters); var newGenericArray1DParameters = new List <ParameterSignature>(baseParameters); var newGenericArray2DParameters = new List <ParameterSignature>(baseParameters); var newGenericArray3DParameters = new List <ParameterSignature>(baseParameters); var newGenericTypeParameters = new List <GenericTypeParameterSignature>(); for (var i = 0; i < baseParameters.Count; ++i) { var parameter = baseParameters[i]; if (!parameter.Type.IsVoidPointer()) { continue; } var genericTypeParameterName = baseParameters.Count(p => p.Type.IsVoidPointer()) > 1 ? $"T{newGenericTypeParameters.Count + 1}" : "T"; var genericTypeParameter = new GenericTypeParameterSignature( genericTypeParameterName, new[] { "unmanaged" }); newGenericTypeParameters.Add(genericTypeParameter); var newIntPtrParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithName(nameof(IntPtr)) .Build(); // TODO: Simplify and generalize this var newGenericArray1DParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithArrayDimensions(1) .WithName(genericTypeParameterName) .Build(); var newGenericArray2DParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithArrayDimensions(2) .WithName(genericTypeParameterName) .Build(); var newGenericArray3DParameterType = new TypeSignatureBuilder(parameter.Type) .WithIndirectionLevel(0) .WithArrayDimensions(3) .WithName(genericTypeParameterName) .Build(); newIntPtrParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newIntPtrParameterType) .Build(); newGenericArray1DParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newGenericArray1DParameterType) .Build(); newGenericArray2DParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newGenericArray2DParameterType) .Build(); newGenericArray3DParameters[i] = new ParameterSignatureBuilder(parameter) .WithType(newGenericArray3DParameterType) .Build(); } yield return(ToPointer ( new FunctionSignatureBuilder(function) .WithParameters(newIntPtrParameters) .Build(), function )); yield return(Fixed ( new FunctionSignatureBuilder(function) .WithParameters(newGenericArray1DParameters) .WithGenericTypeParameters(newGenericTypeParameters) .Build() )); yield return(Fixed ( new FunctionSignatureBuilder(function) .WithParameters(newGenericArray2DParameters) .WithGenericTypeParameters(newGenericTypeParameters) .Build() )); yield return(Fixed ( new FunctionSignatureBuilder(function) .WithParameters(newGenericArray3DParameters) .WithGenericTypeParameters(newGenericTypeParameters) .Build() )); }
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 ReturnInstruction(FunctionSignature signature) { this.signature = signature; }
public void ValidateFunctionBindingArguments_ReturnBinding_Succeeds() { Collection<FunctionParameter> parameters = new Collection<FunctionParameter>() { new FunctionParameter("input", "String", false, RefKind.None) }; FunctionSignature signature = new FunctionSignature("Test", "Test", ImmutableArray.CreateRange<FunctionParameter>(parameters), "Test", false); Collection<FunctionBinding> inputBindings = new Collection<FunctionBinding>() { TestHelpers.CreateTestBinding(new JObject { { "type", "blobTrigger" }, { "name", "input" }, { "direction", "in" }, { "path", "test" } }) }; Collection<FunctionBinding> outputBindings = new Collection<FunctionBinding>() { TestHelpers.CreateTestBinding(new JObject { { "type", "blob" }, { "name", ScriptConstants.SystemReturnParameterBindingName }, { "direction", "out" }, { "path", "test/test" } }) }; var diagnostics = DotNetFunctionInvoker.ValidateFunctionBindingArguments(signature, "input", inputBindings, outputBindings); Assert.Equal(0, diagnostics.Count()); }