public static void Apply(RoslynCompiler compiler, Options options = null, Scope scope = null) { scope?.AddKeywords("concurrent", "spawn", "await"); scope?.set <Options>(options); if (options == null) { options = new Options(); } var lexical = compiler.Lexical(); lexical .match() .token("concurrent", named: "keyword") .token("class", named: "ref") .then(lexical.transform() .remove("keyword") .then(CompileClass(options))) .match() .token("concurrent", named: "keyword") .token("object", named: "ref") .then(lexical.transform() .remove("keyword") .replace("ref", "class ") .then(CompileObject(options))) .match() .token("concurrent", named: "keyword") .token("app", named: "ref") .token("{") .then(lexical.transform() .replace("keyword", "class ") .replace("ref", "__app") .then(CompileApp(options))); compiler.Syntax() .match <MethodDeclarationSyntax>(IsConcurrentFunction, "after-syntax") .then(CompileFunction); compiler.Environment() .dependency(new[] { "System.Threading", "System.Threading.Tasks", }) .dependency <ConcurrentObject>("Excess.Concurrent.Runtime"); }
public void SyntacticalMatching_Usage() { RoslynCompiler compiler = new RoslynCompiler(); var syntax = compiler.Syntax(); //simple match syntax .match <ClassDeclarationSyntax>(c => !c.Members.OfType <ConstructorDeclarationSyntax>().Any()) .then(addConstructor); var tree = compiler.ApplySyntacticalPass("class foo { } class bar { bar() {} }"); Assert.IsTrue(tree .GetRoot() .DescendantNodes() .OfType <ConstructorDeclarationSyntax>() .Count() == 2); //must have added a constructor to "foo" //scope match & transform syntax .match <ClassDeclarationSyntax>(c => c.Identifier.ToString() == "foo") .descendants <MethodDeclarationSyntax>(named: "methods") .descendants <PropertyDeclarationSyntax>(prop => prop.Identifier.ToString().StartsWith("my"), named: "myProps") .then(syntax.transform() .replace("methods", method => ((MethodDeclarationSyntax)method) .WithIdentifier(CSharp.ParseToken("my" + ((MethodDeclarationSyntax)method).Identifier.ToString()))) .remove("myProps")); var scopeTree = compiler.ApplySyntacticalPass("class foo { public void Method() {} int myProp {get; set;} }"); Assert.IsTrue(scopeTree.ToString() == "class foo { public void myMethod() {} foo (){}}"); Assert.IsTrue(scopeTree .GetRoot() .DescendantNodes() .OfType <ConstructorDeclarationSyntax>() .Count() == 1); //must have added a constructor to "foo", since the syntax is the same }
public void SyntacticalExtensions_Usage() { RoslynCompiler compiler = new RoslynCompiler(); var syntax = compiler.Syntax(); SyntaxTree tree; //code extension syntax .extension("codeExtension", ExtensionKind.Code, codeExtension); tree = compiler.ApplySyntacticalPass("class foo { void bar() {codeExtension() {bar();}} }"); Assert.IsTrue(tree .GetRoot() .DescendantNodes() .OfType <StatementSyntax>() .Count() == 5); //must have added a couple of statements tree = compiler.ApplySyntacticalPass("class foo { void bar() {var ce = codeExtension() {bar();}} }"); var localDeclStatement = tree .GetRoot() .DescendantNodes() .OfType <LocalDeclarationStatementSyntax>() .FirstOrDefault(); Assert.IsNotNull(localDeclStatement); Assert.AreEqual(localDeclStatement.ToString(), "var ce = bar(7);"); tree = compiler.ApplySyntacticalPass("class foo { void bar() {ce = codeExtension() {bar();}} }"); var assignmentStatement = tree .GetRoot() .DescendantNodes() .OfType <ExpressionStatementSyntax>() .FirstOrDefault(); Assert.IsNotNull(assignmentStatement); Assert.AreEqual(assignmentStatement.ToString(), "ce = bar(7);"); //member extension syntax .extension("memberExtension", ExtensionKind.Member, memberExtension); tree = compiler.ApplySyntacticalPass("class foo { memberExtension(param: \"foobar\") {int x = 3;} }"); var method = tree .GetRoot() .DescendantNodes() .OfType <MethodDeclarationSyntax>() .FirstOrDefault(); Assert.IsNotNull(method); Assert.AreEqual(method.ParameterList.Parameters.Count, 0); Assert.AreEqual(method.Body.Statements.Count, 3); //type extension syntax .extension("typeExtension", ExtensionKind.Type, typeExtension); tree = compiler.ApplySyntacticalPass("public typeExtension foo(param: \"foobar\") { bar(); }"); var @class = tree .GetRoot() .DescendantNodes() .OfType <ClassDeclarationSyntax>() .FirstOrDefault(); Assert.IsNotNull(@class); Assert.AreEqual(@class.Identifier.ToString(), "foo"); var classMethod = @class .Members .OfType <MethodDeclarationSyntax>() .FirstOrDefault(); Assert.IsNotNull(classMethod); Assert.IsTrue(classMethod .Body .DescendantNodes() .OfType <ExpressionStatementSyntax>() .Count() == 1); }
public void SyntacticalExtensions() { RoslynCompiler compiler = new RoslynCompiler(); var syntax = compiler.Syntax(); SyntaxTree tree; //code extension syntax .extension("codeExtension", ExtensionKind.Code, codeExtension); tree = compiler.ApplySyntacticalPass("class foo { void bar() {codeExtension() {bar();}} }"); Assert.IsTrue(tree .GetRoot() .DescendantNodes() .OfType<StatementSyntax>() .Count() == 5); //must have added a couple of statements tree = compiler.ApplySyntacticalPass("class foo { void bar() {var ce = codeExtension() {bar();}} }"); var localDeclStatement = tree .GetRoot() .DescendantNodes() .OfType<LocalDeclarationStatementSyntax>() .FirstOrDefault(); Assert.IsNotNull(localDeclStatement); Assert.AreEqual(localDeclStatement.ToString(), "var ce = bar(7);"); tree = compiler.ApplySyntacticalPass("class foo { void bar() {ce = codeExtension() {bar();}} }"); var assignmentStatement = tree .GetRoot() .DescendantNodes() .OfType<ExpressionStatementSyntax>() .FirstOrDefault(); Assert.IsNotNull(assignmentStatement); Assert.AreEqual(assignmentStatement.ToString(), "ce = bar(7);"); //member extension syntax .extension("memberExtension", ExtensionKind.Member, memberExtension); tree = compiler.ApplySyntacticalPass("class foo { memberExtension(param: \"foobar\") {int x = 3;} }"); var method = tree .GetRoot() .DescendantNodes() .OfType<MethodDeclarationSyntax>() .FirstOrDefault(); Assert.IsNotNull(method); Assert.AreEqual(method.ParameterList.Parameters.Count, 0); Assert.AreEqual(method.Body.Statements.Count, 3); //type extension syntax .extension("typeExtension", ExtensionKind.Type, typeExtension); tree = compiler.ApplySyntacticalPass("public typeExtension foo(param: \"foobar\") { bar(); }"); var @class = tree .GetRoot() .DescendantNodes() .OfType<ClassDeclarationSyntax>() .FirstOrDefault(); Assert.IsNotNull(@class); Assert.AreEqual(@class.Identifier.ToString(), "foo"); var classMethod = @class .Members .OfType<MethodDeclarationSyntax>() .FirstOrDefault(); Assert.IsNotNull(classMethod); Assert.IsTrue(classMethod .Body .DescendantNodes() .OfType<ExpressionStatementSyntax>() .Count() == 1); }
public void SyntacticalMatching() { RoslynCompiler compiler = new RoslynCompiler(); var syntax = compiler.Syntax(); //simple match syntax .match<ClassDeclarationSyntax>(c => !c.Members.OfType<ConstructorDeclarationSyntax>().Any()) .then(addConstructor); var tree = compiler.ApplySyntacticalPass("class foo { } class bar { bar() {} }"); Assert.IsTrue(tree .GetRoot() .DescendantNodes() .OfType<ConstructorDeclarationSyntax>() .Count() == 2); //must have added a constructor to "foo" //scope match & transform syntax .match<ClassDeclarationSyntax>(c => c.Identifier.ToString() == "foo") .descendants<MethodDeclarationSyntax>(named: "methods") .descendants<PropertyDeclarationSyntax>(prop => prop.Identifier.ToString().StartsWith("my"), named: "myProps") .then(syntax.transform() .replace("methods", method => ((MethodDeclarationSyntax)method) .WithIdentifier(CSharp.ParseToken("my" + ((MethodDeclarationSyntax)method).Identifier.ToString()))) .remove("myProps")); var scopeTree = compiler.ApplySyntacticalPass("class foo { public void Method() {} int myProp {get; set;} }"); Assert.IsTrue(scopeTree.ToString() == "class foo { public void myMethod() {} foo (){}}"); Assert.IsTrue(scopeTree .GetRoot() .DescendantNodes() .OfType<ConstructorDeclarationSyntax>() .Count() == 1); //must have added a constructor to "foo", since the syntax is the same }