Git Product home page Git Product logo

lambda2js's Introduction

Lambda2Js

This is an ExpressionTree (lambda) to Javascript converter.

It is portable, so that you can use it in most environments.

Its purpose is to convert a C# expression tree (from Linq name space) to a syntactically correct javascript code.

It can be extended to customize the mapping of expressions:

  • support custom static methods, instead of emitting code that would otherwise depend on external Javascript
  • support custom types, converting method calls and properties accordingly

It is well tested, and won't break. More than 140 tests passing.

This project uses Semantic versioning.

Installing NuGet package:

PM> Install-Package Lambda2Js

Samples

Converting lambda with boolean and numeric operations:

Expression<Func<MyClass, object>> expr = x => x.PhonesByName["Miguel"].DDD == 32 || x.Phones.Length != 1;
var js = expr.CompileToJavascript();
// js = PhonesByName["Miguel"].DDD===32||Phones.length!==1

Converting lambda with LINQ expression, containing an inner lambda:

Expression<Func<MyClass, object>> expr = x => x.Phones.FirstOrDefault(p => p.DDD > 10);
var js = expr.CompileToJavascript();
// js = System.Linq.Enumerable.FirstOrDefault(Phones,function(p){return p.DDD>10;})

Converting lambda with Linq Select method:

Expression<Func<string[], IEnumerable<char>>> expr = array => array.Select(x => x[0]);
var js = expr.CompileToJavascript(
    new JavascriptCompilationOptions(
        JsCompilationFlags.BodyOnly | JsCompilationFlags.ScopeParameter,
        new[] { new LinqMethods(), }));
// js = array.map(function(x){return x[0];})

Clone using ToArray and targeting ES6:

Expression<Func<string[], IEnumerable<string>>> expr = array => array.ToArray();
var js = expr.Body.CompileToJavascript(
    ScriptVersion.Es60,
    new JavascriptCompilationOptions(new LinqMethods()));
// js = [...array]

Developing custom plugins

You can develop and use some built-in plugins. See the readme.md in the Plugins folder.

Building and testing

ATENTION! Please, run the ProjectsGenerator before doing any of these:

  • build the signed assembly

  • running tests for specific frameworks

    Run Projects Generator

Due to current Visual Studio limitations, I had to create a project generator to create some of the csproj files:

  • Lambda2Js.Signed.csproj is generated using the Lambda2Js.csproj as it's template. It will copy the package version to the FileVersion and to the AssemblyVersion fields to keep them consistent. Also, it adds the ".Signed" string where appropriate in file names and in project name, and finally it includes a reference to the snk file.

  • Lambda2Js.Tests.$(TargetFramework).csproj are generated from Lambda2Js.Tests.csproj. That is needed because this project is a multitargeted test project, and Visual Studio cannot see the tests inside after compiling it... so what I did was: create copy projects that have only one target framework for each of the possible targets.

Testing

To test support on the .Net 4.0, you need to run the Test.Net-v4.0.csproj because this framework version does not support the native test attributes to do automatic testing.

To test other framework versions, please, take a look at the TargetedTests solution folder. In that folder you will find all the tests. Unload all of them, but keep the framework version you want to test, then build it. Visual Studio will see the newly built tests and will list them. If the other frameworks test projects are not unloaded, Visual Studio may or may not list them.

Errors while building test projects

Make sure to NOT LOAD MORE THAN ONE test project inside the TargetedTests solution folder.

  • Load a single test project

    Load Single Test Project

  • Update Test Framework Packages

    Update Test Framework Packages

lambda2js's People

Contributors

andrerpena avatar aviv86 avatar bgurmendi avatar bryantlikes avatar dependabot[bot] avatar devanarch avatar lahma avatar masbicudo avatar ppekrol avatar ysmoradi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lambda2js's Issues

built-in string function like ToLower() raise an exception

The following test case raise an exception:

    [TestMethod]
    public void Test2()
    {
        Expression<Func<MyClass, string>> expr = x => x.Name.ToLower();
        var js = expr.CompileToJavascript(new JavascriptCompilationOptions(JsCompilationFlags.ScopeParameter));          
        Assert.AreEqual("function(Name){return Name.toLowerCase();}", js);     
    }

Exception error:

      Test method Lambda2Js.Tests.GeneralTests.Test1 threw exception: 
       System.NotSupportedException: By default, Lambda2Js cannot convert custom instance methods, only static ones. `ToLower` is not static.

...

Can lambda2js support the built-in functions that have a corresponding one in js?
e.g the string method ToLower() ===> can be mapped to js toLowerCase()

Evaulate instead of generate

I need a tool that will take a C# LINQ Expression tree, like the input for this project, but rather than create JavaScript out of it, it evaluates it on demand -- it would be somewhat equivalent to creating JavaScript and then using a JavaScript interpreter on it. But what I want is given the expression tree, I want to actually evaluate it by interpreting on demand.

I realize I can call .Compile() on the expression and run it, but I can't do that for my project.

I'm thinking of starting with this project as an example and then removing the JavaScript generation code and replacing it with an interpreter. If I did that, are there any issues or limitations that you guys think I might run into?

