diff --git a/src/Perf/CoreWf.Benchmarks/ExpressionTextboxPerformance.cs b/src/Perf/CoreWf.Benchmarks/ExpressionTextboxPerformance.cs index 97dd5d1d..cb3aca9e 100644 --- a/src/Perf/CoreWf.Benchmarks/ExpressionTextboxPerformance.cs +++ b/src/Perf/CoreWf.Benchmarks/ExpressionTextboxPerformance.cs @@ -2,6 +2,8 @@ using Microsoft.CSharp.Activities; using Microsoft.VisualBasic.Activities; using System.Activities; +using System.Activities.Expressions; +using System.Reflection; namespace CoreWf.Benchmarks { @@ -27,13 +29,13 @@ public void VB_CreatePrecompiledValue() [Benchmark] public async Task CS_CreatePrecompiledValueAsync() { - await CSharpDesignerHelper.CreatePrecompiledValueAsync(typeof(object), $"1 + {index++}", new[] { "System" }, new[] { "System" }, GetFreshEnvironment); + await CSharpDesignerHelper.CreatePrecompiledValueAsync(typeof(object), $"1 + {index++}", new[] { "System" }, new[] { (AssemblyReference)new AssemblyName("System") }, GetFreshEnvironment); } [Benchmark] public async Task VB_CreatePrecompiledValueAsync() { - await VisualBasicDesignerHelper.CreatePrecompiledValueAsync(typeof(object), $"1 + {index++}", new[] { "System" }, new[] { "System" }, GetFreshEnvironment); + await VisualBasicDesignerHelper.CreatePrecompiledValueAsync(typeof(object), $"1 + {index++}", new[] { "System" }, new[] { (AssemblyReference)new AssemblyName("System") }, GetFreshEnvironment); } } } diff --git a/src/Test/TestCases.Workflows/XamlTests.cs b/src/Test/TestCases.Workflows/XamlTests.cs index ac0ebbdb..30459ff9 100644 --- a/src/Test/TestCases.Workflows/XamlTests.cs +++ b/src/Test/TestCases.Workflows/XamlTests.cs @@ -14,6 +14,7 @@ using System.IO; using System.Linq; using System.Linq.Expressions; +using System.Reflection; using System.Threading.Tasks; using Xunit; @@ -228,7 +229,7 @@ public void CSharpShould_Infer_Type(string text, Type resultType, string[] names [Theory] [MemberData(nameof(GetCSharpTestData))] - public async Task CS_CreatePrecompiledValueAsync(string expression, IEnumerable namespaces, IEnumerable assemblies, IEnumerable importReferences) + public async Task CS_CreatePrecompiledValueAsync(string expression, IEnumerable namespaces, IEnumerable assemblies, IEnumerable importReferences) { var result = await CSharpDesignerHelper.CreatePrecompiledValueAsync(null, expression, namespaces, assemblies, null); @@ -240,7 +241,7 @@ public async Task CS_CreatePrecompiledValueAsync(string expression, IEnumerable< [Theory] [MemberData(nameof(GetVBTestData))] - public async Task VB_CreatePrecompiledValueAsync(string expression, IEnumerable namespaces, IEnumerable assemblies, IEnumerable importReferences) + public async Task VB_CreatePrecompiledValueAsync(string expression, IEnumerable namespaces, IEnumerable assemblies, IEnumerable importReferences) { var result = await VisualBasicDesignerHelper.CreatePrecompiledValueAsync(null, expression, namespaces, assemblies, null); @@ -254,10 +255,11 @@ public static IEnumerable GetCSharpTestData { get { - yield return new object[] { "typeof(JsonConvert)", new[] { "Newtonsoft.Json" }, new[] { "Newtonsoft.Json" }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; - yield return new object[] { "new JToken[5]", new[] { "Newtonsoft.Json", "Newtonsoft.Json.Linq" }, new[] { "Newtonsoft.Json" }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; - yield return new object[] { "new Dictionary, JToken>()", new[] { "System.Collections.Generic", "Newtonsoft.Json", "Newtonsoft.Json.Linq" }, new[] { "Newtonsoft.Json" }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; - yield return new object[] { "new ClassWithDictionaryProperty().TestProperty", new[] { "TestCases.Workflows" }, new[] { "System.Collections", "TestCases.Workflows", }, new[] { new VisualBasicImportReference { Assembly = "TestCases.Workflows", Import = "TestCases.Workflows" }, new VisualBasicImportReference { Assembly = "System.Private.CoreLib", Import = "System.Collections" } } }; + yield return new object[] { "typeof(JsonConvert)", new[] { "Newtonsoft.Json" }, new[] { (AssemblyReference)new AssemblyName("Newtonsoft.Json") }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; + yield return new object[] { "typeof(JsonConvert)", new[] { "Newtonsoft.Json" }, new[] { (AssemblyReference)typeof(JsonToken).Assembly }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; + yield return new object[] { "new JToken[5]", new[] { "Newtonsoft.Json", "Newtonsoft.Json.Linq" }, new[] { (AssemblyReference)new AssemblyName("Newtonsoft.Json") }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; + yield return new object[] { "new Dictionary, JToken>()", new[] { "System.Collections.Generic", "Newtonsoft.Json", "Newtonsoft.Json.Linq" }, new[] { (AssemblyReference)new AssemblyName("Newtonsoft.Json") }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; + yield return new object[] { "new ClassWithDictionaryProperty().TestProperty", new[] { "TestCases.Workflows" }, new[] { (AssemblyReference)new AssemblyName("System.Collections"), (AssemblyReference)new AssemblyName("TestCases.Workflows") }, new[] { new VisualBasicImportReference { Assembly = "TestCases.Workflows", Import = "TestCases.Workflows" }, new VisualBasicImportReference { Assembly = "System.Private.CoreLib", Import = "System.Collections" } } }; } } @@ -265,10 +267,11 @@ public static IEnumerable GetVBTestData { get { - yield return new object[] { "GetType(JsonConvert)", new[] { "Newtonsoft.Json" }, new[] { "Newtonsoft.Json" }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; - yield return new object[] { "new JToken(5){}", new[] { "Newtonsoft.Json", "Newtonsoft.Json.Linq" }, new[] { "Newtonsoft.Json" }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; - yield return new object[] { "new Dictionary(Of Dictionary(Of JToken, String), JToken)()", new[] { "System.Collections.Generic", "Newtonsoft.Json", "Newtonsoft.Json.Linq" }, new[] { "Newtonsoft.Json" }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; - yield return new object[] { "new ClassWithDictionaryProperty().TestProperty", new[] { "TestCases.Workflows" }, new[] { "System.Collections", "TestCases.Workflows", }, new[] { new VisualBasicImportReference { Assembly = "TestCases.Workflows", Import = "TestCases.Workflows" }, new VisualBasicImportReference { Assembly = "System.Private.CoreLib", Import = "System.Collections" } } }; + yield return new object[] { "GetType(JsonConvert)", new[] { "Newtonsoft.Json" }, new[] { (AssemblyReference)new AssemblyName("Newtonsoft.Json") }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; + yield return new object[] { "GetType(JsonConvert)", new[] { "Newtonsoft.Json" }, new[] { (AssemblyReference)typeof(JsonToken).Assembly }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; + yield return new object[] { "new JToken(5){}", new[] { "Newtonsoft.Json", "Newtonsoft.Json.Linq" }, new[] { (AssemblyReference)new AssemblyName("Newtonsoft.Json") }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; + yield return new object[] { "new Dictionary(Of Dictionary(Of JToken, String), JToken)()", new[] { "System.Collections.Generic", "Newtonsoft.Json", "Newtonsoft.Json.Linq" }, new[] { (AssemblyReference)new AssemblyName("Newtonsoft.Json") }, new[] { new VisualBasicImportReference { Assembly = "Newtonsoft.Json", Import = "Newtonsoft.json" } } }; + yield return new object[] { "new ClassWithDictionaryProperty().TestProperty", new[] { "TestCases.Workflows" }, new[] { (AssemblyReference)new AssemblyName("System.Collections"), (AssemblyReference)new AssemblyName("TestCases.Workflows") }, new[] { new VisualBasicImportReference { Assembly = "TestCases.Workflows", Import = "TestCases.Workflows" }, new VisualBasicImportReference { Assembly = "System.Private.CoreLib", Import = "System.Collections" } } }; } } diff --git a/src/UiPath.Workflow/Activities/DesignerHelperImpl.cs b/src/UiPath.Workflow/Activities/DesignerHelperImpl.cs index 3418a966..7dcbb08a 100644 --- a/src/UiPath.Workflow/Activities/DesignerHelperImpl.cs +++ b/src/UiPath.Workflow/Activities/DesignerHelperImpl.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.PowerFx.Core.Public.Values; using Microsoft.VisualBasic.Activities; using System.Activities.ExpressionParser; using System.Activities.Expressions; @@ -34,9 +35,7 @@ internal abstract class DesignerHelperImpl protected abstract ExpressionCompiler Compiler { get; } - public abstract JitCompilerHelper CreateJitCompilerHelper(string expressionText, HashSet references, - HashSet namespaces); - + public abstract JitCompilerHelper CreateJitCompilerHelper(string expressionText, HashSet references, HashSet namespaces); public Activity CreatePrecompiledValue(Type targetType, string expressionText, @@ -46,35 +45,25 @@ public Activity CreatePrecompiledValue(Type targetType, out Type returnType, out SourceExpressionException compileError, out VisualBasicSettings vbSettings) + => CreatePrecompiledValue(targetType, expressionText, namespaces, CreateReferences(referencedAssemblies), environment, out returnType, out compileError, out vbSettings); + + public Activity CreatePrecompiledValue(Type targetType, + string expressionText, + IEnumerable namespaces, + IEnumerable referencedAssemblies, + LocationReferenceEnvironment environment, + out Type returnType, + out SourceExpressionException compileError, + out VisualBasicSettings vbSettings) { LambdaExpression lambda = null; - var namespacesSet = new HashSet(); - var assembliesSet = new HashSet(); + var namespacesSet = new HashSet(namespaces ?? Enumerable.Empty()); + var assembliesSet = new HashSet(referencedAssemblies ?? Enumerable.Empty()); + namespacesSet.Remove(null); + assembliesSet.Remove(null); compileError = null; returnType = null; - if (namespaces != null) - { - foreach (var ns in namespaces) - { - if (ns != null) - { - namespacesSet.Add(ns); - } - } - } - - if (referencedAssemblies != null) - { - foreach (var assm in referencedAssemblies) - { - if (assm != null) - { - assembliesSet.Add(new AssemblyName(assm)); - } - } - } - var compilerHelper = CreateJitCompilerHelper(expressionText, assembliesSet, namespacesSet); if (targetType == null) { @@ -145,7 +134,7 @@ public Activity CreatePrecompiledValue(Type targetType, } public Task CreatePrecompiledValueAsync(Type targetType, string expressionText, IEnumerable namespaces, - IEnumerable referencedAssemblies, + IEnumerable referencedAssemblies, LocationReferenceEnvironment environment) => CreatePrecompiledExpressionAsync(targetType, expressionText, false, namespaces, referencedAssemblies, environment); @@ -160,13 +149,13 @@ public Activity RecompileValue(ActivityWithResult rValue, out Type returnType, var expressionText = textExpression.ExpressionText; var environment = rValue.GetParentEnvironment(); - GetAllImportReferences(rValue, out var namespaces, out var referencedAssemblies); + JitCompilerHelper.GetAllImportReferences(rValue, true, out var namespaces, out var assemblies); return CreatePrecompiledValue( null, expressionText, namespaces, - referencedAssemblies, + assemblies, environment, out returnType, out compileError, @@ -183,13 +172,13 @@ public Task RecompileValueAsync(ActivityWithResult rVa var expressionText = textExpression.ExpressionText; var environment = rValue.GetParentEnvironment(); - GetAllImportReferences(rValue, out var namespaces, out var referencedAssemblies); + JitCompilerHelper.GetAllImportReferences(rValue, true, out var namespaces, out var assemblies); return CreatePrecompiledValueAsync( null, expressionText, namespaces, - referencedAssemblies, + assemblies, environment); } @@ -201,35 +190,25 @@ public Activity CreatePrecompiledReference(Type targetType, out Type returnType, out SourceExpressionException compileError, out VisualBasicSettings vbSettings) + => CreatePrecompiledReference(targetType, expressionText, namespaces, CreateReferences(referencedAssemblies), environment, out returnType, out compileError, out vbSettings); + + public Activity CreatePrecompiledReference(Type targetType, + string expressionText, + IEnumerable namespaces, + IEnumerable referencedAssemblies, + LocationReferenceEnvironment environment, + out Type returnType, + out SourceExpressionException compileError, + out VisualBasicSettings vbSettings) { LambdaExpression lambda = null; - var namespacesSet = new HashSet(); - var assembliesSet = new HashSet(); + var namespacesSet = new HashSet(namespaces ?? Enumerable.Empty()); + var assembliesSet = new HashSet(referencedAssemblies ?? Enumerable.Empty()); + namespacesSet.Remove(null); + assembliesSet.Remove(null); compileError = null; returnType = null; - if (namespaces != null) - { - foreach (var ns in namespaces) - { - if (ns != null) - { - namespacesSet.Add(ns); - } - } - } - - if (referencedAssemblies != null) - { - foreach (var assm in referencedAssemblies) - { - if (assm != null) - { - assembliesSet.Add(new AssemblyName(assm)); - } - } - } - var compilerHelper = CreateJitCompilerHelper(expressionText, assembliesSet, namespacesSet); if (targetType == null) { @@ -333,7 +312,7 @@ public Activity CreatePrecompiledReference(Type targetType, } public Task CreatePrecompiledReferenceAsync(Type targetType, string expressionText, IEnumerable namespaces, - IEnumerable referencedAssemblies, LocationReferenceEnvironment environment) + IEnumerable referencedAssemblies, LocationReferenceEnvironment environment) => CreatePrecompiledExpressionAsync(targetType, expressionText, true, namespaces, referencedAssemblies, environment); public Activity RecompileReference(ActivityWithResult lValue, out Type returnType, out SourceExpressionException compileError, out VisualBasicSettings vbSettings) @@ -346,13 +325,13 @@ public Activity RecompileReference(ActivityWithResult lValue, out Type returnTyp var expressionText = textExpression.ExpressionText; var environment = lValue.GetParentEnvironment(); - GetAllImportReferences(lValue, out var namespaces, out var referencedAssemblies); + JitCompilerHelper.GetAllImportReferences(lValue, true, out var namespaces, out var assemblies); return CreatePrecompiledReference( null, expressionText, namespaces, - referencedAssemblies, + assemblies, environment, out returnType, out compileError, @@ -369,20 +348,20 @@ public Task RecompileReferenceAsync(ActivityWithResult var expressionText = textExpression.ExpressionText; var environment = lValue.GetParentEnvironment(); - GetAllImportReferences(lValue, out var namespaces, out var referencedAssemblies); + JitCompilerHelper.GetAllImportReferences(lValue, true, out var namespaces, out var assemblies); return CreatePrecompiledReferenceAsync( null, expressionText, namespaces, - referencedAssemblies, + assemblies, environment); } internal Activity CreatePrecompiledReference(Type targetType, string expressionText, Activity parent, out Type returnType, out SourceExpressionException compileError, out VisualBasicSettings vbSettings) { - GetAllImportReferences(parent, out var namespaces, out var assemblies); + JitCompilerHelper.GetAllImportReferences(parent, true, out var namespaces, out var assemblies); return CreatePrecompiledReference(targetType, expressionText, namespaces, assemblies, parent.PublicEnvironment, out returnType, out compileError, out vbSettings); } @@ -390,20 +369,20 @@ internal Activity CreatePrecompiledReference(Type targetType, string expressionT internal Activity CreatePrecompiledValue(Type targetType, string expressionText, Activity parent, out Type returnType, out SourceExpressionException compileError, out VisualBasicSettings vbSettings) { - GetAllImportReferences(parent, out var namespaces, out var assemblies); + JitCompilerHelper.GetAllImportReferences(parent, true, out var namespaces, out var assemblies); return CreatePrecompiledValue(targetType, expressionText, namespaces, assemblies, parent.PublicEnvironment, out returnType, out compileError, out vbSettings); } private async Task CreatePrecompiledExpressionAsync(Type targetType, string expressionText, bool isLocation, IEnumerable namespaces, - IEnumerable referencedAssemblies, + IEnumerable referencedAssemblies, LocationReferenceEnvironment environment) { SourceExpressionException compileError = null; var returnType = typeof(object); var vbSettings = new VisualBasicSettings(); namespaces ??= Array.Empty(); - referencedAssemblies ??= Array.Empty(); + referencedAssemblies ??= Array.Empty(); // execute compiler var compilation = Compiler.Compile(expressionText, isLocation, targetType ?? typeof(object), namespaces.ToList(), referencedAssemblies.ToList(), environment); @@ -796,23 +775,6 @@ private static void FindTypeReferences(MemberBinding binding, HashSet type } } - private static void GetAllImportReferences(Activity activity, out List namespaces, out List assemblies) - { - JitCompilerHelper.GetAllImportReferences(activity, true, out namespaces, out var referencedAssemblies); - - assemblies = new List(); - foreach (var reference in referencedAssemblies) - { - if (reference.AssemblyName != null) - { - assemblies.Add(reference.AssemblyName.FullName); - } - else if (reference.Assembly != null) - { - assemblies.Add(reference.Assembly.FullName); - } - } - } private static SourceExpressionException GetErrorsFromDiagnostics(string expressionText, ImmutableArray diagnostics) { @@ -838,4 +800,7 @@ private static void PopulateVbSettings(VisualBasicSettings vbSettings, Immutable vbSettings.ImportReferences.Add(import); } } + + private static IEnumerable CreateReferences(IEnumerable assemblyNames) + => assemblyNames?.OfType().Select(asmName => (AssemblyReference)new AssemblyName(asmName)) ?? Enumerable.Empty(); } diff --git a/src/UiPath.Workflow/Activities/ExpressionCompiler.cs b/src/UiPath.Workflow/Activities/ExpressionCompiler.cs index ba09e625..c0ef5200 100644 --- a/src/UiPath.Workflow/Activities/ExpressionCompiler.cs +++ b/src/UiPath.Workflow/Activities/ExpressionCompiler.cs @@ -12,10 +12,10 @@ namespace System.Activities { internal abstract class ExpressionCompiler { - public Compilation Compile(string expressionText, bool isLocation, Type returnType, IReadOnlyCollection namespaces, IReadOnlyCollection referencedAssemblies, LocationReferenceEnvironment environment) + public Compilation Compile(string expressionText, bool isLocation, Type returnType, IReadOnlyCollection namespaces, IReadOnlyCollection referencedAssemblies, LocationReferenceEnvironment environment) { var syntaxTree = GetSyntaxTreeForExpression(expressionText, isLocation, returnType, environment); - return GetCompilation(JitCompilerHelper.DefaultReferencedAssemblies.Select(a => AssemblyReference.GetFastAssemblyName(a).Name).Union(referencedAssemblies).ToList(), namespaces).AddSyntaxTrees(syntaxTree); + return GetCompilation(JitCompilerHelper.DefaultReferencedAssemblies.Select(a => (AssemblyReference)a).Union(referencedAssemblies).ToList(), namespaces).AddSyntaxTrees(syntaxTree); } public abstract Type GetReturnType(Compilation compilation); @@ -66,7 +66,7 @@ private static string GetTypeName(ITypeSymbol typeSymbol) } } - protected abstract Compilation GetCompilation(IReadOnlyCollection assemblies, IReadOnlyCollection namespaces); + protected abstract Compilation GetCompilation(IReadOnlyCollection assemblies, IReadOnlyCollection namespaces); protected abstract SyntaxTree GetSyntaxTreeForExpression(string expression, bool isLocation, Type returnType, LocationReferenceEnvironment environment); diff --git a/src/UiPath.Workflow/Activities/JitCompilerHelper.cs b/src/UiPath.Workflow/Activities/JitCompilerHelper.cs index 40b65bd1..b4ffdb09 100644 --- a/src/UiPath.Workflow/Activities/JitCompilerHelper.cs +++ b/src/UiPath.Workflow/Activities/JitCompilerHelper.cs @@ -64,19 +64,22 @@ protected virtual void OnCompilerCacheCreated(CompilerCache compilerCache) { } - protected virtual void Initialize(HashSet refAssemNames, HashSet namespaceImportsNames) + protected virtual void Initialize(HashSet assemblyReferences, HashSet namespaceImportsNames) { SanitizeNamespaces(namespaceImportsNames); - NamespaceImports = namespaceImportsNames; + InitializeAssemblies(assemblyReferences); + } - foreach (var assemblyName in refAssemNames) - { - ReferencedAssemblies ??= new HashSet(); + private void InitializeAssemblies(HashSet assemblyReferences) + { + ReferencedAssemblies ??= new HashSet(); + foreach (var assemblyReference in assemblyReferences) + { try { - var loaded = AssemblyReference.GetAssembly(assemblyName); + var loaded = GetAssembly(assemblyReference); if (loaded != null) { ReferencedAssemblies.Add(loaded); @@ -94,6 +97,21 @@ protected virtual void Initialize(HashSet refAssemNames, HashSet namespaceImportsNames) { namespaceImportsNames.Remove(""); @@ -1285,11 +1303,10 @@ internal abstract class JitCompilerHelper : JitCompilerHelper private static CompilerCache s_hostedCompilerCache; - public JitCompilerHelper(string expressionText, HashSet refAssemNames, - HashSet namespaceImportsNames) + public JitCompilerHelper(string expressionText, HashSet assemblyReferences, HashSet namespaceImportsNames) : this(expressionText) { - Initialize(refAssemNames, namespaceImportsNames); + Initialize(assemblyReferences, namespaceImportsNames); } protected JitCompilerHelper(string expressionText) diff --git a/src/UiPath.Workflow/Microsoft/CSharp/Activities/CSharpDesignerHelper.cs b/src/UiPath.Workflow/Microsoft/CSharp/Activities/CSharpDesignerHelper.cs index 6d89745e..d55d4385 100644 --- a/src/UiPath.Workflow/Microsoft/CSharp/Activities/CSharpDesignerHelper.cs +++ b/src/UiPath.Workflow/Microsoft/CSharp/Activities/CSharpDesignerHelper.cs @@ -4,6 +4,7 @@ using System; using System.Activities; using System.Activities.ExpressionParser; +using System.Activities.Expressions; using System.Collections.Generic; using System.Reflection; using System.Threading.Tasks; @@ -13,8 +14,8 @@ namespace Microsoft.CSharp.Activities; internal class CSharpHelper : JitCompilerHelper { - public CSharpHelper(string expressionText, HashSet refAssemNames, - HashSet namespaceImportsNames) : base(expressionText, refAssemNames, namespaceImportsNames) { } + public CSharpHelper(string expressionText, HashSet assemblyReferences, + HashSet namespaceImportsNames) : base(expressionText, assemblyReferences, namespaceImportsNames) { } protected override JustInTimeCompiler CreateCompiler(HashSet references) => new CSharpJitCompiler(references); @@ -34,7 +35,7 @@ internal class CSharpDesignerHelperImpl : DesignerHelperImpl public override Type ExpressionFactoryType => typeof(CSharpExpressionFactory<>); public override string Language => CSharpHelper.Language; - public override JitCompilerHelper CreateJitCompilerHelper(string expressionText, HashSet references, + public override JitCompilerHelper CreateJitCompilerHelper(string expressionText, HashSet references, HashSet namespaces) { return new CSharpHelper(expressionText, references, namespaces); @@ -72,6 +73,15 @@ public static Activity CreatePrecompiledValue(Type targetType, string expression environment, out returnType, out compileError, out vbSettings); } + public static Activity CreatePrecompiledValue(Type targetType, string expressionText, + IEnumerable namespaces, IEnumerable referencedAssemblies, + LocationReferenceEnvironment environment, out Type returnType, out SourceExpressionException compileError, + out VisualBasicSettings vbSettings) + { + return s_impl.CreatePrecompiledValue(targetType, expressionText, namespaces, referencedAssemblies, + environment, out returnType, out compileError, out vbSettings); + } + public static Activity CreatePrecompiledReference(Type targetType, string expressionText, IEnumerable namespaces, IEnumerable referencedAssemblies, LocationReferenceEnvironment environment, out Type returnType, out SourceExpressionException compileError, @@ -81,13 +91,21 @@ public static Activity CreatePrecompiledReference(Type targetType, string expres environment, out returnType, out compileError, out vbSettings); } + public static Activity CreatePrecompiledReference(Type targetType, string expressionText, + IEnumerable namespaces, IEnumerable referencedAssemblies, + LocationReferenceEnvironment environment, out Type returnType, out SourceExpressionException compileError, + out VisualBasicSettings vbSettings) + { + return s_impl.CreatePrecompiledReference(targetType, expressionText, namespaces, referencedAssemblies, + environment, out returnType, out compileError, out vbSettings); + } + public static Activity CreatePrecompiledValue(Type targetType, string expressionText, Activity parent, out Type returnType, out SourceExpressionException compileError, out VisualBasicSettings vbSettings) { return s_impl.CreatePrecompiledValue(targetType, expressionText, parent, out returnType, out compileError, out vbSettings); } - public static Activity CreatePrecompiledValue(Type targetType, string expressionText, Activity parent, out Type returnType, out SourceExpressionException compileError) { @@ -106,9 +124,9 @@ public static Activity CreatePrecompiledReference(Type targetType, string expres return CreatePrecompiledReference(targetType, expressionText, parent, out returnType, out compileError, out _); } - public static Task CreatePrecompiledValueAsync(Type targetType, string expressionText, IEnumerable namespaces, IEnumerable assemblies, LocationReferenceEnvironment environment) + public static Task CreatePrecompiledValueAsync(Type targetType, string expressionText, IEnumerable namespaces, IEnumerable assemblies, LocationReferenceEnvironment environment) => s_impl.CreatePrecompiledValueAsync(targetType, expressionText, namespaces, assemblies, environment); - public static Task CreatePrecompiledReferenceAsync(Type targetType, string expressionText, IEnumerable namespaces, IEnumerable assemblies, LocationReferenceEnvironment environment) + public static Task CreatePrecompiledReferenceAsync(Type targetType, string expressionText, IEnumerable namespaces, IEnumerable assemblies, LocationReferenceEnvironment environment) => s_impl.CreatePrecompiledReferenceAsync(targetType, expressionText, namespaces, assemblies, environment); } diff --git a/src/UiPath.Workflow/Microsoft/CSharp/CSharpExpressionCompiler.cs b/src/UiPath.Workflow/Microsoft/CSharp/CSharpExpressionCompiler.cs index b9cd4d54..0da3541a 100644 --- a/src/UiPath.Workflow/Microsoft/CSharp/CSharpExpressionCompiler.cs +++ b/src/UiPath.Workflow/Microsoft/CSharp/CSharpExpressionCompiler.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using System; using System.Activities; +using System.Activities.Expressions; using System.Activities.Utils; using System.Collections.Generic; using System.Linq; @@ -15,7 +16,7 @@ internal sealed class CSharpExpressionCompiler : ExpressionCompiler { private readonly CSharpCompilerHelper _compilerHelper = new(); - protected override Compilation GetCompilation(IReadOnlyCollection assemblies, IReadOnlyCollection namespaces) + protected override Compilation GetCompilation(IReadOnlyCollection assemblies, IReadOnlyCollection namespaces) { var options = _compilerHelper.DefaultCompilationUnit.Options as CSharpCompilationOptions; diff --git a/src/UiPath.Workflow/Microsoft/VisualBasic/Activities/VisualBasicDesignerHelper.cs b/src/UiPath.Workflow/Microsoft/VisualBasic/Activities/VisualBasicDesignerHelper.cs index 3cc7b57d..54f90ca8 100644 --- a/src/UiPath.Workflow/Microsoft/VisualBasic/Activities/VisualBasicDesignerHelper.cs +++ b/src/UiPath.Workflow/Microsoft/VisualBasic/Activities/VisualBasicDesignerHelper.cs @@ -4,6 +4,7 @@ using System; using System.Activities; using System.Activities.ExpressionParser; +using System.Activities.Expressions; using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; @@ -13,8 +14,8 @@ namespace Microsoft.VisualBasic.Activities; internal class VisualBasicHelper : JitCompilerHelper { - public VisualBasicHelper(string expressionText, HashSet refAssemNames, - HashSet namespaceImportsNames) : base(expressionText, refAssemNames, namespaceImportsNames) { } + public VisualBasicHelper(string expressionText, HashSet assemblyReferences, + HashSet namespaceImportsNames) : base(expressionText, assemblyReferences, namespaceImportsNames) { } private VisualBasicHelper(string expressionText) : base(expressionText) { } @@ -40,10 +41,10 @@ protected override void OnCompilerCacheCreated(Dictionary, Hos base.OnCompilerCacheCreated(compilerCache); } - protected override void Initialize(HashSet refAssemNames, HashSet namespaceImportsNames) + protected override void Initialize(HashSet assemblyReferences, HashSet namespaceImportsNames) { namespaceImportsNames.Add("Microsoft.VisualBasic"); - base.Initialize(refAssemNames, namespaceImportsNames); + base.Initialize(assemblyReferences, namespaceImportsNames); } public static Expression> Compile(string expressionText, @@ -52,7 +53,7 @@ public static Expression> Compile(string expressionT GetAllImportReferences(publicAccessor.ActivityMetadata.CurrentActivity, false, out var localNamespaces, out var localAssemblies); var helper = new VisualBasicHelper(expressionText); - var localReferenceAssemblies = new HashSet(); + var localReferenceAssemblies = new HashSet(); var localImports = new HashSet(localNamespaces); foreach (var assemblyReference in localAssemblies) { @@ -66,7 +67,7 @@ public static Expression> Compile(string expressionT } else if (assemblyReference.AssemblyName != null) { - localReferenceAssemblies.Add(assemblyReference.AssemblyName); + localReferenceAssemblies.Add(assemblyReference); } } @@ -82,11 +83,8 @@ internal class VisualBasicDesignerHelperImpl : DesignerHelperImpl protected override ExpressionCompiler Compiler { get; } = new VisualBasicExpressionCompiler(); - public override JitCompilerHelper CreateJitCompilerHelper(string expressionText, HashSet references, - HashSet namespaces) - { - return new VisualBasicHelper(expressionText, references, namespaces); - } + public override JitCompilerHelper CreateJitCompilerHelper(string expressionText, HashSet references, HashSet namespaces) + => new VisualBasicHelper(expressionText, references, namespaces); } public static class VisualBasicDesignerHelper @@ -131,7 +129,16 @@ public static Activity CreatePrecompiledVisualBasicValue(Type targetType, string environment, out returnType, out compileError, out vbSettings); } - public static Task CreatePrecompiledValueAsync(Type targetType, string expressionText, IEnumerable namespaces, IEnumerable assemblies, LocationReferenceEnvironment environment) + public static Activity CreatePrecompiledVisualBasicValue(Type targetType, string expressionText, + IEnumerable namespaces, IEnumerable referencedAssemblies, + LocationReferenceEnvironment environment, out Type returnType, out SourceExpressionException compileError, + out VisualBasicSettings vbSettings) + { + return s_impl.CreatePrecompiledValue(targetType, expressionText, namespaces, referencedAssemblies, + environment, out returnType, out compileError, out vbSettings); + } + + public static Task CreatePrecompiledValueAsync(Type targetType, string expressionText, IEnumerable namespaces, IEnumerable assemblies, LocationReferenceEnvironment environment) => s_impl.CreatePrecompiledValueAsync(targetType, expressionText, namespaces, assemblies, environment); public static Activity CreatePrecompiledVisualBasicReference(Type targetType, string expressionText, @@ -143,7 +150,16 @@ public static Activity CreatePrecompiledVisualBasicReference(Type targetType, st environment, out returnType, out compileError, out vbSettings); } - public static Task CreatePrecompiledReferenceAsync(Type targetType, string expressionText, IEnumerable namespaces, IEnumerable assemblies, LocationReferenceEnvironment environment) + public static Activity CreatePrecompiledVisualBasicReference(Type targetType, string expressionText, + IEnumerable namespaces, IEnumerable referencedAssemblies, + LocationReferenceEnvironment environment, out Type returnType, out SourceExpressionException compileError, + out VisualBasicSettings vbSettings) + { + return s_impl.CreatePrecompiledReference(targetType, expressionText, namespaces, referencedAssemblies, + environment, out returnType, out compileError, out vbSettings); + } + + public static Task CreatePrecompiledReferenceAsync(Type targetType, string expressionText, IEnumerable namespaces, IEnumerable assemblies, LocationReferenceEnvironment environment) => s_impl.CreatePrecompiledReferenceAsync(targetType, expressionText, namespaces, assemblies, environment); public static Activity CreatePrecompiledValue(Type targetType, string expressionText, Activity parent, diff --git a/src/UiPath.Workflow/Microsoft/VisualBasic/VisualBasicExpressionCompiler.cs b/src/UiPath.Workflow/Microsoft/VisualBasic/VisualBasicExpressionCompiler.cs index 6b344789..922e0d09 100644 --- a/src/UiPath.Workflow/Microsoft/VisualBasic/VisualBasicExpressionCompiler.cs +++ b/src/UiPath.Workflow/Microsoft/VisualBasic/VisualBasicExpressionCompiler.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis.VisualBasic.Syntax; using System; using System.Activities; +using System.Activities.Expressions; using System.Activities.Utils; using System.Collections.Generic; using System.Linq; @@ -29,7 +30,7 @@ public override Type GetReturnType(Compilation compilation) return GetSystemType(typeInfo, GetAssemblyForType(typeInfo)); } - protected override Compilation GetCompilation(IReadOnlyCollection assemblies, IReadOnlyCollection namespaces) + protected override Compilation GetCompilation(IReadOnlyCollection assemblies, IReadOnlyCollection namespaces) { var options = _compilerHelper.DefaultCompilationUnit.Options as VisualBasicCompilationOptions; diff --git a/src/UiPath.Workflow/Utils/MetadataReferenceUtils.cs b/src/UiPath.Workflow/Utils/MetadataReferenceUtils.cs index b3027157..ad032e4f 100644 --- a/src/UiPath.Workflow/Utils/MetadataReferenceUtils.cs +++ b/src/UiPath.Workflow/Utils/MetadataReferenceUtils.cs @@ -33,10 +33,8 @@ internal static MetadataReference GetMetadataReferenceForAssembly(Assembly assem return meta; } - internal static IReadOnlyCollection GetMetadataReferences(IEnumerable assemblyNames) - { - return GetMetadataReferences(assemblyNames.Select(a => AssemblyReference.GetAssembly(new AssemblyName(a)))); - } + internal static IReadOnlyCollection GetMetadataReferences(IEnumerable assemblyReferences) + => GetMetadataReferences(assemblyReferences.OfType().Select(aref => aref.Assembly ?? LoadAssemblyFromReference(aref))); internal static IReadOnlyCollection GetMetadataReferences(IEnumerable assemblies) { @@ -81,5 +79,17 @@ private static MetadataReference GetMetadataReference(Assembly assembly) return null; } + + /// + /// If is null, loads the assembly. Default is to + /// call . + /// + /// + /// + private static Assembly LoadAssemblyFromReference(AssemblyReference assemblyReference) + { + assemblyReference.LoadAssembly(); + return assemblyReference.Assembly; + } } }