private CSharpCompilation CompileViews(ViewCompilationInfo[] results, string assemblyName) { var compilation = compiler.CreateCompilation(assemblyName); var syntaxTrees = new SyntaxTree[results.Length]; Parallel.For(0, results.Length, ParallelOptions, i => { ViewCompilationInfo result = results[i]; SourceText sourceText = SourceText.From(result.CSharpDocument.GeneratedCode, Encoding.UTF8); TemplateFileInfo fileInfo = result.TemplateFileInfo; SyntaxTree syntaxTree = compiler.CreateSyntaxTree(sourceText).WithFilePath(fileInfo.FullPath ?? fileInfo.ViewEnginePath); syntaxTrees[i] = syntaxTree; }); compilation = compilation.AddSyntaxTrees(syntaxTrees); compilation = ExpressionRewriter.Rewrite(compilation); compilation = AssemblyMetadataGenerator.AddAssemblyMetadata( compiler, compilation, Options); return(compilation); }
public void ExpressionRewriter_CannotRewriteExpression_NestedClass() { // Arrange var source = @" using System; using System.Linq.Expressions; public class Program { private class Nested { public static void CalledWithExpression(Expression<Func<object, int>> expression) { } public static void Main(string[] args) { Expression<Func<object, int>> expr = x => x.GetHashCode(); CalledWithExpression(expr); } } } "; var tree = CSharpSyntaxTree.ParseText(source); var compilation = Compile(tree); var semanticModel = compilation.GetSemanticModel(tree, ignoreAccessibility: true); var rewriter = new ExpressionRewriter(semanticModel); // Act var result = rewriter.Visit(tree.GetRoot()); // Assert Assert.Empty(FindFields(result)); }
private CSharpCompilation CompileViews(ViewCompilationInfo[] results, string assemblyname) { var compiler = MvcServiceProvider.Compiler; var compilation = compiler.CreateCompilation(assemblyname); var syntaxTrees = new SyntaxTree[results.Length]; Parallel.For(0, results.Length, ParalellOptions, i => { var result = results[i]; var sourceText = SourceText.From(result.CSharpDocument.GeneratedCode, Encoding.UTF8); var fileInfo = result.ViewFileInfo; var syntaxTree = compiler.CreateSyntaxTree(sourceText) .WithFilePath(fileInfo.FullPath ?? fileInfo.ViewEnginePath); syntaxTrees[i] = syntaxTree; }); compilation = compilation.AddSyntaxTrees(syntaxTrees); // Post process the compilation - run ExpressionRewritter and any user specified callbacks. compilation = ExpressionRewriter.Rewrite(compilation); var compilationContext = new RoslynCompilationContext(compilation); MvcServiceProvider.ViewEngineOptions.CompilationCallback(compilationContext); compilation = AssemblyMetadataGenerator.AddAssemblyMetadata( compiler, compilationContext.Compilation, Options); return(compilation); }
private ExpressionRewriter(ExpressionRewriter parent) { if (parent == null) { throw new ArgumentNullException("parent"); } subst = new Dictionary <Expression, Expression>(parent.subst); inline = parent.inline; }
private void ShouldEqual(Expression <Func <bool> > assertion, string toString) { var rewriter = new ExpressionRewriter(); var result = (LambdaExpression)rewriter.Visit(assertion); var str = ExpressionStringBuilder.ExpressionToString(result.Body); Assert(() => str.StartsWith(toString)); }
/// <summary> /// Update the data with new version information /// </summary> public override TModel Update(ModelDataContext context, TModel data, IPrincipal principal) { if (data.Key == Guid.Empty) { throw new SqlFormalConstraintException(SqlFormalConstraintType.NonIdentityUpdate); } // This is technically an insert and not an update var existingObject = context.GetTable <TDomain>().FirstOrDefault(ExpressionRewriter.Rewrite <TDomain>(o => o.Id == data.Key && !o.ObsoletionTime.HasValue)); // Get the last version (current) if (existingObject == null) { throw new KeyNotFoundException(data.Key.ToString()); } else if (existingObject.IsReadonly) { throw new SqlFormalConstraintException(SqlFormalConstraintType.UpdatedReadonlyObject); } // Map existing var storageInstance = this.FromModelInstance(data, context, principal); // Create a new version var user = principal.GetUser(context); var newEntityVersion = new TDomain(); newEntityVersion.CopyObjectData(storageInstance); // Client did not change on update, so we need to update!!! if (!data.VersionKey.HasValue || data.VersionKey.Value == existingObject.VersionId) { data.VersionKey = newEntityVersion.VersionId = Guid.NewGuid(); } data.VersionSequence = newEntityVersion.VersionSequenceId = default(Decimal); newEntityVersion.Id = data.Key.Value; data.PreviousVersionKey = newEntityVersion.ReplacesVersionId = existingObject.VersionId; data.CreatedByKey = newEntityVersion.CreatedBy = user.UserId; // Obsolete the old version existingObject.ObsoletedBy = user.UserId; existingObject.ObsoletionTime = DateTime.Now; context.GetTable <TDomain>().InsertOnSubmit(newEntityVersion); context.SubmitChanges(); // Pull database generated fields data.VersionSequence = newEntityVersion.VersionSequenceId; data.CreationTime = newEntityVersion.CreationTime; return(data); //return base.Update(context, data, principal); }
private CSharpCompilation CompileViews(ViewCompilationInfo[] results, string assemblyname) { var compiler = MvcServiceProvider.Compiler; var compilation = compiler.CreateCompilation(assemblyname); var syntaxTrees = new SyntaxTree[results.Length]; string[] additionalReferences = new string[] { @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Microsoft.CSharp.dll", //@"C:\Users\jbato\.nuget\packages\Microsoft.DiaSymReader.Native\1.4.0\runtimes\win-x64\native\Microsoft.DiaSymReader.Native.amd64.dll", }; compilation = compilation.AddReferences(additionalReferences.Select(r => MetadataReference.CreateFromFile(r))); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); compilation = compilation.AddReferences(assemblies.Where(a => !a.IsDynamic).Select(a => MetadataReference.CreateFromFile(a.Location))); Parallel.For(0, results.Length, ParalellOptions, i => { var result = results[i]; var sourceText = SourceText.From(result.GeneratorResults.GeneratedCode, Encoding.UTF8); var fileInfo = result.RelativeFileInfo; var syntaxTree = compiler.CreateSyntaxTree(sourceText) .WithFilePath(fileInfo.FileInfo.PhysicalPath ?? fileInfo.RelativePath); syntaxTrees[i] = syntaxTree; }); compilation = compilation.AddSyntaxTrees(syntaxTrees); Parallel.For(0, results.Length, ParalellOptions, i => { results[i].TypeName = ReadTypeInfo(compilation, syntaxTrees[i]); }); // Post process the compilation - run ExpressionRewritter and any user specified callbacks. compilation = ExpressionRewriter.Rewrite(compilation); var compilationContext = new RoslynCompilationContext(compilation); MvcServiceProvider.ViewEngineOptions.CompilationCallback(compilationContext); compilation = compilationContext.Compilation; var codeGenerator = new ViewInfoContainerCodeGenerator(compiler, compilation); codeGenerator.AddViewFactory(results); var assemblyName = new AssemblyName(ApplicationNameOption.Value()); assemblyName = Assembly.Load(assemblyName).GetName(); codeGenerator.AddAssemblyMetadata(assemblyName, StrongNameOptions); return(codeGenerator.Compilation); }
private CSharpCompilation CreateCompilation(string compilationContent, string assemblyName) { SourceText sourceText = SourceText.From(compilationContent, Encoding.UTF8); SyntaxTree syntaxTree = CreateSyntaxTree(sourceText).WithFilePath(assemblyName); CSharpCompilation compilation = CreateCompilation(assemblyName).AddSyntaxTrees(syntaxTree); compilation = ExpressionRewriter.Rewrite(compilation); //var compilationContext = new RoslynCompilationContext(compilation); //_compilationCallback(compilationContext); //compilation = compilationContext.Compilation; return(compilation); }
internal Expression AutoInline(InvocationExpression expression) { isLocked = true; if(expression == null) throw new ArgumentNullException("expression"); LambdaExpression lambda = (LambdaExpression)expression.Expression; ExpressionRewriter childScope = new ExpressionRewriter(this); var lambdaParams = lambda.Parameters; var invokeArgs = expression.Arguments; if (lambdaParams.Count != invokeArgs.Count) throw new InvalidOperationException("Lambda/invoke mismatch"); for(int i = 0 ; i < lambdaParams.Count; i++) { childScope.Subst(lambdaParams[i], invokeArgs[i]); } return childScope.Apply(lambda.Body); }
private CSharpCompilation Rewrite(CSharpCompilation compilation) { var rewrittenTrees = new List <SyntaxTree>(); foreach (var tree in compilation.SyntaxTrees) { var semanticModel = compilation.GetSemanticModel(tree, ignoreAccessibility: true); var rewriter = new ExpressionRewriter(semanticModel); var rewrittenTree = tree.WithRootAndOptions(rewriter.Visit(tree.GetRoot()), tree.Options); rewrittenTrees.Add(rewrittenTree); } return(compilation.RemoveAllSyntaxTrees().AddSyntaxTrees(rewrittenTrees)); }
/// <summary> /// Update associated items /// </summary> protected virtual void UpdateAssociatedItems <TAssociation, TDomainAssociation>(IEnumerable <TAssociation> storage, TModel source, ModelDataContext context, IPrincipal principal) where TAssociation : IdentifiedData, ISimpleAssociation, new() where TDomainAssociation : class, IDbAssociation, new() { var persistenceService = ApplicationContext.Current.GetService <IDataPersistenceService <TAssociation> >() as SqlServerBasePersistenceService <TAssociation>; if (persistenceService == null) { this.m_tracer.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "Missing persister for type {0}", typeof(TAssociation).Name); return; } // Ensure the source key is set foreach (var itm in storage) { if (itm.SourceEntityKey == Guid.Empty || itm.SourceEntityKey == null) { itm.SourceEntityKey = source.Key; } } // Get existing var existing = context.GetTable <TDomainAssociation>().Where(ExpressionRewriter.Rewrite <TDomainAssociation>(o => o.AssociatedItemKey == source.Key)).ToList().Select(o => m_mapper.MapDomainInstance <TDomainAssociation, TAssociation>(o) as TAssociation); // Remove old var obsoleteRecords = existing.Where(o => !storage.Any(ecn => ecn.Key == o.Key)); foreach (var del in obsoleteRecords) { persistenceService.Obsolete(context, del, principal); } // Update those that need it var updateRecords = storage.Where(o => existing.Any(ecn => ecn.Key == o.Key && o.Key != Guid.Empty && o != ecn)); foreach (var upd in updateRecords) { persistenceService.Update(context, upd, principal); } // Insert those that do not exist var insertRecords = storage.Where(o => !existing.Any(ecn => ecn.Key == o.Key)); foreach (var ins in insertRecords) { persistenceService.Insert(context, ins, principal); } }
/// <summary> /// Performs the actual obsoletion /// </summary> /// <param name="context">Context.</param> /// <param name="data">Data.</param> public override TModel Obsolete(ModelDataContext context, TModel data, IPrincipal principal) { if (data.Key == Guid.Empty) { throw new SqlFormalConstraintException(SqlFormalConstraintType.NonIdentityUpdate); } var domainObject = context.GetTable <TDomain>().FirstOrDefault(ExpressionRewriter.Rewrite <TDomain>(o => o.Id == data.Key)); if (domainObject == null) { throw new KeyNotFoundException(data.Key.ToString()); } context.GetTable <TDomain>().DeleteOnSubmit(domainObject); return(this.ToModelInstance(domainObject, context, principal)); }
public override Core.Model.Security.SecurityPolicy Update(ModelDataContext context, Core.Model.Security.SecurityPolicy data, IPrincipal principal) { var domainInstance = this.FromModelInstance(data, context, principal) as Data.Policy; var currentObject = context.GetTable <Data.Policy>().FirstOrDefault(ExpressionRewriter.Rewrite <Data.Policy>(o => o.Id == data.Key)); if (currentObject == null) { throw new KeyNotFoundException(data.Key.ToString()); } currentObject.CopyObjectData(domainInstance); currentObject.ObsoletedBy = data.ObsoletedByKey == Guid.Empty ? null : data.ObsoletedByKey; currentObject.ObsoletionTime = data.ObsoletionTime; context.SubmitChanges(); return(data); }
/// <summary> /// Performs the actual obsoletion /// </summary> /// <param name="context">Context.</param> /// <param name="data">Data.</param> public override TModel Obsolete(ModelDataContext context, TModel data, IPrincipal principal) { if (data.Key == Guid.Empty) { throw new SqlFormalConstraintException(SqlFormalConstraintType.NonIdentityUpdate); } // Current object var currentObject = context.GetTable <TDomain>().FirstOrDefault(ExpressionRewriter.Rewrite <TDomain>(o => o.Id == data.Key)); if (currentObject == null) { throw new KeyNotFoundException(data.Key.ToString()); } data.ObsoletedBy?.EnsureExists(context, principal); data.ObsoletedByKey = currentObject.ObsoletedBy = data.ObsoletedBy?.Key ?? principal.GetUser(context).UserId; data.ObsoletionTime = currentObject.ObsoletionTime = currentObject.ObsoletionTime ?? DateTimeOffset.Now; context.SubmitChanges(); return(data); }
private CSharpCompilation CompileViews(ViewCompilationInfo[] results, string assemblyname) { var compiler = MvcServiceProvider.Compiler; var compilation = compiler.CreateCompilation(assemblyname); var syntaxTrees = new SyntaxTree[results.Length]; Parallel.For(0, results.Length, ParalellOptions, i => { var result = results[i]; var sourceText = SourceText.From(result.GeneratorResults.GeneratedCode, Encoding.UTF8); var fileInfo = result.RelativeFileInfo; var syntaxTree = compiler.CreateSyntaxTree(sourceText) .WithFilePath(fileInfo.FileInfo.PhysicalPath ?? fileInfo.RelativePath); syntaxTrees[i] = syntaxTree; }); compilation = compilation.AddSyntaxTrees(syntaxTrees); Parallel.For(0, results.Length, ParalellOptions, i => { results[i].TypeName = ReadTypeInfo(compilation, syntaxTrees[i]); }); // Post process the compilation - run ExpressionRewritter and any user specified callbacks. compilation = ExpressionRewriter.Rewrite(compilation); var compilationContext = new RoslynCompilationContext(compilation); MvcServiceProvider.ViewEngineOptions.CompilationCallback(compilationContext); compilation = compilationContext.Compilation; var codeGenerator = new ViewInfoContainerCodeGenerator(compiler, compilation); codeGenerator.AddViewFactory(results); var assemblyName = new AssemblyName(ApplicationNameOption.Value()); assemblyName = Assembly.Load(assemblyName).GetName(); codeGenerator.AddAssemblyMetadata(assemblyName, StrongNameOptions); return(codeGenerator.Compilation); }
/// <summary> /// Perform the actual update. /// </summary> /// <param name="context">Context.</param> /// <param name="data">Data.</param> public override TModel Update(ModelDataContext context, TModel data, IPrincipal principal) { // Sanity if (data.Key == Guid.Empty) { throw new SqlFormalConstraintException(SqlFormalConstraintType.NonIdentityUpdate); } // Map and copy var newDomainObject = this.FromModelInstance(data, context, principal) as TDomain; var domainQuery = ExpressionRewriter.Rewrite <TDomain>(o => o.Id == newDomainObject.Id); var oldDomainObject = context.GetTable <TDomain>().SingleOrDefault(domainQuery); if (oldDomainObject == null) { throw new KeyNotFoundException(data.Key.ToString()); } oldDomainObject.CopyObjectData(newDomainObject); context.SubmitChanges(); return(data); }
/// <summary> /// Update versioned association items /// </summary> internal virtual void UpdateVersionedAssociatedItems <TAssociation, TDomainAssociation>(IEnumerable <TAssociation> storage, TModel source, ModelDataContext context, IPrincipal principal) where TAssociation : VersionedAssociation <TModel>, new() where TDomainAssociation : class, IDbVersionedAssociation, new() { var persistenceService = ApplicationContext.Current.GetService <IDataPersistenceService <TAssociation> >() as SqlServerBasePersistenceService <TAssociation>; if (persistenceService == null) { this.m_tracer.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "Missing persister for type {0}", typeof(TAssociation).Name); return; } Dictionary <Guid, Decimal> sourceVersionMaps = new Dictionary <Guid, decimal>(); // Ensure the source key is set foreach (var itm in storage) { if (itm.SourceEntityKey == Guid.Empty || itm.SourceEntityKey == null) { itm.SourceEntityKey = source.Key; } else if (itm.SourceEntityKey != source.Key && !sourceVersionMaps.ContainsKey(itm.SourceEntityKey ?? Guid.Empty)) // The source comes from somewhere else { // First we have our association type, we need to get the property that is // linked on the association to get the map to the underlying SQL table var domainType = m_mapper.MapModelType(typeof(TDomainAssociation)); var mappedProperty = domainType.GetRuntimeProperty("AssociatedItemKey").GetCustomAttribute <LinqPropertyMapAttribute>().LinqMember; // Next we want to get the association entity which is linked to this key identifier var rpi = domainType.GetRuntimeProperties().FirstOrDefault(o => o.GetCustomAttribute <AssociationAttribute>()?.ThisKey == mappedProperty); // Now we want to switch the type to the entity that is linked to the key so we can // get ist primary key domainType = rpi.PropertyType; var pkey = domainType.GetRuntimeProperties().FirstOrDefault(o => o.GetCustomAttribute <ColumnAttribute>()?.IsPrimaryKey == true); // Now we want to get the key that we should query by that is version independent domainType = typeof(TDomain); pkey = domainType.GetRuntimeProperty(pkey.Name); // Construct a LINQ expression to query the db var parm = Expression.Parameter(domainType); var delegateType = typeof(Func <,>).MakeGenericType(domainType, typeof(bool)); var predicate = Expression.Lambda(delegateType, Expression.MakeBinary(ExpressionType.Equal, Expression.MakeMemberAccess(parm, pkey), Expression.Constant(itm.SourceEntityKey.Value)), parm); // Get the SQL table instance and filter var table = context.GetTable(domainType); var tableEnum = table.Provider.Execute(table.Expression); var methodInfo = typeof(Queryable).GetGenericMethod("FirstOrDefault", new Type[] { domainType }, new Type[] { typeof(IQueryable <>).MakeGenericType(domainType), typeof(Expression <>).MakeGenericType(delegateType) }); var result = methodInfo.Invoke(null, new Object[] { tableEnum, predicate }) as IDbVersionedData; sourceVersionMaps.Add(itm.SourceEntityKey.Value, result.VersionSequenceId); //var whereMethod = //var result = context.GetTable(domainType).Provider.Execute(predicate); } } // Get existing // TODO: What happens which this is reverse? var existing = context.GetTable <TDomainAssociation>().Where(ExpressionRewriter.Rewrite <TDomainAssociation>(o => o.AssociatedItemKey == source.Key && source.VersionSequence >= o.EffectiveVersionSequenceId && (source.VersionSequence < o.ObsoleteVersionSequenceId || !o.ObsoleteVersionSequenceId.HasValue))).ToList().Select(o => m_mapper.MapDomainInstance <TDomainAssociation, TAssociation>(o) as TAssociation); // Remove old var obsoleteRecords = existing.Where(o => !storage.Any(ecn => ecn.Key == o.Key)); foreach (var del in obsoleteRecords) { decimal obsVersion = 0; if (!sourceVersionMaps.TryGetValue(del.SourceEntityKey.Value, out obsVersion)) { obsVersion = source.VersionSequence.GetValueOrDefault(); } del.ObsoleteVersionSequenceId = obsVersion; persistenceService.Update(context, del, principal); } // Update those that need it var updateRecords = storage.Where(o => existing.Any(ecn => ecn.Key == o.Key && o.Key != Guid.Empty && o != ecn)); foreach (var upd in updateRecords) { persistenceService.Update(context, upd, principal); } // Insert those that do not exist var insertRecords = storage.Where(o => !existing.Any(ecn => ecn.Key == o.Key)); foreach (var ins in insertRecords) { decimal eftVersion = 0; if (!sourceVersionMaps.TryGetValue(ins.SourceEntityKey.Value, out eftVersion)) { eftVersion = source.VersionSequence.GetValueOrDefault(); } ins.EffectiveVersionSequenceId = eftVersion; persistenceService.Insert(context, ins, principal); } }
protected ConcatenationRewriter(ExpressionRewriter <object> scout) { EnsureArg.IsNotNull(scout, nameof(scout)); _rewritingScout = scout; }
/// <summary> /// Update the roles to security user /// </summary> public override Core.Model.Security.SecurityApplication Update(ModelDataContext context, Core.Model.Security.SecurityApplication data, IPrincipal principal) { var domainInstance = this.FromModelInstance(data, context, principal) as Data.SecurityApplication; var currentObject = context.GetTable <Data.SecurityApplication>().FirstOrDefault(ExpressionRewriter.Rewrite <Data.SecurityApplication>(o => o.Id == data.Key)); if (currentObject == null) { throw new KeyNotFoundException(data.Key.ToString()); } currentObject.CopyObjectData(domainInstance); currentObject.ObsoletedBy = data.ObsoletedByKey == Guid.Empty ? null : data.ObsoletedByKey; currentObject.ObsoletionTime = data.ObsoletionTime; context.SubmitChanges(); context.SecurityApplicationPolicies.DeleteAllOnSubmit(context.SecurityApplicationPolicies.Where(o => o.ApplicationId == domainInstance.Id)); context.SubmitChanges(); context.SecurityApplicationPolicies.InsertAllOnSubmit(data.Policies.Select(o => new Data.SecurityApplicationPolicy { PolicyId = o.PolicyKey.Value, PolicyAction = (int)o.GrantType, ApplicationId = domainInstance.Id, SecurityPolicyInstanceId = Guid.NewGuid() })); context.SubmitChanges(); return(data); }
// Token: 0x06000183 RID: 387 RVA: 0x00007458 File Offset: 0x00005658 private CSharpCompilation CreateCompilation(string compilationContent, string assemblyName) { SourceText sourceText = SourceText.From(compilationContent, Encoding.UTF8, SourceHashAlgorithm.Sha1); SyntaxTree syntaxTree = this._csharpCompiler.CreateSyntaxTree(sourceText).WithFilePath(assemblyName); RoslynCompilationContext roslynCompilationContext = new RoslynCompilationContext(ExpressionRewriter.Rewrite(this._csharpCompiler.CreateCompilation(assemblyName).AddSyntaxTrees(new SyntaxTree[] { syntaxTree }))); this._compilationCallback(roslynCompilationContext); return(roslynCompilationContext.Compilation); }
private CSharpCompilation Rewrite(CSharpCompilation compilation) { var rewrittenTrees = new List<SyntaxTree>(); foreach (var tree in compilation.SyntaxTrees) { var semanticModel = compilation.GetSemanticModel(tree, ignoreAccessibility: true); var rewriter = new ExpressionRewriter(semanticModel); var rewrittenTree = tree.WithRootAndOptions(rewriter.Visit(tree.GetRoot()), tree.Options); rewrittenTrees.Add(rewrittenTree); } return compilation.RemoveAllSyntaxTrees().AddSyntaxTrees(rewrittenTrees); }
public void ExpressionRewriter_DoesNotThrowsOnUnknownTypes() { // Arrange var source = @" using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Razor; public class ExamplePage : RazorPage { public IViewComponentHelper Component { get; set; } public override async Task ExecuteAsync() { Write( await Component.InvokeAsync( ""SomeComponent"", item => new HelperResult((__razor_template_writer) => WriteLiteralTo(__razor_template_writer, ""Hello World"")))); } } "; var tree = CSharpSyntaxTree.ParseText(source); // Allow errors here because of an anomaly where Roslyn (depending on code sample) will finish compilation // without diagnostic errors. This test case replicates that scenario by allowing a semantic model with // errors to be visited by the expression rewriter to validate unexpected exceptions aren't thrown. // Error created: "Cannot convert lambda expression to type 'object' because it is not a delegate type." var compilation = Compile(tree, allowErrors: true); var semanticModel = compilation.GetSemanticModel(tree, ignoreAccessibility: true); var rewriter = new ExpressionRewriter(semanticModel); var root = tree.GetRoot(); // Act var result = rewriter.Visit(root); // Assert Assert.True(root.IsEquivalentTo(result)); }
public void ExpressionRewriter_CanRewriteExpression_SimpleFormatting() { // Arrange var source = @" using System; using System.Linq.Expressions; public class Program { public static void CalledWithExpression(Expression<Func<Person, int>> expression) { } public static void Main(string[] args) { CalledWithExpression(x => x.Name.Length); } } public class Person { public string Name { get; set; } } "; var tree = CSharpSyntaxTree.ParseText(source); var originalArguments = FindArguments(tree.GetRoot()); var originalSpan = originalArguments.GetLocation().GetMappedLineSpan(); var compilation = Compile(tree); var semanticModel = compilation.GetSemanticModel(tree, ignoreAccessibility: true); var rewriter = new ExpressionRewriter(semanticModel); // Act var result = rewriter.Visit(tree.GetRoot()); // Assert var arguments = FindArguments(result); Assert.Equal(originalSpan, arguments.GetLocation().GetMappedLineSpan()); }
public void ExpressionRewriter_CanRewriteExpression_MemberAccessExpression() { // Arrange var source = @" using System; using System.Linq.Expressions; public class Program { public static void CalledWithExpression(Expression<Func<Person, object>> expression) { } public static void Main(string[] args) { CalledWithExpression(x => x.Name); } } public class Person { public string Name { get; set; } } "; var tree = CSharpSyntaxTree.ParseText(source); var compilation = Compile(tree); var semanticModel = compilation.GetSemanticModel(tree, ignoreAccessibility: true); var rewriter = new ExpressionRewriter(semanticModel); // Act var result = rewriter.Visit(tree.GetRoot()); // Assert var fields = FindFields(result); var field = Assert.Single(fields); Assert.Collection( field.Modifiers, m => Assert.Equal("private", m.ToString()), m => Assert.Equal("static", m.ToString()), m => Assert.Equal("readonly", m.ToString())); var declaration = field.Declaration; Assert.Equal( "global::System.Linq.Expressions.Expression<global::System.Func<global::Person, object>>", declaration.Type.ToString()); var variable = Assert.Single(declaration.Variables); Assert.Equal("__h0", variable.Identifier.ToString()); Assert.Equal("x => x.Name", variable.Initializer.Value.ToString()); var arguments = FindArguments(result); var argument = Assert.IsType<IdentifierNameSyntax>(Assert.Single(arguments.Arguments).Expression); Assert.Equal("__h0", argument.Identifier.ToString()); }
//constructors public RealRewriter() { _rewriter = new ExpressionRewriter(exp => exp.NodeType == ExpressionType.Call && ((MethodCallExpression)exp).Method.Name == "Diff"); //Identity _rewriter.AppendRule <Func <double, double> >(x => 1.0 * x, x => x); _rewriter.AppendRule <Func <double, double> >(x => 0.0 * x, x => 0.0); _rewriter.AppendRule <Func <double, double> >(x => x + 0.0, x => x); _rewriter.AppendRule <Func <double, double> >(x => 0.0 + x, x => x); _rewriter.AppendRule <Func <double, double> >(x => Math.Pow(x, 1.0), x => x); _rewriter.AppendRule <Func <double, double> >(x => Math.Pow(1.0, x), x => 1.0); _rewriter.AppendRule <Func <double, double> >(x => Math.Pow(x, 0.0), x => 1.0); _rewriter.AppendRule <Func <double, double> >(x => Math.Pow(0.0, x), x => 0.0); //Commutation _rewriter.AppendRule <Func <double, double, double> >( p => p["y"].NodeType == ExpressionType.Constant && p["x"].NodeType != ExpressionType.Constant, (x, y) => x * y, (x, y) => y * x); //Association _rewriter.AppendRule <Func <double, double, double, double> >( p => p["x"].NodeType != ExpressionType.Constant || p["y"].NodeType == ExpressionType.Constant, (x, y, z) => x * (y * z), (x, y, z) => (x * y) * z); _rewriter.AppendRule <Func <double, double, double, double> >( p => p["x"].NodeType == ExpressionType.Constant && p["y"].NodeType != ExpressionType.Constant, (x, y, z) => (x * y) * z, (x, y, z) => x * (y * z)); //Distribution _rewriter.AppendRule <Func <double, double, double, double> >( p => p["y"].NodeType != ExpressionType.Constant || p["z"].NodeType != ExpressionType.Constant, (x, y, z) => x * (y + z), (x, y, z) => x * y + x * z); _rewriter.AppendRule <Func <double, double, double, double> >( p => p["y"].NodeType != ExpressionType.Constant || p["z"].NodeType != ExpressionType.Constant, (x, y, z) => (y + z) * x, (x, y, z) => y * x + z * x); //Factoring _rewriter.AppendRule <Func <double, double, double> >((x, y) => x / y, (x, y) => x * Math.Pow(y, -1.0)); _rewriter.AppendRule <Func <double, double, double> >((x, y) => x - y, (x, y) => x + -1.0 * y); _rewriter.AppendRule <Func <double, double> >(x => - x, x => - 1.0 * x); _rewriter.AppendRule <Func <double, double, double, double> >( p => p["y"].NodeType == ExpressionType.Constant && p["z"].NodeType == ExpressionType.Constant, (x, y, z) => (y * x) + (z * x), (x, y, z) => (y + z) * x); _rewriter.AppendRule <Func <double, double, double> >( p => p["y"].NodeType == ExpressionType.Constant, (x, y) => x + y * x, (x, y) => (y + 1.0) * x); _rewriter.AppendRule <Func <double, double, double> >( p => p["y"].NodeType == ExpressionType.Constant, (x, y) => y * x + x, (x, y) => (y + 1.0) * x); _rewriter.AppendRule <Func <double, double> >(x => x + x, x => 2.0 * x); //Exponentation _rewriter.AppendRule <Func <double, double> >( p => p["x"].NodeType != ExpressionType.Add, x => x * x, x => Math.Pow(x, 2.0)); _rewriter.AppendRule <Func <double, int, double> >( p => p["x"].NodeType != ExpressionType.Add, (x, y) => x * Math.Pow(x, y), (x, y) => Math.Pow(x, y + 1.0)); _rewriter.AppendRule <Func <int, double, double, double> >( p => p["x"].NodeType == ExpressionType.Constant && Math.Abs((double)((ConstantExpression)p["x"]).Value) > 1.0, (x, y, z) => Math.Pow(y + z, x), (x, y, z) => Math.Pow(y + z, x - 1.0) * (y + z)); _rewriter.AppendRule <Func <double, double, double, double> >((x, y, z) => Math.Pow(y * z, x), (x, y, z) => Math.Pow(y, x) * Math.Pow(z, x)); _rewriter.AppendRule <Func <double, double, double, double> >((x, y, z) => Math.Pow(Math.Pow(x, y), z), (x, y, z) => Math.Pow(x, y * z)); _rewriter.AppendRule <Func <double, double, double, double> >((x, y, z) => Math.Pow(x, y) * Math.Pow(x, z), (x, y, z) => Math.Pow(x, y + z)); _rewriter.AppendRule <Func <double, double> >(x => Math.Sqrt(x), x => Math.Pow(x, 0.5)); _rewriter.AppendRule <Func <double, double> >(x => Math.Log10(x), x => Math.Log(x, 10.0)); _rewriter.AppendRule <Func <double, double> >(x => Math.Abs(x) * Math.Abs(x), x => Math.Pow(x, 2.0)); //general differentation _rewriter.AppendRule <Func <double, double, double> >( (x, y) => MathExt2.Diff(x * y), (x, y) => MathExt2.Diff(x) * y + x * MathExt2.Diff(y)); _rewriter.AppendRule <Func <double, double, double> >( (x, y) => MathExt2.Diff(x + y), (x, y) => MathExt2.Diff(x) + MathExt2.Diff(y)); //simple differentiation _rewriter.AppendRule <Func <double, double> >( p => p["c"].NodeType == ExpressionType.Constant, c => MathExt2.Diff(c), c => 0.0); _rewriter.AppendRule <Func <double, double> >( p => p["x"].NodeType == ExpressionType.Parameter, x => MathExt2.Diff(x), x => 1.0); _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Abs(x)), x => MathExt2.Diff(x) * x * Math.Pow(Math.Abs(x), -1.0)); _rewriter.AppendRule <Func <double, double, double> >( p => p["c"].NodeType == ExpressionType.Constant, (x, c) => MathExt2.Diff(Math.Pow(x, c)), (x, c) => MathExt2.Diff(x) * c * Math.Pow(x, c - 1.0)); //exponential and logarithm differentiation _rewriter.AppendRule <Func <double, double, double> >( p => p["c"].NodeType == ExpressionType.Constant, (c, x) => MathExt2.Diff(Math.Pow(c, x)), (c, x) => MathExt2.Diff(x) * Math.Pow(c, x) * Math.Log(c)); _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Exp(x)), x => Math.Exp(x)); _rewriter.AppendRule <Func <double, double, double> >( p => p["c"].NodeType == ExpressionType.Constant, (c, x) => MathExt2.Diff(Math.Log(x, c)), (c, x) => MathExt2.Diff(x) * Math.Pow(x * Math.Log(c), -1.0)); _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Log(x)), x => MathExt2.Diff(x) * Math.Pow(x, -1.0)); _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Pow(x, x)), x => MathExt2.Diff(x) * Math.Pow(x, x) * (1.0 + Math.Log(x))); //trigonometric differentiation _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Sin(x)), x => MathExt2.Diff(x) * Math.Cos(x)); _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Cos(x)), x => MathExt2.Diff(x) * -1.0 * Math.Sin(x)); _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Tan(x)), x => MathExt2.Diff(x) * Math.Pow(Math.Cos(x), -2.0)); _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Asin(x)), x => MathExt2.Diff(x) * Math.Pow(1.0 - Math.Pow(x, 2.0), -0.5)); _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Acos(x)), x => MathExt2.Diff(x) * -1.0 * Math.Pow(1.0 - Math.Pow(x, 2.0), -0.5)); _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Atan(x)), x => MathExt2.Diff(x) * Math.Pow(1.0 + Math.Pow(x, 2.0), -1.0)); //hyperbolic differentiation _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Sinh(x)), x => MathExt2.Diff(x) * Math.Cosh(x)); _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Cosh(x)), x => MathExt2.Diff(x) * Math.Sinh(x)); _rewriter.AppendRule <Func <double, double> >( x => MathExt2.Diff(Math.Tan(x)), x => MathExt2.Diff(x) * Math.Pow(Math.Cosh(x), -2.0)); }
//constructors public DiophantineRewriter() { _rewriter = new ExpressionRewriter(); //Identity _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => 1 * x, x => x); _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => 0 * x, x => 0); _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => x + 0, x => x); _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => 0 + x, x => x); _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => x.Power(1), x => x); _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => x.Power(0), x => 1); //Commutation _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger> >( p => p["y"].NodeType == ExpressionType.Constant && p["x"].NodeType != ExpressionType.Constant, (x, y) => x * y, (x, y) => y * x); //Association _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger, BigInteger> >( p => p["x"].NodeType != ExpressionType.Constant || p["y"].NodeType == ExpressionType.Constant, (x, y, z) => x * (y * z), (x, y, z) => (x * y) * z); _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger, BigInteger> >( p => p["x"].NodeType == ExpressionType.Constant && p["y"].NodeType != ExpressionType.Constant, (x, y, z) => (x * y) * z, (x, y, z) => x * (y * z)); //Distribution _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger, BigInteger> >( p => p["y"].NodeType != ExpressionType.Constant || p["z"].NodeType != ExpressionType.Constant, (x, y, z) => x * (y + z), (x, y, z) => x * y + x * z); _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger, BigInteger> >( p => p["y"].NodeType != ExpressionType.Constant || p["z"].NodeType != ExpressionType.Constant, (x, y, z) => (y + z) * x, (x, y, z) => y * x + z * x); //Factoring //_rewriter.AppendRule<Func<BigInteger, BigInteger, BigInteger>>((x, y) => x / y, (x, y) => x * y.Power(-1)); _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger> >((x, y) => x - y, (x, y) => x + -1 * y); _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => - x, x => - 1 * x); _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger, BigInteger> >( p => p["y"].NodeType == ExpressionType.Constant && p["z"].NodeType == ExpressionType.Constant, (x, y, z) => (y * x) + (z * x), (x, y, z) => (y + z) * x); _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger> >( p => p["y"].NodeType == ExpressionType.Constant, (x, y) => x + y * x, (x, y) => (y + 1) * x); _rewriter.AppendRule <Func <BigInteger, BigInteger, BigInteger> >( p => p["y"].NodeType == ExpressionType.Constant, (x, y) => y * x + x, (x, y) => (y + 1) * x); _rewriter.AppendRule <Func <BigInteger, BigInteger> >(x => x + x, x => 2 * x); //Exponentation _rewriter.AppendRule <Func <BigInteger, BigInteger> >( p => p["x"].NodeType != ExpressionType.Add, x => x * x, x => x.Power(2)); _rewriter.AppendRule <Func <BigInteger, int, BigInteger> >( p => p["x"].NodeType != ExpressionType.Add, (x, y) => x * x.Power(y), (x, y) => x.Power(y + 1)); _rewriter.AppendRule <Func <int, BigInteger, BigInteger, BigInteger> >( p => p["x"].NodeType == ExpressionType.Constant && (int)((ConstantExpression)p["x"]).Value > 1, (x, y, z) => (y + z).Power(x), (x, y, z) => (y + z).Power(x - 1) * (y + z)); _rewriter.AppendRule <Func <int, BigInteger, BigInteger, BigInteger> >((x, y, z) => (y * z).Power(x), (x, y, z) => y.Power(x) * z.Power(x)); _rewriter.AppendRule <Func <BigInteger, int, int, BigInteger> >((x, y, z) => x.Power(y).Power(z), (x, y, z) => x.Power(y * z)); _rewriter.AppendRule <Func <BigInteger, int, int, BigInteger> >((x, y, z) => x.Power(y) * x.Power(z), (x, y, z) => x.Power(y + z)); }