Beispiel #1
0
        public void Matches_IsTrue_WhenParametersAreEquivalent()
        {
            var function1 = @"using System;
public static void Run(string id, out string output)
{
    output = string.Empty;
}";

            // Diferent formatting, qualified name, not using alias
            var function2 = @"using System;
public static void Run( System.String id , 
out String output )
{
    string result = string.Empty;
    output = result;
}";

            var tree1 = CSharpSyntaxTree.ParseText(function1, CSharpParseOptions.Default.WithKind(SourceCodeKind.Script));
            var tree2 = CSharpSyntaxTree.ParseText(function2, CSharpParseOptions.Default.WithKind(SourceCodeKind.Script));

            var references = new MetadataReference[] { MetadataReference.CreateFromFile(typeof(string).Assembly.Location) };

            var compilation1 = CSharpCompilation.Create("test1", references: references).AddSyntaxTrees(tree1);
            var compilation2 = CSharpCompilation.Create("test2", references: references).AddSyntaxTrees(tree1);

            var signature1 = CSharpFunctionSignature.FromCompilation(compilation1, new FunctionEntryPointResolver());
            var signature2 = CSharpFunctionSignature.FromCompilation(compilation2, new FunctionEntryPointResolver());

            Assert.True(signature1.Equals(signature2));
            Assert.Equal(signature1.GetHashCode(), signature2.GetHashCode());
        }
Beispiel #2
0
        public void Matches_IsTrue_WhenUsingLocalTypes()
        {
            var function1 = @"using System;
public static void Run(Test id, out string output)
{
    output = string.Empty;
}

public class Test 
{
    public string Id { get; set; }
}";

            var tree        = CSharpSyntaxTree.ParseText(function1, CSharpParseOptions.Default.WithKind(SourceCodeKind.Script));
            var references  = new MetadataReference[] { MetadataReference.CreateFromFile(typeof(string).Assembly.Location) };
            var compilation = CSharpCompilation.Create("test1", references: references).AddSyntaxTrees(tree);

            var signature1 = CSharpFunctionSignature.FromCompilation(compilation, new FunctionEntryPointResolver());

            Assert.True(signature1.HasLocalTypeReference);
        }
Beispiel #3
0
        public void Matches_IsFalse_WhenNotUsingLocalTypes()
        {
            var function1 = @"using System;
using System.Threading.Tasks;
using System.Collections.Generic;
public static void Run(string id, int test1)
{
    
}

public class Test 
{
    public string Id { get; set; }
}";

            var tree        = CSharpSyntaxTree.ParseText(function1, CSharpParseOptions.Default.WithKind(SourceCodeKind.Script));
            var references  = new MetadataReference[] { MetadataReference.CreateFromFile(typeof(string).Assembly.Location) };
            var compilation = CSharpCompilation.Create("test1", references: references).AddSyntaxTrees(tree);

            var signature1 = CSharpFunctionSignature.FromCompilation(compilation, new FunctionEntryPointResolver());

            Assert.False(signature1.HasLocalTypeReference);
        }
        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();
        }
        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;
            }
        }