net40 target has compability issues with .NET 4.5+ frameworks

I'm using Lambda2Js.Signed as a transitive dependency of RavenDb.Client in a .NET Framework 4.7.2 application.

Lambda2Js.Signed's NuGet package has a net40 lib and a netstandard1.0 lib. Since I'm using .NET Framework, NuGet package manager picks the latest .NET Framework version of the package, net40. This would be fine, except the net40 package has some compatbility definitions of types that exist in mscorlib in .NET 4.5 and later, such as System.Threading.Interlocked. Because of this, my application is full of warnings like warning CS1685: The predefined type 'System.Threading.Interlocked' is defined in multiple assemblies in the global alias; using definition from 'c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\mscorlib.dll'

I am able to manually edit my csproj to use the netstandard1.0 lib instead of net40, which resolves the issue. But any updates through NuGet package manager will reverse this, making this dependency fragile.

Would it be possible to add a new net45 lib to the NuGet package that doesn't contain the net40 compatibility types? This would help anyone on .NET Framework 4.5 or later.

NuGet package

Create a NuGet package and submit it to nuget.org

Cannot use UsedImplicitly attribute with the "WithInheritors" flag due to assembly versioning bug.

Hi, I am using the JetBrains.Annotations NuGet package and have experienced a compatibility issue with your Lambda2js NuGet package (which the jetbrains package uses as a dependency).

I reported the problem here: JetBrains/JetBrains.Annotations#4

Hi, I hope this is the right place to report a bug. I cannot use [UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)] in my codebase because there is a dependency issue with JetBrains.Annotations. It says:

The type 'ImplicitUseTargetFlags' exists in both 'JetBrains.Annotations, Version=2021.2.0.0, ...' and 'Lambda2Js.Signed, Version=3.1.3.0, ...',

but JetBrains.Annotations has a dependency on .NetStandard v1.0, and .NetStandard v1.0 has a dependency on that Lambda2Js.Signed package, so I cannot fix the dependency problem myself.

I want to use these flags (e.g., ImplicitUseTargetFlags) but can only use the UsedImplicitly attribute without flags. I hope this can get fixed as inheritance would be a great feature to use with these attributes. This would let me have a base class with the UsedImplicitly attribute and then all my derived classes would not need to also have this attribute and it can be assumed that if I'm deriving from the base class then it will be used implicitly (which is great for many design patterns). Thank you.

But they closed it and said I might want to open up an issue with your library instead.

Metadata is not considered when using member initialization

When serializing initialization like this:

public class MyClass
{
    [JsonProperty(PropertyName = "custom_name")]
    public string Name { get; set; }
}

public delegate object MyFuncDef(string name);

Expression<MyFuncDef> expr = name => new MyClass { Name = name };

var js = expr.CompileToJavascript(
        new JavascriptCompilationOptions(
            (JsCompilationFlags)0,
            MemberInitAsJson.ForAllTypes));

It does not work. Result is:

function(name){return {Name:name};}

But should be:

function(name){return {custom_name:name};}

Conditional ?: Operator result in blank result

usage of conditional ?: operator like:

Expression<Func<Tuple<bool,int>,int>> expr = row => row.Item1?2*row.Item2:1;
Console.WriteLine(expr.CompileToJavascript(new JavascriptCompilationOptions(JsCompilationFlags.BodyOnly)));

results in blank output:

Press any key to continue . . .

where one would expect:
row.Item1?2*row.Item2:1
Press any key to continue . . .

Next release

Hi, are there any plans for releasing version 3.1.1 with latest fixes?

Literal null on string type raises an exception

This new test throws a null pointer exception.

[TestMethod] public void NullLiteralToString() { Expression<Func<string>> expr = () => null; var js = expr.Body.CompileToJavascript(); Assert.AreEqual("null", js); }

Nuget package doesn't work with .NET 4.0 project

The current nuget package doesn't work with .NET 4.0 project and it seems it is because the lib has a folder for: portable-net403%2Bsl50%2Bwin%2Bwpa81%2Bwp80.

When I change it to: portable-net40%2Bsl50%2Bwin%2Bwpa81%2Bwp80 (I removed the 3 in net403)

Then it works.

Treat Enums as strings?

Hey @masbicudo, thanks for this great library!

I was wondering if there is a way to convert this...

x => x.SomeEnumProperty == MyEnum.HelloWorld

to this...

SomeEnumProperty === 'HelloWorld'

instead of this...

SomeEnumProperty === 0

Convert property names to camel case

In C# most property names follow the PascalCaseConvention. In JavaScript it's more common to use camelCaseConvention.

There should be an option to allow the conversion.

Can't handle basic consts??

I have the expression:

Expressions.Expression<Func<string, bool>> asd = x => x == "qwe";
Console.WriteLine(asd.CompileToJavascript());

This throws an NotSupportedException:
"The used constant value is not supported: False (Boolean)"

Kris

Sign DLLs

Is there a possibility for the DLLs to be signed? I'm getting following error:

CS8002: Referenced assembly 'Lambda2Js, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have a strong name.

Using '3.0.1' NuGet package. The '1.0.0.0' also means that the File version is not set.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.