private void ReloadScript()
        {
            // Reset cached function
            ResetFunctionValue();
            TraceWriter.Verbose(string.Format(CultureInfo.InvariantCulture, "Script for function '{0}' changed. Reloading.", Metadata.Name));

            TraceWriter.Verbose("Compiling function script.");

            Script <object>             script            = CreateScript();
            Compilation                 compilation       = script.GetCompilation();
            ImmutableArray <Diagnostic> compilationResult = compilation.GetDiagnostics();

            CSharpFunctionSignature signature = CSharpFunctionSignature.FromCompilation(compilation, _functionEntryPointResolver);

            compilationResult = ValidateFunctionBindingArguments(signature, compilationResult.ToBuilder());

            TraceCompilationDiagnostics(compilationResult);

            bool compilationSucceeded = !compilationResult.Any(d => d.Severity == DiagnosticSeverity.Error);

            TraceWriter.Verbose(string.Format(CultureInfo.InvariantCulture, "Compilation {0}.",
                                              compilationSucceeded ? "succeeded" : "failed"));

            // If the compilation succeeded, AND:
            //  - We haven't cached a function (failed to compile on load), OR
            //  - We're referencing local function types (i.e. POCOs defined in the function) AND Our our function signature has changed
            // Restart our host.
            if (compilationSucceeded &&
                (_functionSignature == null ||
                 (_functionSignature.HasLocalTypeReference || !_functionSignature.Equals(signature))))
            {
                _host.RestartEvent.Set();
            }
        }
        private MethodInfo CreateFunctionTarget(CancellationToken cancellationToken)
        {
            // TODO:Get this from some context set in/by the host.
            bool         debug          = true;
            MemoryStream assemblyStream = null;
            MemoryStream pdbStream      = null;

            try
            {
                Script <object>         script            = CreateScript();
                Compilation             compilation       = GetScriptCompilation(script, debug);
                CSharpFunctionSignature functionSignature = CSharpFunctionSignature.FromCompilation(compilation, _functionEntryPointResolver);

                ValidateFunctionBindingArguments(functionSignature, throwIfFailed: true);

                using (assemblyStream = new MemoryStream())
                {
                    using (pdbStream = new MemoryStream())
                    {
                        var result = compilation.Emit(assemblyStream, pdbStream);

                        // Check if cancellation was requested while we were compiling,
                        // and if so quit here.
                        cancellationToken.ThrowIfCancellationRequested();

                        if (!result.Success)
                        {
                            throw new CompilationErrorException("Script compilation failed.", result.Diagnostics);
                        }

                        Assembly assembly = Assembly.Load(assemblyStream.GetBuffer(), pdbStream.GetBuffer());
                        _assemblyLoader.CreateOrUpdateContext(Metadata, assembly, _metadataResolver, TraceWriter);

                        // Get our function entry point
                        System.Reflection.TypeInfo scriptType = assembly.DefinedTypes.FirstOrDefault(t => string.Compare(t.Name, ScriptClassName, StringComparison.Ordinal) == 0);
                        _functionSignature = functionSignature;
                        return(_functionEntryPointResolver.GetFunctionEntryPoint(scriptType.DeclaredMethods.ToList()));
                    }
                }
            }
            catch (CompilationErrorException ex)
            {
                TraceWriter.Error("Function compilation error");
                TraceCompilationDiagnostics(ex.Diagnostics);
                throw;
            }
        }
        private ImmutableArray <Diagnostic> ValidateFunctionBindingArguments(CSharpFunctionSignature functionSignature,
                                                                             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(CSharpConstants.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 (binding.Metadata.Type == BindingType.Http)
                {
                    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}'.", binding.Metadata.Name);
                    var    descriptor = new DiagnosticDescriptor(CSharpConstants.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());
        }