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