├── .gitattributes ├── .gitignore ├── Drawings └── RoslynCodeAsData.vsd ├── MetaProgramming ├── .nuget │ ├── NuGet.Config │ ├── NuGet.exe │ └── NuGet.targets ├── MetaProgramming.Nemerle.Macro │ ├── EmptyMacro.n │ ├── Fault.n │ ├── MetaProgramming.Nemerle.Macro.nproj │ ├── Properties │ │ └── AssemblyInfo.n │ └── TestMacro.n ├── MetaProgramming.Nemerle.Tests.CSharp │ ├── FaultKeywordTests.cs │ ├── MacroTests.cs │ ├── MetaProgramming.Nemerle.Tests.CSharp.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── MetaProgramming.Nemerle │ ├── CompileTimeVsRunTimeExecutionSample.n │ ├── FaultKeywordSample.n │ ├── MetaProgramming.Nemerle.nproj │ └── Properties │ │ └── AssemblyInfo.n ├── MetaProgramming.RoslynCTP.Tests │ ├── ClassTemplateInfos.json │ ├── CodeAsDataTests.ScriptAsData_ConvertJsonToScript_ScriptSubmission.approved.txt │ ├── CodeAsDataTests.cs │ ├── CodeSmells.Samples │ │ ├── .nuget │ │ │ ├── NuGet.Config │ │ │ ├── NuGet.exe │ │ │ └── NuGet.targets │ │ ├── ClassWithExtraComplexity.cs │ │ ├── ClassWithReturnNullMethods.cs │ │ ├── CodeSmells.Samples.csproj │ │ ├── CodeSmells.Samples.sln │ │ └── Properties │ │ │ └── AssemblyInfo.cs │ ├── ConverterTests.CSharp2VB_Convert_ValidCode.approved.txt │ ├── ConverterTests.VB2CSharp_Convert_ValidCode.approved.txt │ ├── ConverterTests.cs │ ├── InputData.json │ ├── IntrospectionTests.cs │ ├── IntrospectionTests`1.Introspection_SearchForComplexityGt10_ApprovedList.Integration.approved.txt │ ├── IntrospectionTests`1.Introspection_SearchForComplexityGt10_ApprovedList.UnitTests.approved.txt │ ├── IntrospectionTests`1.Introspection_SearchForReturnNullStatements_ApprovedList.Integration.approved.txt │ ├── IntrospectionTests`1.Introspection_SearchForReturnNullStatements_ApprovedList.UnitTests.approved.txt │ ├── MetaProgramming.RoslynCTP.Tests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RuntimeTextTemplateTests.RuntimeTextTemplate_TransformText_ExpectedOutput.approved.txt │ ├── RuntimeTextTemplateTests.cs │ ├── ScriptInfo.json │ ├── Strategy │ │ ├── CodeSmellsIntrospectionFixture.cs │ │ ├── IIntrospectionFixture.cs │ │ ├── IntegrationIntrospectionFixture.cs │ │ └── StrategyNamer.cs │ └── packages.config ├── MetaProgramming.RoslynCTP │ ├── CSharpToVisualBasicConverter │ │ ├── CSharpToVisualBasicConverter.csproj │ │ ├── Cleanup │ │ │ ├── CurlyCleanup.cs │ │ │ ├── MissingCurlyCleanup.cs │ │ │ ├── NewLineCleanup.cs │ │ │ └── WhiteSpaceCleanup.cs │ │ ├── Converting │ │ │ ├── Converter.NodeVisitor.cs │ │ │ ├── Converter.StatementVisitor.ForStatement.cs │ │ │ ├── Converter.StatementVisitor.cs │ │ │ └── Converter.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── Utilities │ │ │ ├── CSharpExtensions.cs │ │ │ ├── EnumerableExtensions.cs │ │ │ └── StringExtensions.cs │ │ └── packages.config │ ├── CodeAsData.cs │ ├── ConvertTo.cs │ ├── Internal │ │ └── PredicateBuilder.cs │ ├── Introspection.cs │ ├── MetaProgramming.RoslynCTP.csproj │ ├── Model │ │ ├── ClassTemplateInfo.cs │ │ └── ScriptInfo.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RuntimeTextTemplate.cs │ ├── RuntimeTextTemplate.tt │ ├── VisualBasicToCSharpConverter │ │ ├── Converting │ │ │ ├── Converter.vb │ │ │ ├── NodeConvertingVisitor.vb │ │ │ └── QueryClauseConvertingVisitor.vb │ │ ├── My Project │ │ │ └── AssemblyInfo.vb │ │ ├── VisualBasicToCSharpConverter.vbproj │ │ └── packages.config │ └── packages.config ├── MetaProgramming.sln └── README.md ├── Presentation ├── README.md ├── apple-touch-icon.png ├── architectural_validation_in_dotnet.html ├── css │ ├── architectural_validation.css │ ├── metaprogramming.css │ ├── metaprogramming_roslyn_and_nemerle.css │ └── scriptcs_for_project-less_development.css ├── images │ ├── CodeAsData_ConvertVBtoCSharp.png │ ├── FreeBSD-No-Bikeshed.png │ ├── IronPythonScript.png │ ├── JavaScriptMetaprogrammingViaScripting.pdn │ ├── JavaScriptMetaprogrammingViaScripting_00_Begin.png │ ├── JavaScriptMetaprogrammingViaScripting_01_SimpleMultiplication.png │ ├── JavaScriptMetaprogrammingViaScripting_02_UseFunctionDynamicly.png │ ├── JavaScriptMetaprogrammingViaScripting_03_InjectionValuesIntoLocalExecutionScope.png │ ├── JavaScript_Eval_vs_Roslyn_ScriptEngine.png │ ├── RoslynInspection_CalculateCyclomaticComplexity.png │ ├── RoslynSyntaxTree_00.png │ ├── chocolatey.png │ ├── hotcode_logo.png │ ├── introspection_return_null_with_approvaltests.png │ ├── itera_logo.png │ ├── nemerle_compiletime_macro_execution.png │ ├── nodejs.png │ ├── npm.png │ ├── nuget.png │ ├── postsharp_validation_aspect-virtual_keyword_is_required.png │ ├── roslyn_ctp_compiler_pipeline_api_and_services.png │ ├── roslyn_syntax_tree_for_return_null.png │ ├── scriptcs.png │ ├── scriptcs_execution_screenshot.png │ └── type_name_collision.png ├── js │ ├── architectural_validation.js │ ├── impress.js │ ├── jquery-ui.min.js │ ├── jquery.jsPlumb-1.5.2-min.js │ ├── jquery.min.js │ └── metaprogramming_roslyn.js ├── metaprogramming_in_dotnet_roslynctp.html ├── metaprogramming_in_dotnet_roslynctp_and_nemerle.html └── scriptcs_for_project-less_development.html ├── README.md └── Snippets ├── CaaS ├── CodeDOM-BuildAtRuntime.linq ├── CodeDOM-BuildAtRuntimeCSharp45.linq └── Roslyn-BuildAtRuntime.linq ├── CodeAsData ├── Roslyn-ConvertC#2VB.linq └── Roslyn-ConvertVB2C#.linq ├── Introspection ├── AfterProgramming-ReturnNull.csx ├── AfterProgramming-ReturnNull.linq ├── OptionTypeAndNull.linq ├── Reflection-TestReferencesIntersection.linq ├── Roslyn-CyclomaticComplexity.linq ├── Roslyn-CyclomaticComplexityRx.linq ├── Roslyn-ReturnNull.linq ├── Roslyn-ReturnNullRx.linq ├── Roslyn-ReturnNullSyntaxWalker.linq └── packages.config ├── Other ├── Roslyn-C#compilerIssues.csx └── SyntaxTreesSamples.cs ├── Performance ├── C#-HardCodedRule.linq ├── DLR-ExpressionTrees.linq └── Roslyn-ScriptingWithStaticlyTypedResult.linq ├── README.md └── Scripting ├── IronPython-Scripting.linq ├── JsEvalSample.html ├── JsEvalSample.md ├── README.md ├── Roslyn-EvalSample.csx ├── Roslyn-EvalSample.linq ├── Roslyn-ScriptingWithDynamiclyTypeResult.linq ├── ScriptCs ├── Edge.js │ ├── EdgeJs2ClrSample.js │ ├── EdgeJs2ProjectlessCsx.js │ └── ProjectlessCsx.csx ├── EmbededScriptCsWithNuGetSupport.csx ├── FluentAutomation.SeleniumWebDriver │ ├── FluentAutomation.SeleniumWebDriver.csx │ └── packages.config ├── README.md ├── ScriptCs-ScriptingFromC#.linq ├── ScriptCs.WebApi.Sample.csx ├── SeleniumWebDriver │ ├── SeleniumWebDriver.FireFox.csx │ ├── SeleniumWebDriver.PhantomJs.csx │ └── packages.config └── packages.config ├── packages.config └── sample.py /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | *.ide 16 | 17 | # Build results 18 | [Dd]ebug/ 19 | [Rr]elease/ 20 | x64/ 21 | *_i.c 22 | *_p.c 23 | *.ilk 24 | *.meta 25 | *.obj 26 | *.pch 27 | *.pdb 28 | *.pgc 29 | *.pgd 30 | *.rsp 31 | *.sbr 32 | *.tlb 33 | *.tli 34 | *.tlh 35 | *.tmp 36 | *.log 37 | *.vspscc 38 | *.vssscc 39 | .builds 40 | 41 | # Visual C++ cache files 42 | ipch/ 43 | *.aps 44 | *.ncb 45 | *.opensdf 46 | *.sdf 47 | 48 | # Visual Studio profiler 49 | *.psess 50 | *.vsp 51 | *.vspx 52 | 53 | # Guidance Automation Toolkit 54 | *.gpState 55 | 56 | # ReSharper is a .NET coding add-in 57 | _ReSharper* 58 | 59 | # NCrunch 60 | *.ncrunch* 61 | .*crunch*.local.xml 62 | 63 | # Installshield output folder 64 | [Ee]xpress 65 | 66 | # DocProject is a documentation generator add-in 67 | DocProject/buildhelp/ 68 | DocProject/Help/*.HxT 69 | DocProject/Help/*.HxC 70 | DocProject/Help/*.hhc 71 | DocProject/Help/*.hhk 72 | DocProject/Help/*.hhp 73 | DocProject/Help/Html2 74 | DocProject/Help/html 75 | 76 | # Click-Once directory 77 | publish 78 | 79 | # Publish Web Output 80 | *.Publish.xml 81 | 82 | # NuGet Packages Directory 83 | packages 84 | 85 | # Windows Azure Build Output 86 | csx 87 | *.build.csdef 88 | 89 | # Windows Store app package directory 90 | AppPackages/ 91 | 92 | # Others 93 | [Bb]in 94 | [Oo]bj 95 | sql 96 | TestResults 97 | [Tt]est[Rr]esult* 98 | *.Cache 99 | ClientBin 100 | [Ss]tyle[Cc]op.* 101 | ~$* 102 | *.dbmdl 103 | Generated_Code #added for RIA/Silverlight projects 104 | 105 | # Backup & report files from converting an old project file to a newer 106 | # Visual Studio version. Backup files are not needed, because we have git ;-) 107 | _UpgradeReport_Files/ 108 | Backup*/ 109 | UpgradeLog*.XML 110 | 111 | # ApprovalTests 112 | *.received.txt 113 | 114 | # Selenium PNGs 115 | test*.png 116 | 117 | # Node.js modules 118 | node_modules 119 | 120 | # Sublime projects/workspaces 121 | *.sublime-* 122 | 123 | #Video 124 | video -------------------------------------------------------------------------------- /Drawings/RoslynCodeAsData.vsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Drawings/RoslynCodeAsData.vsd -------------------------------------------------------------------------------- /MetaProgramming/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MetaProgramming/.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/MetaProgramming/.nuget/NuGet.exe -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle.Macro/EmptyMacro.n: -------------------------------------------------------------------------------- 1 | using Nemerle; 2 | using Nemerle.Collections; 3 | using Nemerle.Compiler; 4 | using Nemerle.Text; 5 | using Nemerle.Utility; 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | 11 | namespace MetaProgramming.Nemerle.Macro 12 | { 13 | public macro Macro1() 14 | { 15 | <[ () ]> 16 | } 17 | } -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle.Macro/Fault.n: -------------------------------------------------------------------------------- 1 | using Nemerle; 2 | using Nemerle.Collections; 3 | using Nemerle.Compiler; 4 | using Nemerle.Text; 5 | using Nemerle.Utility; 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | 11 | namespace MetaProgramming.Nemerle.Macro 12 | { 13 | macro execute(body, actionOnFault, actionOnFinally) 14 | syntax ( 15 | "try", 16 | body, 17 | "fault", 18 | actionOnFault, 19 | "finally", 20 | actionOnFinally) 21 | { 22 | <[ 23 | try 24 | { 25 | $body; 26 | } 27 | catch 28 | { 29 | | e is System.Exception => { $actionOnFault; throw; } 30 | } 31 | finally 32 | { 33 | $actionOnFinally; 34 | } 35 | ]> 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle.Macro/MetaProgramming.Nemerle.Macro.nproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | 3bb3e243-467a-42d5-878f-0f1aa26195a5 9 | Library 10 | Properties 11 | MetaProgramming.Nemerle.Macro 12 | MetaProgramming.Nemerle.Macro 13 | v4.5 14 | 512 15 | true 16 | Net-4.5 17 | $(ProgramFiles)\Nemerle 18 | $(NemerleBinPathRoot)\$(NemerleVersion) 19 | MetaProgramming.Nemerle.Macro 20 | 21 | 22 | true 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | false 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | $(OutputPath)\$(AssemblyName).xml 37 | 38 | 39 | 40 | 41 | 42 | 3.5 43 | 44 | 45 | 3.5 46 | 47 | 48 | 3.5 49 | 50 | 51 | 52 | 53 | False 54 | $(Nemerle)\Nemerle.dll 55 | 56 | 57 | False 58 | $(Nemerle)\Nemerle.Compiler.dll 59 | 60 | 61 | $(Nemerle)\Nemerle.Linq.dll 62 | 63 | 64 | 65 | 66 | Code 67 | 68 | 69 | 70 | 71 | Code 72 | 73 | 74 | 75 | 76 | 77 | 78 | 87 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle.Macro/Properties/AssemblyInfo.n: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: Nemerle.Macro.Resource(@"Properties\Resources.resx")] 6 | [assembly: Nemerle.Macro.Settings(@"Properties\Settings.settings")] 7 | 8 | // General Information about an assembly is controlled through the following 9 | // set of attributes. Change these attribute values to modify the information 10 | // associated with an assembly. 11 | [assembly: AssemblyTitle("MetaProgramming.Nemerle.Macro")] 12 | [assembly: AssemblyDescription("")] 13 | [assembly: AssemblyConfiguration("")] 14 | [assembly: AssemblyCompany("")] 15 | [assembly: AssemblyProduct("MetaProgramming.Nemerle.Macro")] 16 | [assembly: AssemblyCopyright("Copyright © 2013")] 17 | [assembly: AssemblyTrademark("")] 18 | [assembly: AssemblyCulture("")] 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | // The following GUID is for the ID of the typelib if this project is exposed to COM 26 | [assembly: Guid("3bb3e243-467a-42d5-878f-0f1aa26195a5")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // 30 | // Major Version 31 | // Minor Version 32 | // Build Number 33 | // Revision 34 | // 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle.Macro/TestMacro.n: -------------------------------------------------------------------------------- 1 | using System; 2 | using Nemerle; 3 | using Nemerle.Collections; 4 | using Nemerle.Compiler; 5 | using Nemerle.Text; 6 | using Nemerle.Utility; 7 | 8 | namespace MetaProgramming.Nemerle.Macro 9 | { 10 | // Test macros to show difference between compile time and runtime execution 11 | public macro TestMacro(inputAST) 12 | { 13 | Console.WriteLine("Compile-time execution: '{0}' of type {1}\n", 14 | inputAST, inputAST.GetType()); 15 | 16 | <[ Console.WriteLine("Run-time execution: {0} of type {1}\n", 17 | $inputAST, $inputAST.GetType()) ]>; 18 | } 19 | 20 | // Expected console output during build 21 | // 3> Compile-time execution: '"literal"' of type Nemerle.Compiler.Parsetree.PExpr+Literal 22 | // 3> Compile-time execution: 'x' of type Nemerle.Compiler.Parsetree.PExpr+Ref 23 | } 24 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle.Tests.CSharp/FaultKeywordTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using FluentAssertions; 3 | using NUnit.Framework; 4 | 5 | namespace MetaProgramming.Nemerle.Tests.CSharp 6 | { 7 | [TestFixture] 8 | public class FaultKeywordTests 9 | { 10 | [Test] 11 | public void FaultKeywordAtNemerle_NormalFlow_BodyHasBeenExecuted() 12 | { 13 | var finallyHasBeenExecuted = false; 14 | var uniqueString = Guid.NewGuid().ToString(); 15 | 16 | new FaultKeywordSample() 17 | .ExecuteFaultCSharpNemerle( 18 | () => uniqueString, 19 | () => { throw new Exception("Should not execute `fault`"); }, 20 | () => { finallyHasBeenExecuted = true; }) 21 | .Should().Be(uniqueString); 22 | 23 | finallyHasBeenExecuted.Should().BeTrue(); 24 | } 25 | 26 | [Test] 27 | public void FaultKeywordAtNemerle_ExceptionalFlow_BothBodyAndFaultHadBeenExecuted() 28 | { 29 | var bodyHasBeenExecuted = false; 30 | var faultHasBeenExecuted = false; 31 | var finallyHasBeenExecuted = false; 32 | var uniqueExceptionalMessage = string.Format("Exceptional Flow {0}", Guid.NewGuid()); 33 | 34 | Action act = () => 35 | new FaultKeywordSample() 36 | .ExecuteFaultCSharpNemerle( 37 | () => 38 | { 39 | bodyHasBeenExecuted = true; 40 | throw new Exception(uniqueExceptionalMessage); 41 | }, 42 | () => { faultHasBeenExecuted = true; }, 43 | () => { finallyHasBeenExecuted = true; }); 44 | 45 | act.ShouldThrow() 46 | .WithMessage(uniqueExceptionalMessage); 47 | 48 | bodyHasBeenExecuted.Should().BeTrue(); 49 | faultHasBeenExecuted.Should().BeTrue(); 50 | finallyHasBeenExecuted.Should().BeTrue(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle.Tests.CSharp/MacroTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | 4 | namespace MetaProgramming.Nemerle.Tests.CSharp 5 | { 6 | [TestFixture] 7 | public class MacroTests 8 | { 9 | [Test] 10 | public void CompileTimeVsRunTime_Execution_ExpectedOutput() 11 | { 12 | string result = new CompileTimeVsRunTimeExecutionSample().Execute(); 13 | 14 | result.Should().Be("output"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle.Tests.CSharp/MetaProgramming.Nemerle.Tests.CSharp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {44555B43-900C-4F80-B77B-D2C751788BA1} 8 | Library 9 | Properties 10 | MetaProgramming.Nemerle.Tests.CSharp 11 | MetaProgramming.Nemerle.Tests.CSharp 12 | v4.5 13 | 512 14 | ..\ 15 | true 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\packages\FluentAssertions.2.0.1\lib\net45\FluentAssertions.dll 37 | 38 | 39 | ..\packages\NUnit.2.6.2\lib\nunit.framework.dll 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | {eee410f7-10df-452f-a2a5-d073ad12efd6} 60 | MetaProgramming.Nemerle 61 | 62 | 63 | 64 | 65 | 72 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle.Tests.CSharp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MetaProgramming.Nemerle.Tests.CSharp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MetaProgramming.Nemerle.Tests.CSharp")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5a7bdbe2-b796-4088-89ed-6f22b584a189")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle.Tests.CSharp/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle/CompileTimeVsRunTimeExecutionSample.n: -------------------------------------------------------------------------------- 1 | using Nemerle.Collections; 2 | using Nemerle.Text; 3 | using Nemerle.Utility; 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | 9 | using MetaProgramming.Nemerle.Macro; 10 | 11 | namespace MetaProgramming.Nemerle 12 | { 13 | public class CompileTimeVsRunTimeExecutionSample 14 | { 15 | public Execute() : string 16 | { 17 | TestMacro("literal"); 18 | 19 | def x = 1 + 2; 20 | 21 | TestMacro(x); 22 | 23 | "output"; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle/FaultKeywordSample.n: -------------------------------------------------------------------------------- 1 | using Nemerle; 2 | using Nemerle.Collections; 3 | using Nemerle.Text; 4 | using Nemerle.Utility; 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | 10 | using MetaProgramming.Nemerle.Macro; 11 | 12 | namespace MetaProgramming.Nemerle 13 | { 14 | public partial class FaultKeywordSample 15 | { 16 | public ExecuteFaultCSharpNemerle(body : Func[string], onFault : Action, onFinally : Action) : string 17 | { 18 | mutable result : string = null; 19 | 20 | try 21 | { 22 | result = body(); 23 | } 24 | fault // here is a _new keyword_ `fault` only executed after exceptions 25 | { 26 | onFault(); 27 | } 28 | finally 29 | { 30 | onFinally(); 31 | } 32 | 33 | result; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle/MetaProgramming.Nemerle.nproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | eee410f7-10df-452f-a2a5-d073ad12efd6 9 | Library 10 | Properties 11 | MetaProgramming.Nemerle 12 | MetaProgramming.Nemerle 13 | v4.5 14 | 512 15 | true 16 | Net-4.5 17 | $(ProgramFiles)\Nemerle 18 | $(NemerleBinPathRoot)\$(NemerleVersion) 19 | MetaProgramming.Nemerle 20 | 21 | 22 | true 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | false 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | $(OutputPath)\$(AssemblyName).xml 37 | 38 | 39 | 40 | 41 | 42 | 3.5 43 | 44 | 45 | 3.5 46 | 47 | 48 | 3.5 49 | 50 | 51 | 52 | 53 | False 54 | $(Nemerle)\Nemerle.dll 55 | True 56 | 57 | 58 | $(Nemerle)\Nemerle.Linq.dll 59 | 60 | 61 | 62 | 63 | 64 | Code 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | MetaProgramming.Nemerle.Macro 74 | {3bb3e243-467a-42d5-878f-0f1aa26195a5} 75 | False 76 | 77 | 78 | 79 | 88 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.Nemerle/Properties/AssemblyInfo.n: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: Nemerle.Macro.Resource(@"Properties\Resources.resx")] 6 | [assembly: Nemerle.Macro.Settings(@"Properties\Settings.settings")] 7 | 8 | // General Information about an assembly is controlled through the following 9 | // set of attributes. Change these attribute values to modify the information 10 | // associated with an assembly. 11 | [assembly: AssemblyTitle("MetaProgramming.Nemerle")] 12 | [assembly: AssemblyDescription("")] 13 | [assembly: AssemblyConfiguration("")] 14 | [assembly: AssemblyCompany("")] 15 | [assembly: AssemblyProduct("MetaProgramming.Nemerle")] 16 | [assembly: AssemblyCopyright("Copyright © 2013")] 17 | [assembly: AssemblyTrademark("")] 18 | [assembly: AssemblyCulture("")] 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | // The following GUID is for the ID of the typelib if this project is exposed to COM 26 | [assembly: Guid("eee410f7-10df-452f-a2a5-d073ad12efd6")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // 30 | // Major Version 31 | // Minor Version 32 | // Build Number 33 | // Revision 34 | // 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/ClassTemplateInfos.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name" : "ProcessingModel", 4 | "IsPublic" : true, 5 | "Properties" : 6 | { 7 | "InputA" : "System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 8 | "InputB" : "System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 9 | "Factor" : "System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 10 | "Result" : "System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 11 | "Delta" : "System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 12 | "Description" : "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 13 | "Addition" : "System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 14 | } 15 | }, 16 | 17 | { 18 | "Name" : "ReportModel", 19 | "IsPublic" : true, 20 | "Properties" : 21 | { 22 | "Σ" : "System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 23 | "Δ" : "System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 24 | "λ" : "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 25 | } 26 | } 27 | ] -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/CodeAsDataTests.ScriptAsData_ConvertJsonToScript_ScriptSubmission.approved.txt: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Σ": 10.2500, 4 | "Δ": 0.2500, 5 | "λ": "Some description" 6 | }, 7 | { 8 | "Σ": 20.0400, 9 | "Δ": 0.0400, 10 | "λ": "Some description" 11 | }, 12 | { 13 | "Σ": 12.2250, 14 | "Δ": 0.2250, 15 | "λ": "Some description" 16 | }, 17 | { 18 | "Σ": 7.2000, 19 | "Δ": 7.2000, 20 | "λ": "Some description" 21 | } 22 | ] -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/CodeAsDataTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using ApprovalTests; 5 | using ApprovalTests.Reporters; 6 | using MetaProgramming.RoslynCTP.Model; 7 | using Newtonsoft.Json; 8 | using NUnit.Framework; 9 | 10 | namespace MetaProgramming.RoslynCTP.Tests 11 | { 12 | [TestFixture] 13 | [UseReporter(typeof(DiffReporter))] 14 | public class CodeAsDataTests 15 | { 16 | [Test] 17 | public void ScriptAsData_ConvertJsonToScript_ScriptSubmission() 18 | { 19 | // Arrange 20 | // INFO: JSON deserializer 21 | var scriptInfo = JsonConvert.DeserializeObject(File.ReadAllText(@"./ScriptInfo.json")); 22 | var dataClassesInfo = JsonConvert.DeserializeObject(File.ReadAllText(@"./ClassTemplateInfos.json")); 23 | Func deserializeToType = type => JsonConvert.DeserializeObject(File.ReadAllText(@"./InputData.json"), type.MakeArrayType()); 24 | 25 | // Act 26 | IEnumerable results = CodeAsData.ProcessScript(scriptInfo, dataClassesInfo, deserializeToType); 27 | 28 | // Assert 29 | Approvals.Verify(JsonConvert.SerializeObject(results, Formatting.Indented)); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/CodeSmells.Samples/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/CodeSmells.Samples/.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/MetaProgramming/MetaProgramming.RoslynCTP.Tests/CodeSmells.Samples/.nuget/NuGet.exe -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/CodeSmells.Samples/ClassWithExtraComplexity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CodeSmells.Samples 4 | { 5 | public class ClassWithExtraComplexity 6 | { 7 | public string SimpleMethod() 8 | { 9 | return @"Simple Method with Cyclomatic complexity == 1"; 10 | } 11 | 12 | public string ComplexMethod() 13 | { 14 | int seed = new Random(DateTime.Now.Millisecond).Next() % 10; 15 | 16 | if (seed == 0) 17 | { 18 | return @"Case 0"; 19 | } 20 | 21 | if (seed == 1) 22 | { 23 | return @"Case 1"; 24 | } 25 | 26 | if (seed == 2) 27 | { 28 | return @"Case 2"; 29 | } 30 | 31 | if (seed == 3) 32 | { 33 | return @"Case 3"; 34 | } 35 | 36 | if (seed == 4) 37 | { 38 | return @"Case 4"; 39 | } 40 | 41 | if (seed == 5) 42 | { 43 | return @"Case 5"; 44 | } 45 | 46 | if (seed == 6) 47 | { 48 | return @"Case 6"; 49 | } 50 | 51 | if (seed == 7) 52 | { 53 | return @"Case 7"; 54 | } 55 | 56 | if (seed == 8) 57 | { 58 | return @"Case 8"; 59 | } 60 | 61 | if (seed == 9) 62 | { 63 | return @"Case 9"; 64 | } 65 | 66 | return @"Default case"; 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/CodeSmells.Samples/ClassWithReturnNullMethods.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CodeSmells.Samples 4 | { 5 | public class ClassWithReturnNullMethods 6 | { 7 | public object ReturnSomeReferenceType() 8 | { 9 | return new object(); 10 | } 11 | 12 | public object ReturnNullReferenceType() 13 | { 14 | return null; 15 | } 16 | 17 | public object ReturnDefaultReferenceType() 18 | { 19 | return default(object); 20 | } 21 | 22 | public IEnumerable ReturnEnumerableOfDefaultReferenceType() 23 | { 24 | yield return default(object); 25 | } 26 | 27 | public int ReturnSomeValueType() 28 | { 29 | return new int(); 30 | } 31 | 32 | public int ReturnDefaultValueType() 33 | { 34 | return default(int); 35 | } 36 | 37 | public IEnumerable ReturnEnumerableOfDefaultValueType() 38 | { 39 | yield return default(int); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/CodeSmells.Samples/CodeSmells.Samples.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {AF6664E5-9BB8-4487-A790-8E75BF2AB8D8} 8 | Library 9 | Properties 10 | CodeSmells.Samples 11 | CodeSmells.Samples 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 54 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/CodeSmells.Samples/CodeSmells.Samples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeSmells.Samples", "CodeSmells.Samples.csproj", "{AF6664E5-9BB8-4487-A790-8E75BF2AB8D8}" 5 | EndProject 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2B8BBA77-6CE6-4C47-8B04-B604F4B85604}" 7 | ProjectSection(SolutionItems) = preProject 8 | .nuget\NuGet.Config = .nuget\NuGet.Config 9 | .nuget\NuGet.exe = .nuget\NuGet.exe 10 | .nuget\NuGet.targets = .nuget\NuGet.targets 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Any CPU = Debug|Any CPU 16 | Release|Any CPU = Release|Any CPU 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {AF6664E5-9BB8-4487-A790-8E75BF2AB8D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 20 | {AF6664E5-9BB8-4487-A790-8E75BF2AB8D8}.Debug|Any CPU.Build.0 = Debug|Any CPU 21 | {AF6664E5-9BB8-4487-A790-8E75BF2AB8D8}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {AF6664E5-9BB8-4487-A790-8E75BF2AB8D8}.Release|Any CPU.Build.0 = Release|Any CPU 23 | EndGlobalSection 24 | GlobalSection(SolutionProperties) = preSolution 25 | HideSolutionNode = FALSE 26 | EndGlobalSection 27 | EndGlobal 28 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/CodeSmells.Samples/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CodeSmells.Samples")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CodeSmells.Samples")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f5ab6503-6582-44c4-bd9c-85a872bf1c6c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/ConverterTests.CSharp2VB_Convert_ValidCode.approved.txt: -------------------------------------------------------------------------------- 1 | Namespace Generated 2 | 3 | Public Class GeneartedClass 4 | 5 | Public Shared Function Test(model As Model.ProcessingModel) As Model.ReportModel 6 | model.Result =(model.InputA + (model.InputB * model.Factor)) 7 | model.Delta =(System.Math.Abs(model.Result.GetValueOrDefault(0m)) - model.InputA) 8 | model.Description = "Some description" 9 | Dim reportModel As Model.ReportModel = New Model.ReportModel() 10 | reportModel.Σ = model.Result 11 | reportModel.Δ = model.Delta 12 | reportModel.λ = model.Description 13 | Return reportModel 14 | End Function 15 | End Class 16 | End Namespace 17 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/ConverterTests.VB2CSharp_Convert_ValidCode.approved.txt: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Generated 4 | { 5 | public class GeneartedClass 6 | { 7 | public static Model.ReportModel Test(Model.ProcessingModel model) 8 | { 9 | model.Result = (model.InputA + (model.InputB * model.Factor)); 10 | model.Delta = (System.Math.Abs(model.Result.GetValueOrDefault(0D)) - model.InputA); 11 | model.Description = "Some description"; 12 | Model.ReportModel reportModel = new Model.ReportModel(); 13 | reportModel.Σ = model.Result; 14 | reportModel.Δ = model.Delta; 15 | reportModel.λ = model.Description; 16 | return reportModel; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/ConverterTests.cs: -------------------------------------------------------------------------------- 1 | using ApprovalTests; 2 | using ApprovalTests.Reporters; 3 | using NUnit.Framework; 4 | 5 | namespace MetaProgramming.RoslynCTP.Tests 6 | { 7 | [TestFixture] 8 | [UseReporter(typeof(DiffReporter))] 9 | public class ConverterTests 10 | { 11 | private const string CSharpCode = @" 12 | namespace Generated 13 | { 14 | using System; 15 | 16 | public class GeneartedClass 17 | { 18 | public static Model.ReportModel Test(Model.ProcessingModel model) 19 | { 20 | model.Result = (model.InputA 21 | + (model.InputB * model.Factor)); 22 | model.Delta = (System.Math.Abs(model.Result.GetValueOrDefault(0m)) - model.InputA); 23 | model.Description = ""Some description""; 24 | Model.ReportModel reportModel = new Model.ReportModel(); 25 | reportModel.Σ = model.Result; 26 | reportModel.Δ = model.Delta; 27 | reportModel.λ = model.Description; 28 | return reportModel; 29 | } 30 | } 31 | }"; 32 | 33 | private const string VbCode = @" 34 | Imports System 35 | 36 | Namespace Generated 37 | Public Class GeneartedClass 38 | Public Shared Function Test(ByVal model As Model.ProcessingModel) As Model.ReportModel 39 | model.Result = (model.InputA _ 40 | + (model.InputB * model.Factor)) 41 | model.Delta = (System.Math.Abs(model.Result.GetValueOrDefault(0D)) - model.InputA) 42 | model.Description = ""Some description"" 43 | Dim reportModel As Model.ReportModel = New Model.ReportModel() 44 | reportModel.Σ = model.Result 45 | reportModel.Δ = model.Delta 46 | reportModel.λ = model.Description 47 | Return reportModel 48 | End Function 49 | End Class 50 | End Namespace"; 51 | 52 | [Test] 53 | public void CSharp2VB_Convert_ValidCode() 54 | { 55 | Approvals.Verify(ConvertTo.VisualBasic(CSharpCode)); 56 | } 57 | 58 | [Test] 59 | public void VB2CSharp_Convert_ValidCode() 60 | { 61 | Approvals.Verify(ConvertTo.CSharp(VbCode)); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/InputData.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "InputA" : 10.0, 4 | "InputB" : 5.0, 5 | "Factor" : 0.050, 6 | "Result" : null, 7 | "Delta" : null, 8 | "Description" : null, 9 | "Addition" : null 10 | }, 11 | 12 | { 13 | "InputA" : 20.0, 14 | "InputB" : 2.0, 15 | "Factor" : 0.020, 16 | "Result" : null, 17 | "Delta" : null, 18 | "Description" : null, 19 | "Addition" : null 20 | }, 21 | 22 | { 23 | "InputA" : 12.0, 24 | "InputB" : 3.0, 25 | "Factor" : 0.075, 26 | "Result" : null, 27 | "Delta" : null, 28 | "Description" : null, 29 | "Addition" : null 30 | }, 31 | 32 | { 33 | "InputA" : 0.0, 34 | "InputB" : 9.0, 35 | "Factor" : 0.800, 36 | "Result" : null, 37 | "Delta" : null, 38 | "Description" : null, 39 | "Addition" : null 40 | } 41 | ] -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/IntrospectionTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.Immutable; 3 | using System.Linq; 4 | using System.Threading; 5 | using AfterProgramming.Model; 6 | using ApprovalTests; 7 | using ApprovalTests.Reporters; 8 | using FluentAssertions; 9 | using MetaProgramming.RoslynCTP.Tests.Strategy; 10 | using NUnit.Framework; 11 | using Newtonsoft.Json; 12 | using Approvals = ApprovalTests.Approvals; 13 | 14 | namespace MetaProgramming.RoslynCTP.Tests 15 | { 16 | [TestFixture(typeof(IntegrationIntrospectionFixture))] 17 | [TestFixture(typeof(CodeSmellsIntrospectionFixture))] 18 | [UseReporter(typeof(DiffReporter))] 19 | public class IntrospectionTests 20 | where TIntrospectionFixture : IIntrospectionFixture, new() 21 | { 22 | private readonly TIntrospectionFixture _strategy = new TIntrospectionFixture(); 23 | 24 | private CancellationTokenSource _cancellationTokenSource; 25 | 26 | [SetUp] 27 | public void SetUp() 28 | { 29 | _cancellationTokenSource = new CancellationTokenSource(_strategy.SeachTimeOut); 30 | } 31 | 32 | [Test] 33 | public void Introspection_SearchForComplexityGt10_ApprovedList() 34 | { 35 | var cancellationToken = _cancellationTokenSource.Token; 36 | 37 | IEnumerable methodsWithCyclomaticComplexityGt10 = 38 | new Introspection() 39 | .SearchForComplexMethods( 40 | solutionFile: _strategy.GetSolutionPath(), 41 | maxAllowedCyclomaticComplexity: 10, 42 | cancellationToken: cancellationToken); 43 | 44 | methodsWithCyclomaticComplexityGt10.Should() 45 | .NotBeNull() 46 | .And.BeOfType>() 47 | .And.NotBeEmpty(); 48 | 49 | var methodsWithCyclomaticComplexityGt10Results = 50 | methodsWithCyclomaticComplexityGt10 51 | .GroupBy(complexity => complexity.TypeIdentifier) 52 | .OrderByDescending(@group => @group.Sum(complexity => complexity.NStatementSyntax)) 53 | .ThenBy(@group => @group.First().FilePath) 54 | .Select(@group => @group 55 | .OrderByDescending(complexity => complexity.NStatementSyntax) 56 | .ThenBy(complexity => complexity.MethodIdentifier)) 57 | .ToArray(); 58 | 59 | ApprovalsVerify(methodsWithCyclomaticComplexityGt10Results); 60 | } 61 | 62 | [Test] 63 | public void Introspection_SearchForReturnNullStatements_ApprovedList() 64 | { 65 | var cancellationToken = _cancellationTokenSource.Token; 66 | 67 | IEnumerable returnNullStatements = 68 | new Introspection() 69 | .SearchForReturnNullStatements( 70 | solutionFile: _strategy.GetSolutionPath(), 71 | cancellationToken: cancellationToken); 72 | 73 | returnNullStatements.Should() 74 | .NotBeNull() 75 | .And.BeOfType>() 76 | .And.NotBeEmpty(); 77 | 78 | var orderedReturnNullStatements = 79 | returnNullStatements 80 | .OrderBy(returnNull => returnNull.FilePath) 81 | .ThenBy(returnNull => returnNull.SourceLine) 82 | .ToArray(); 83 | 84 | ApprovalsVerify(orderedReturnNullStatements); 85 | } 86 | 87 | private void ApprovalsVerify(IEnumerable records) 88 | { 89 | var serializeObject = JsonConvert.SerializeObject(records, Formatting.Indented); 90 | Approvals.Verify(new ApprovalTextWriter(serializeObject), new StrategyNamer(_strategy.GetTestType()), 91 | new DiffReporter()); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/IntrospectionTests`1.Introspection_SearchForComplexityGt10_ApprovedList.UnitTests.approved.txt: -------------------------------------------------------------------------------- 1 | [ 2 | [ 3 | { 4 | "TypeIdentifier": "ClassWithExtraComplexity", 5 | "MethodIdentifier": "ComplexMethod", 6 | "SourcesSample": "public string ComplexMethod()\r\n {\r\n int seed = new Random(DateTime.Now.Millisecond).Next() % 10;\r\n\r\n if (seed == 0)\r\n {\r\n return @\"Case 0\";\r\n }\r\n \r\n if (seed == 1)\r\n {\r\n return @\"Case 1\";\r\n }\r\n \r\n if (seed == 2)\r\n {\r\n return @\"Case 2\";\r\n }\r\n \r\n if (seed == 3)\r\n {\r\n return @\"Case 3\";\r\n }\r\n \r\n if (seed == 4)\r\n {\r\n return @\"Case 4\";\r\n }\r\n \r\n if (seed == 5)\r\n {\r\n return @\"Case 5\";\r\n }\r\n \r\n if (seed == 6)\r\n {\r\n return @\"Case 6\";\r\n }\r\n \r\n if (seed == 7)\r\n {\r\n return @\"Case 7\";\r\n }\r\n \r\n if (seed == 8)\r\n {\r\n return @\"Case 8\";\r\n }\r\n \r\n if (seed == 9)\r\n {\r\n return @\"Case 9\";\r\n }\r\n\r\n return @\"Default case\";\r\n }", 7 | "NStatementSyntax": 11, 8 | "FilePath": "Debug\\CodeSmells.Samples\\ClassWithExtraComplexity.cs", 9 | "SourceLine": 11 10 | } 11 | ] 12 | ] -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/IntrospectionTests`1.Introspection_SearchForReturnNullStatements_ApprovedList.UnitTests.approved.txt: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "TypeIdentifier": "ClassWithReturnNullMethods", 4 | "SourcesSample": "return null;", 5 | "FilePath": "Debug\\CodeSmells.Samples\\ClassWithReturnNullMethods.cs", 6 | "SourceLine": 14 7 | }, 8 | { 9 | "TypeIdentifier": "ClassWithReturnNullMethods", 10 | "SourcesSample": "return default(object);", 11 | "FilePath": "Debug\\CodeSmells.Samples\\ClassWithReturnNullMethods.cs", 12 | "SourceLine": 19 13 | }, 14 | { 15 | "TypeIdentifier": "ClassWithReturnNullMethods", 16 | "SourcesSample": "yield return default(object);", 17 | "FilePath": "Debug\\CodeSmells.Samples\\ClassWithReturnNullMethods.cs", 18 | "SourceLine": 24 19 | } 20 | ] -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MetaProgramming.RoslynCTP.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("ICGUA-SCCM-001")] 12 | [assembly: AssemblyProduct("MetaProgramming.RoslynCTP.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © ICGUA-SCCM-001 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b38d6cb1-1d1b-43c9-8def-89899c5bc3e2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/RuntimeTextTemplateTests.RuntimeTextTemplate_TransformText_ExpectedOutput.approved.txt: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Model 4 | { 5 | public class ProcessingModel 6 | { 7 | public Decimal InputA { get; set; } 8 | public Decimal InputB { get; set; } 9 | public Decimal Factor { get; set; } 10 | public Nullable Result { get; set; } 11 | public Nullable Delta { get; set; } 12 | public String Description { get; set; } 13 | public Nullable Addition { get; set; } 14 | } 15 | 16 | public class ReportModel 17 | { 18 | public Nullable Σ { get; set; } 19 | public Nullable Δ { get; set; } 20 | public String λ { get; set; } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/RuntimeTextTemplateTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using ApprovalTests; 4 | using ApprovalTests.Reporters; 5 | using MetaProgramming.RoslynCTP.Model; 6 | using Newtonsoft.Json; 7 | using NUnit.Framework; 8 | 9 | namespace MetaProgramming.RoslynCTP.Tests 10 | { 11 | [TestFixture] 12 | [UseReporter(typeof(DiffReporter))] 13 | public class RuntimeTextTemplateTests 14 | { 15 | [Test] 16 | public void RuntimeTextTemplate_TransformText_ExpectedOutput() 17 | { 18 | // Act 19 | var runtimeTextTemplate = new RuntimeTextTemplate 20 | { 21 | Session = new Dictionary 22 | { 23 | { "namespaceName", "Model" }, 24 | { "classes", JsonConvert.DeserializeObject(File.ReadAllText(@"ClassTemplateInfos.json")) } 25 | } 26 | }; 27 | 28 | runtimeTextTemplate.Initialize(); 29 | 30 | // Assert 31 | Approvals.Verify(runtimeTextTemplate.TransformText()); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/ScriptInfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "Namespaces" : ["System", "System.Math", "Model"], 3 | "Assemblies" : ["mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"], 4 | "Script" : " 5 | Result = InputA + InputB * Factor; 6 | Delta = Math.Abs((Result ?? 0M) - InputA); 7 | Description = \"Some description\"; 8 | new Model.ReportModel { Σ = Result, Δ = Delta, λ = Description } 9 | " 10 | } -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/Strategy/CodeSmellsIntrospectionFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | 5 | namespace MetaProgramming.RoslynCTP.Tests.Strategy 6 | { 7 | public class CodeSmellsIntrospectionFixture : IIntrospectionFixture 8 | { 9 | private const string SolutionFileName = @"CodeSmells.Samples.sln"; 10 | private readonly string _solutionFullPath; 11 | 12 | public CodeSmellsIntrospectionFixture() 13 | { 14 | _solutionFullPath = Directory 15 | .GetFiles(Directory.GetCurrentDirectory(), SolutionFileName, 16 | SearchOption.AllDirectories) 17 | .SingleOrDefault(); 18 | 19 | if (string.IsNullOrWhiteSpace(_solutionFullPath)) 20 | { 21 | throw new FileNotFoundException(string.Format("Can't find solution '{0}' starting for '{1}'", 22 | SolutionFileName, Directory.GetCurrentDirectory()), 23 | SolutionFileName); 24 | } 25 | } 26 | 27 | public string GetTestType() 28 | { 29 | return "UnitTests"; 30 | } 31 | 32 | public string GetSolutionPath() 33 | { 34 | return _solutionFullPath; 35 | } 36 | 37 | public TimeSpan SeachTimeOut 38 | { 39 | get { return TimeSpan.FromSeconds(20); } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/Strategy/IIntrospectionFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MetaProgramming.RoslynCTP.Tests.Strategy 4 | { 5 | public interface IIntrospectionFixture 6 | { 7 | string GetTestType(); 8 | string GetSolutionPath(); 9 | 10 | TimeSpan SeachTimeOut { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/Strategy/IntegrationIntrospectionFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MetaProgramming.RoslynCTP.Tests.Strategy 4 | { 5 | public class IntegrationIntrospectionFixture : IIntrospectionFixture 6 | { 7 | // source code downloaded from https://github.com/nhibernate/nhibernate-core 8 | const string SolutionPath = @"D:\temp\nhibernate-core-master\src\NHibernate.Everything.sln"; 9 | 10 | public string GetTestType() 11 | { 12 | return "Integration"; 13 | } 14 | 15 | public string GetSolutionPath() 16 | { 17 | return SolutionPath; 18 | } 19 | 20 | public TimeSpan SeachTimeOut 21 | { 22 | get { return TimeSpan.FromMinutes(5); } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/Strategy/StrategyNamer.cs: -------------------------------------------------------------------------------- 1 | using ApprovalTests.Core; 2 | using ApprovalTests.Namers; 3 | 4 | namespace MetaProgramming.RoslynCTP.Tests.Strategy 5 | { 6 | public class StrategyNamer : IApprovalNamer 7 | { 8 | private readonly IApprovalNamer _namer = new UnitTestFrameworkNamer(); 9 | private readonly string _strategyType; 10 | 11 | public StrategyNamer(string strategyType) 12 | { 13 | _strategyType = strategyType; 14 | } 15 | 16 | public string SourcePath { get { return _namer.SourcePath; } } 17 | 18 | public string Name 19 | { 20 | get { return string.Concat(_namer.Name, ".", _strategyType); } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/CSharpToVisualBasicConverter.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4C23E864-A81E-45FC-B62E-A85E3B521864} 8 | Library 9 | Properties 10 | CSharpToVisualBasicConverter 11 | CSharpToVisualBasicConverter 12 | v4.5 13 | ..\..\ 14 | true 15 | 16 | 17 | bin\Debug 18 | 19 | AnyCPU 20 | 21 | 22 | bin\Release 23 | 24 | 25 | 26 | 27 | True 28 | ..\..\packages\Roslyn.Compilers.Common.1.2.20906.2\lib\net45\Roslyn.Compilers.dll 29 | 30 | 31 | True 32 | ..\..\packages\Roslyn.Compilers.CSharp.1.2.20906.2\lib\net45\Roslyn.Compilers.CSharp.dll 33 | 34 | 35 | True 36 | ..\..\packages\Roslyn.Compilers.VisualBasic.1.2.20906.2\lib\net45\Roslyn.Compilers.VisualBasic.dll 37 | 38 | 39 | True 40 | ..\..\packages\Roslyn.Services.Common.1.2.20906.2\lib\net45\Roslyn.Services.dll 41 | 42 | 43 | True 44 | ..\..\packages\Roslyn.Services.CSharp.1.2.20906.2\lib\net45\Roslyn.Services.CSharp.dll 45 | 46 | 47 | True 48 | ..\..\packages\Roslyn.Services.VisualBasic.1.2.20906.2\lib\net45\Roslyn.Services.VisualBasic.dll 49 | 50 | 51 | True 52 | ..\..\packages\Roslyn.Services.Common.1.2.20906.2\lib\net45\Roslyn.Utilities.dll 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Cleanup/CurlyCleanup.cs: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // Copyright © Microsoft Corporation 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in 7 | // compliance with the License. You may obtain a copy of 8 | // the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES 13 | // OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 14 | // INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES 15 | // OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 16 | // PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. 17 | // 18 | // See the Apache 2 License for the specific language 19 | // governing permissions and limitations under the License. 20 | // 21 | // ********************************************************* 22 | 23 | using System.Linq; 24 | using Roslyn.Compilers.CSharp; 25 | 26 | namespace CSharpToVisualBasicConverter.Cleanup 27 | { 28 | internal class CurlyCleanup : SyntaxRewriter 29 | { 30 | private readonly SyntaxTree syntaxTree; 31 | 32 | public CurlyCleanup(SyntaxTree syntaxTree) 33 | { 34 | this.syntaxTree = syntaxTree; 35 | } 36 | 37 | public override SyntaxToken VisitToken(SyntaxToken token) 38 | { 39 | token = base.VisitToken(token); 40 | if (token.IsMissing) 41 | { 42 | return token; 43 | } 44 | 45 | if (token.Kind != SyntaxKind.CloseBraceToken) 46 | { 47 | return token; 48 | } 49 | 50 | var nextToken = token.GetNextToken(includeSkipped: true); 51 | 52 | var tokenLine = syntaxTree.GetText().GetLineNumberFromPosition(token.Span.Start); 53 | var nextTokenLine = syntaxTree.GetText().GetLineNumberFromPosition(nextToken.Span.Start); 54 | var nextTokenIsCloseBrace = nextToken.Kind == SyntaxKind.CloseBraceToken; 55 | 56 | var expectedDiff = nextTokenIsCloseBrace ? 1 : 2; 57 | if (nextTokenLine == tokenLine + expectedDiff) 58 | { 59 | return token; 60 | } 61 | 62 | var nonNewLineTrivia = token.TrailingTrivia.Where(t => t.Kind != SyntaxKind.EndOfLineTrivia); 63 | var newTrivia = nonNewLineTrivia.Concat(Enumerable.Repeat(Syntax.EndOfLine("\r\n"), expectedDiff)); 64 | 65 | return token.WithTrailingTrivia(Syntax.TriviaList(newTrivia)); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Cleanup/MissingCurlyCleanup.cs: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // Copyright © Microsoft Corporation 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in 7 | // compliance with the License. You may obtain a copy of 8 | // the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES 13 | // OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 14 | // INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES 15 | // OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 16 | // PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. 17 | // 18 | // See the Apache 2 License for the specific language 19 | // governing permissions and limitations under the License. 20 | // 21 | // ********************************************************* 22 | 23 | using Roslyn.Compilers.CSharp; 24 | 25 | namespace CSharpToVisualBasicConverter.Cleanup 26 | { 27 | internal class MissingCurlyCleanup : SyntaxRewriter 28 | { 29 | private readonly SyntaxTree syntaxTree; 30 | 31 | public MissingCurlyCleanup(SyntaxTree syntaxTree) 32 | { 33 | this.syntaxTree = syntaxTree; 34 | } 35 | 36 | public override SyntaxNode VisitIfStatement(IfStatementSyntax node) 37 | { 38 | node = (IfStatementSyntax)base.VisitIfStatement(node); 39 | if (node.Statement.Kind == SyntaxKind.Block) 40 | { 41 | return node; 42 | } 43 | 44 | var block = Syntax.Block(statements: Syntax.List(node.Statement)); 45 | return Syntax.IfStatement( 46 | node.IfKeyword, 47 | node.OpenParenToken, 48 | node.Condition, 49 | node.CloseParenToken, 50 | block, 51 | node.Else); 52 | } 53 | 54 | public override SyntaxNode VisitElseClause(ElseClauseSyntax node) 55 | { 56 | node = (ElseClauseSyntax)base.VisitElseClause(node); 57 | if (node.Statement.Kind == SyntaxKind.Block || node.Statement.Kind == SyntaxKind.IfStatement) 58 | { 59 | return node; 60 | } 61 | 62 | var block = Syntax.Block(statements: Syntax.List(node.Statement)); 63 | return Syntax.ElseClause( 64 | node.ElseKeyword, 65 | block); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Cleanup/NewLineCleanup.cs: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // Copyright © Microsoft Corporation 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in 7 | // compliance with the License. You may obtain a copy of 8 | // the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES 13 | // OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 14 | // INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES 15 | // OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 16 | // PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. 17 | // 18 | // See the Apache 2 License for the specific language 19 | // governing permissions and limitations under the License. 20 | // 21 | // ********************************************************* 22 | 23 | using System.Collections.Generic; 24 | using Roslyn.Compilers.CSharp; 25 | 26 | namespace CSharpToVisualBasicConverter.Cleanup 27 | { 28 | internal class NewLineCleanup : SyntaxRewriter 29 | { 30 | private readonly SyntaxTree syntaxTree; 31 | 32 | public NewLineCleanup(SyntaxTree syntaxTree) 33 | { 34 | this.syntaxTree = syntaxTree; 35 | } 36 | 37 | public override SyntaxToken VisitToken(SyntaxToken token) 38 | { 39 | token = base.VisitToken(token); 40 | if (token.IsMissing) 41 | { 42 | return token; 43 | } 44 | 45 | bool changed; 46 | 47 | do 48 | { 49 | changed = false; 50 | if ((token.HasLeadingTrivia && token.LeadingTrivia.Count >= 2) || 51 | (token.HasTrailingTrivia && token.TrailingTrivia.Count >= 2)) 52 | { 53 | var newLeadingTrivia = RemoveBlankLines(token.LeadingTrivia, ref changed); 54 | var newTrailingTrivia = RemoveBlankLines(token.TrailingTrivia, ref changed); 55 | 56 | if (changed) 57 | { 58 | token = token.WithLeadingTrivia(Syntax.TriviaList(newLeadingTrivia)); 59 | token = token.WithTrailingTrivia(Syntax.TriviaList(newTrailingTrivia)); 60 | } 61 | } 62 | } 63 | while (changed); 64 | 65 | return token; 66 | } 67 | 68 | private static List RemoveBlankLines(SyntaxTriviaList trivia, ref bool changed) 69 | { 70 | var newTrivia = new List(); 71 | 72 | for (int i = 0; i < trivia.Count;) 73 | { 74 | var trivia1 = trivia[i]; 75 | newTrivia.Add(trivia1); 76 | 77 | if (i < trivia.Count - 1) 78 | { 79 | var trivia2 = trivia[i + 1]; 80 | 81 | if (trivia1.Kind == SyntaxKind.EndOfLineTrivia && 82 | trivia2.Kind == SyntaxKind.EndOfLineTrivia) 83 | { 84 | changed = true; 85 | i += 2; 86 | continue; 87 | } 88 | } 89 | 90 | i++; 91 | } 92 | 93 | return newTrivia; 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Cleanup/WhiteSpaceCleanup.cs: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // Copyright © Microsoft Corporation 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in 7 | // compliance with the License. You may obtain a copy of 8 | // the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES 13 | // OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 14 | // INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES 15 | // OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 16 | // PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. 17 | // 18 | // See the Apache 2 License for the specific language 19 | // governing permissions and limitations under the License. 20 | // 21 | // ********************************************************* 22 | 23 | using System.Collections.Generic; 24 | using Roslyn.Compilers.CSharp; 25 | 26 | namespace CSharpToVisualBasicConverter.Cleanup 27 | { 28 | internal class WhiteSpaceCleanup : SyntaxRewriter 29 | { 30 | private readonly SyntaxTree syntaxTree; 31 | 32 | public WhiteSpaceCleanup(SyntaxTree syntaxTree) 33 | { 34 | this.syntaxTree = syntaxTree; 35 | } 36 | 37 | public override SyntaxToken VisitToken(SyntaxToken token) 38 | { 39 | token = base.VisitToken(token); 40 | if (token.IsMissing) 41 | { 42 | return token; 43 | } 44 | 45 | bool changed; 46 | 47 | do 48 | { 49 | changed = false; 50 | if ((token.HasTrailingTrivia && token.TrailingTrivia.Count >= 3) || 51 | (token.HasLeadingTrivia && token.LeadingTrivia.Count >= 3)) 52 | { 53 | var newLeadingTrivia = RemoveBlankLineTrivia(token.LeadingTrivia, ref changed); 54 | var newTrailingTrivia = RemoveBlankLineTrivia(token.TrailingTrivia, ref changed); 55 | 56 | if (changed) 57 | { 58 | token = token.WithLeadingTrivia(Syntax.TriviaList(newLeadingTrivia)); 59 | token = token.WithTrailingTrivia(Syntax.TriviaList(newTrailingTrivia)); 60 | } 61 | } 62 | } 63 | while (changed); 64 | 65 | return token; 66 | } 67 | 68 | private static List RemoveBlankLineTrivia(SyntaxTriviaList trivia, ref bool changed) 69 | { 70 | var newTrivia = new List(); 71 | 72 | for (int i = 0; i < trivia.Count;) 73 | { 74 | var trivia1 = trivia[i]; 75 | newTrivia.Add(trivia1); 76 | 77 | if (i < trivia.Count - 2) 78 | { 79 | var trivia2 = trivia[i + 1]; 80 | var trivia3 = trivia[i + 2]; 81 | 82 | if (trivia1.Kind == SyntaxKind.EndOfLineTrivia && 83 | trivia2.Kind == SyntaxKind.WhitespaceTrivia && 84 | trivia3.Kind == SyntaxKind.EndOfLineTrivia) 85 | { 86 | // Skip the whitespace with a newline. 87 | newTrivia.Add(trivia3); 88 | changed = true; 89 | i += 3; 90 | continue; 91 | } 92 | } 93 | 94 | i++; 95 | } 96 | 97 | return newTrivia; 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Converting/Converter.NodeVisitor.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Converting/Converter.NodeVisitor.cs -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Converting/Converter.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Converting/Converter.cs -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // Copyright © Microsoft Corporation 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in 7 | // compliance with the License. You may obtain a copy of 8 | // the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES 13 | // OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 14 | // INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES 15 | // OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 16 | // PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. 17 | // 18 | // See the Apache 2 License for the specific language 19 | // governing permissions and limitations under the License. 20 | // 21 | // ********************************************************* 22 | 23 | using System.Reflection; 24 | using System.Runtime.CompilerServices; 25 | 26 | [assembly: AssemblyTitle("CSharpToVisualBasicConverter")] 27 | [assembly: InternalsVisibleTo("CSharpToVisualBasicConverter.UnitTests")] -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Utilities/CSharpExtensions.cs: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // Copyright © Microsoft Corporation 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in 7 | // compliance with the License. You may obtain a copy of 8 | // the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES 13 | // OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 14 | // INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES 15 | // OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 16 | // PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. 17 | // 18 | // See the Apache 2 License for the specific language 19 | // governing permissions and limitations under the License. 20 | // 21 | // ********************************************************* 22 | 23 | using System.Collections.Generic; 24 | using System.Linq; 25 | using Roslyn.Compilers.CSharp; 26 | 27 | namespace CSharpToVisualBasicConverter.Utilities 28 | { 29 | internal static class CSharpExtensions 30 | { 31 | public static IEnumerable GetAncestorsOrThis(this SyntaxNode node, bool allowStructuredTrivia = false) 32 | where T : SyntaxNode 33 | { 34 | var current = node; 35 | while (current != null) 36 | { 37 | if (current is T) 38 | { 39 | yield return (T)current; 40 | } 41 | 42 | if (allowStructuredTrivia && 43 | current.IsStructuredTrivia && 44 | current.Parent == null) 45 | { 46 | var structuredTrivia = (StructuredTriviaSyntax)current; 47 | var parentTrivia = structuredTrivia.ParentTrivia; 48 | current = parentTrivia.Token.Parent; 49 | } 50 | else 51 | { 52 | current = current.Parent; 53 | } 54 | } 55 | } 56 | 57 | public static SyntaxNode GetParent(this SyntaxTree syntaxTree, SyntaxNode node) 58 | { 59 | return node != null ? node.Parent : null; 60 | } 61 | 62 | public static TypeSyntax GetVariableType(this VariableDeclaratorSyntax variable) 63 | { 64 | var parent = variable.Parent as VariableDeclarationSyntax; 65 | if (parent == null) 66 | { 67 | return null; 68 | } 69 | 70 | return parent.Type; 71 | } 72 | 73 | public static bool IsBreakableConstruct(this SyntaxNode node) 74 | { 75 | switch (node.Kind) 76 | { 77 | case SyntaxKind.DoStatement: 78 | case SyntaxKind.WhileStatement: 79 | case SyntaxKind.SwitchStatement: 80 | case SyntaxKind.ForStatement: 81 | case SyntaxKind.ForEachStatement: 82 | return true; 83 | } 84 | 85 | return false; 86 | } 87 | 88 | public static bool IsContinuableConstruct(this SyntaxNode node) 89 | { 90 | switch (node.Kind) 91 | { 92 | case SyntaxKind.DoStatement: 93 | case SyntaxKind.WhileStatement: 94 | case SyntaxKind.ForStatement: 95 | case SyntaxKind.ForEachStatement: 96 | return true; 97 | } 98 | 99 | return false; 100 | } 101 | 102 | public static bool IsParentKind(this SyntaxNode node, SyntaxKind kind) 103 | { 104 | return node != null && node.Parent.IsKind(kind); 105 | } 106 | 107 | public static bool IsKind(this SyntaxNode node, SyntaxKind kind) 108 | { 109 | return node != null && node.Kind == kind; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Utilities/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // Copyright © Microsoft Corporation 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in 7 | // compliance with the License. You may obtain a copy of 8 | // the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES 13 | // OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 14 | // INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES 15 | // OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 16 | // PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. 17 | // 18 | // See the Apache 2 License for the specific language 19 | // governing permissions and limitations under the License. 20 | // 21 | // ********************************************************* 22 | 23 | using System; 24 | using System.Collections.Generic; 25 | 26 | namespace CSharpToVisualBasicConverter.Utilities 27 | { 28 | internal static class EnumerableExtensions 29 | { 30 | private static IEnumerable ConcatWorker(this IEnumerable source, T value) 31 | { 32 | foreach (var v in source) 33 | { 34 | yield return v; 35 | } 36 | 37 | yield return value; 38 | } 39 | 40 | public static IEnumerable Concat(this IEnumerable source, T value) 41 | { 42 | if (source == null) 43 | { 44 | throw new ArgumentNullException("source"); 45 | } 46 | 47 | return source.ConcatWorker(value); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/Utilities/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | // ********************************************************* 2 | // 3 | // Copyright © Microsoft Corporation 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in 7 | // compliance with the License. You may obtain a copy of 8 | // the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES 13 | // OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 14 | // INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES 15 | // OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 16 | // PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. 17 | // 18 | // See the Apache 2 License for the specific language 19 | // governing permissions and limitations under the License. 20 | // 21 | // ********************************************************* 22 | 23 | using System; 24 | using System.Text; 25 | 26 | namespace CSharpToVisualBasicConverter.Utilities 27 | { 28 | internal static class StringExtensions 29 | { 30 | public static string Repeat(this string s, int count) 31 | { 32 | if (s == null) 33 | { 34 | throw new ArgumentNullException("s"); 35 | } 36 | 37 | if (count == 0 || s.Length == 0) 38 | { 39 | return string.Empty; 40 | } 41 | else if (count == 1) 42 | { 43 | return s; 44 | } 45 | else 46 | { 47 | var builder = new StringBuilder(s.Length * count); 48 | for (int i = 0; i < count; i++) 49 | { 50 | builder.Append(s); 51 | } 52 | 53 | return builder.ToString(); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/CSharpToVisualBasicConverter/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/ConvertTo.cs: -------------------------------------------------------------------------------- 1 | namespace MetaProgramming.RoslynCTP 2 | { 3 | public static class ConvertTo 4 | { 5 | public static string VisualBasic(string sourceCode) 6 | { 7 | return new CSharpToVisualBasicConverter.Converting.Converter().Convert(sourceCode); 8 | } 9 | 10 | public static string CSharp(string sourceCode) 11 | { 12 | var tree = Roslyn.Compilers.VisualBasic.SyntaxTree.ParseText(sourceCode); 13 | return new VisualBasicToCSharpConverter.Converting.Converter().Convert(tree).ToFullString(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/Internal/PredicateBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | 5 | namespace MetaProgramming.RoslynCTP.Internal 6 | { 7 | // http://www.albahari.com/nutshell/predicatebuilder.aspx 8 | internal static class PredicateBuilder 9 | { 10 | public static Expression> True() { return f => true; } 11 | public static Expression> False() { return f => false; } 12 | 13 | // ReSharper disable RedundantEnumerableCastCall 14 | 15 | public static Expression> Or(this Expression> expr1, 16 | Expression> expr2) 17 | { 18 | var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast()); 19 | return Expression.Lambda> 20 | (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters); 21 | } 22 | 23 | public static Expression> And(this Expression> expr1, 24 | Expression> expr2) 25 | { 26 | var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast()); 27 | return Expression.Lambda> 28 | (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters); 29 | } 30 | 31 | // ReSharper restore RedundantEnumerableCastCall 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/Introspection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | using AfterProgramming; 4 | using AfterProgramming.Model; 5 | 6 | namespace MetaProgramming.RoslynCTP 7 | { 8 | public class Introspection 9 | { 10 | public IEnumerable SearchForComplexMethods( 11 | string solutionFile, 12 | int maxAllowedCyclomaticComplexity, 13 | CancellationToken cancellationToken) 14 | { 15 | return new CyclomaticComplexity() 16 | .SearchForComplexMethods( 17 | solutionFile, maxAllowedCyclomaticComplexity, cancellationToken); 18 | } 19 | 20 | public IEnumerable SearchForReturnNullStatements( 21 | string solutionFile, 22 | CancellationToken cancellationToken) 23 | { 24 | return new ReturnStatement() 25 | .SearchForReturnNullStatements( 26 | solutionFile, cancellationToken); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/Model/ClassTemplateInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace MetaProgramming.RoslynCTP.Model 5 | { 6 | public class ClassTemplateInfo 7 | { 8 | public string Name { get; set; } 9 | public bool IsPublic { get; set; } 10 | public IDictionary Properties { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/Model/ScriptInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MetaProgramming.RoslynCTP.Model 4 | { 5 | public class ScriptInfo 6 | { 7 | public IEnumerable Namespaces { get; set; } 8 | public IEnumerable Assemblies { get; set; } 9 | public string Script { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MetaProgramming.RoslynCTP")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("ICGUA-SCCM-001")] 12 | [assembly: AssemblyProduct("MetaProgramming.RoslynCTP")] 13 | [assembly: AssemblyCopyright("Copyright © ICGUA-SCCM-001 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("63f38829-c42d-4c1a-8dd7-15167509e113")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/RuntimeTextTemplate.tt: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" #> 2 | <#@ assembly name="System.Core" #> 3 | <#@ import namespace="System.Linq" #> 4 | <#@ import namespace="System.Text" #> 5 | <#@ import namespace="System.Collections.Generic" #> 6 | <#@ import namespace="MetaProgramming.RoslynCTP" #> 7 | <#@ parameter name="namespaceName" type="System.String" #> 8 | <#@ parameter name="classes" type="System.Collections.Generic.IEnumerable" #> 9 | using System; 10 | 11 | namespace <#= this.namespaceName #> 12 | { 13 | <# 14 | foreach(var @class in this.classes) 15 | { 16 | ClearIndent(); 17 | PushIndent(" "); 18 | #><#= @class.IsPublic ? "public" : "private" #> class <#= @class.Name #><# 19 | 20 | Write(Environment.NewLine); 21 | Write("{"); 22 | Write(Environment.NewLine); 23 | 24 | PushIndent(" "); 25 | foreach(var key in @class.Properties.Keys) 26 | { 27 | #>public <#= ExpandedTypeName(@class.Properties[key]) #> <#= key #> { get; set; }<# 28 | Write(Environment.NewLine); 29 | } 30 | PopIndent(); 31 | 32 | Write("}"); 33 | Write(Environment.NewLine); 34 | Write(Environment.NewLine); 35 | } 36 | 37 | ClearIndent(); 38 | #> 39 | } 40 | <#+ 41 | private string ExpandedTypeName(Type t) 42 | { 43 | var result = new StringBuilder(); 44 | 45 | if (!t.IsGenericType) 46 | { 47 | result.Append(t.Name); 48 | } 49 | else 50 | { 51 | result.Append(t.Name.Substring(0, t.Name.IndexOf('`'))); 52 | result.Append("<"); 53 | 54 | int ndx = 0; 55 | 56 | foreach (var tp in t.GetGenericArguments()) 57 | { 58 | result.AppendFormat((ndx++ > 0) ? ", {0}" : "{0}", tp.Name); 59 | } 60 | 61 | result.Append(">"); 62 | } 63 | 64 | return result.ToString(); 65 | } 66 | #> -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/VisualBasicToCSharpConverter/Converting/Converter.vb: -------------------------------------------------------------------------------- 1 | ' ********************************************************* 2 | ' 3 | ' Copyright © Microsoft Corporation 4 | ' 5 | ' Licensed under the Apache License, Version 2.0 (the 6 | ' "License"); you may not use this file except in 7 | ' compliance with the License. You may obtain a copy of 8 | ' the License at 9 | ' 10 | ' http://www.apache.org/licenses/LICENSE-2.0 11 | ' 12 | ' THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES 13 | ' OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 14 | ' INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES 15 | ' OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 16 | ' PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. 17 | ' 18 | ' See the Apache 2 License for the specific language 19 | ' governing permissions and limitations under the License. 20 | ' 21 | ' ********************************************************* 22 | 23 | Imports System.Collections.Generic 24 | Imports CS = Roslyn.Compilers.CSharp 25 | Imports VB = Roslyn.Compilers.VisualBasic 26 | 27 | Namespace VisualBasicToCSharpConverter.Converting 28 | Public Class Converter 29 | Public Function Convert( 30 | tree As VB.SyntaxTree, 31 | Optional identifierMap As IDictionary(Of String, String) = Nothing, 32 | Optional convertStrings As Boolean = False 33 | ) As CS.SyntaxNode 34 | 35 | Return ConvertTree(tree) 36 | End Function 37 | 38 | Public Shared Function ConvertTree(tree As VB.SyntaxTree) As CS.SyntaxNode 39 | Return New NodeConvertingVisitor().Visit(tree.GetRoot()) 40 | End Function 41 | End Class 42 | End Namespace -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/VisualBasicToCSharpConverter/My Project/AssemblyInfo.vb: -------------------------------------------------------------------------------- 1 | ' ********************************************************* 2 | ' 3 | ' Copyright © Microsoft Corporation 4 | ' 5 | ' Licensed under the Apache License, Version 2.0 (the 6 | ' "License"); you may not use this file except in 7 | ' compliance with the License. You may obtain a copy of 8 | ' the License at 9 | ' 10 | ' http://www.apache.org/licenses/LICENSE-2.0 11 | ' 12 | ' THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES 13 | ' OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 14 | ' INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES 15 | ' OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 16 | ' PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT. 17 | ' 18 | ' See the Apache 2 License for the specific language 19 | ' governing permissions and limitations under the License. 20 | ' 21 | ' ********************************************************* 22 | 23 | Imports System.Reflection 24 | Imports System.Runtime.CompilerServices 25 | 26 | 27 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/VisualBasicToCSharpConverter/VisualBasicToCSharpConverter.vbproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | v4.5 8 | ..\..\ 9 | true 10 | 11 | 12 | Debug 13 | AnyCPU 14 | {93C7AB9E-ACE5-4586-9C7D-B3C1697C4D9D} 15 | Library 16 | VisualBasicToCSharpConverter 17 | Empty 18 | 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 19 | On 20 | Binary 21 | Off 22 | On 23 | false 24 | 25 | 26 | bin\Debug 27 | true 28 | full 29 | true 30 | true 31 | 41999,42016,42030,42104,42108,42109 32 | 41998,42004,42020,42021,42022,42026,42029,42031,42105,42106,42107,42353,42354,42355 33 | 34 | true 35 | AnyCPU 36 | 37 | 38 | bin\Release 39 | pdbonly 40 | false 41 | true 42 | true 43 | 41999,42016,42030,42104,42108,42109 44 | 41998,42004,42020,42021,42022,42026,42029,42031,42105,42106,42107,42353,42354,42355 45 | 46 | true 47 | 48 | 49 | 50 | True 51 | 52 | 53 | True 54 | ..\..\packages\Roslyn.Compilers.CSharp.1.2.20906.2\lib\net45\Roslyn.Compilers.CSharp.dll 55 | 56 | 57 | True 58 | ..\..\packages\Roslyn.Compilers.VisualBasic.1.2.20906.2\lib\net45\Roslyn.Compilers.VisualBasic.dll 59 | 60 | 61 | True 62 | ..\..\packages\Roslyn.Services.Common.1.2.20906.2\lib\net45\Roslyn.Services.dll 63 | 64 | 65 | True 66 | ..\..\packages\Roslyn.Services.CSharp.1.2.20906.2\lib\net45\Roslyn.Services.CSharp.dll 67 | 68 | 69 | True 70 | ..\..\packages\Roslyn.Services.VisualBasic.1.2.20906.2\lib\net45\Roslyn.Services.VisualBasic.dll 71 | 72 | 73 | True 74 | ..\..\packages\Roslyn.Services.Common.1.2.20906.2\lib\net45\Roslyn.Utilities.dll 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/VisualBasicToCSharpConverter/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.RoslynCTP/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /MetaProgramming/MetaProgramming.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetaProgramming.RoslynCTP", "MetaProgramming.RoslynCTP\MetaProgramming.RoslynCTP.csproj", "{45271A67-4801-4499-9C12-2A844278021F}" 5 | EndProject 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{555D7659-337B-40D5-893B-BA262859138A}" 7 | ProjectSection(SolutionItems) = preProject 8 | .nuget\NuGet.Config = .nuget\NuGet.Config 9 | .nuget\NuGet.exe = .nuget\NuGet.exe 10 | .nuget\NuGet.targets = .nuget\NuGet.targets 11 | EndProjectSection 12 | EndProject 13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetaProgramming.RoslynCTP.Tests", "MetaProgramming.RoslynCTP.Tests\MetaProgramming.RoslynCTP.Tests.csproj", "{F2D19CBA-40C0-4AD4-809F-E5039A323348}" 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpToVisualBasicConverter", "MetaProgramming.RoslynCTP\CSharpToVisualBasicConverter\CSharpToVisualBasicConverter.csproj", "{4C23E864-A81E-45FC-B62E-A85E3B521864}" 16 | EndProject 17 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "VisualBasicToCSharpConverter", "MetaProgramming.RoslynCTP\VisualBasicToCSharpConverter\VisualBasicToCSharpConverter.vbproj", "{93C7AB9E-ACE5-4586-9C7D-B3C1697C4D9D}" 18 | EndProject 19 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Metaprogramming.RoslynCTP.Samples", "Metaprogramming.RoslynCTP.Samples", "{847E0D3D-9E31-4923-9F5F-42C3FAD06A95}" 20 | EndProject 21 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{A3A3F624-117A-4E0C-9F84-02D8283BA55D}" 22 | EndProject 23 | Project("{EDCC3B85-0BAD-11DB-BC1A-00112FDE8B61}") = "MetaProgramming.Nemerle", "MetaProgramming.Nemerle\MetaProgramming.Nemerle.nproj", "{EEE410F7-10DF-452F-A2A5-D073AD12EFD6}" 24 | EndProject 25 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetaProgramming.Nemerle.Tests.CSharp", "MetaProgramming.Nemerle.Tests.CSharp\MetaProgramming.Nemerle.Tests.CSharp.csproj", "{44555B43-900C-4F80-B77B-D2C751788BA1}" 26 | EndProject 27 | Project("{EDCC3B85-0BAD-11DB-BC1A-00112FDE8B61}") = "MetaProgramming.Nemerle.Macro", "MetaProgramming.Nemerle.Macro\MetaProgramming.Nemerle.Macro.nproj", "{3BB3E243-467A-42D5-878F-0F1AA26195A5}" 28 | EndProject 29 | Global 30 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 31 | Debug|Any CPU = Debug|Any CPU 32 | Release|Any CPU = Release|Any CPU 33 | EndGlobalSection 34 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 35 | {45271A67-4801-4499-9C12-2A844278021F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {45271A67-4801-4499-9C12-2A844278021F}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {45271A67-4801-4499-9C12-2A844278021F}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {45271A67-4801-4499-9C12-2A844278021F}.Release|Any CPU.Build.0 = Release|Any CPU 39 | {F2D19CBA-40C0-4AD4-809F-E5039A323348}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {F2D19CBA-40C0-4AD4-809F-E5039A323348}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {F2D19CBA-40C0-4AD4-809F-E5039A323348}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {F2D19CBA-40C0-4AD4-809F-E5039A323348}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {4C23E864-A81E-45FC-B62E-A85E3B521864}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 44 | {4C23E864-A81E-45FC-B62E-A85E3B521864}.Debug|Any CPU.Build.0 = Debug|Any CPU 45 | {4C23E864-A81E-45FC-B62E-A85E3B521864}.Release|Any CPU.ActiveCfg = Release|Any CPU 46 | {4C23E864-A81E-45FC-B62E-A85E3B521864}.Release|Any CPU.Build.0 = Release|Any CPU 47 | {93C7AB9E-ACE5-4586-9C7D-B3C1697C4D9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 48 | {93C7AB9E-ACE5-4586-9C7D-B3C1697C4D9D}.Debug|Any CPU.Build.0 = Debug|Any CPU 49 | {93C7AB9E-ACE5-4586-9C7D-B3C1697C4D9D}.Release|Any CPU.ActiveCfg = Release|Any CPU 50 | {93C7AB9E-ACE5-4586-9C7D-B3C1697C4D9D}.Release|Any CPU.Build.0 = Release|Any CPU 51 | {EEE410F7-10DF-452F-A2A5-D073AD12EFD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 52 | {EEE410F7-10DF-452F-A2A5-D073AD12EFD6}.Debug|Any CPU.Build.0 = Debug|Any CPU 53 | {EEE410F7-10DF-452F-A2A5-D073AD12EFD6}.Release|Any CPU.ActiveCfg = Release|Any CPU 54 | {EEE410F7-10DF-452F-A2A5-D073AD12EFD6}.Release|Any CPU.Build.0 = Release|Any CPU 55 | {44555B43-900C-4F80-B77B-D2C751788BA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 56 | {44555B43-900C-4F80-B77B-D2C751788BA1}.Debug|Any CPU.Build.0 = Debug|Any CPU 57 | {44555B43-900C-4F80-B77B-D2C751788BA1}.Release|Any CPU.ActiveCfg = Release|Any CPU 58 | {44555B43-900C-4F80-B77B-D2C751788BA1}.Release|Any CPU.Build.0 = Release|Any CPU 59 | {3BB3E243-467A-42D5-878F-0F1AA26195A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 60 | {3BB3E243-467A-42D5-878F-0F1AA26195A5}.Debug|Any CPU.Build.0 = Debug|Any CPU 61 | {3BB3E243-467A-42D5-878F-0F1AA26195A5}.Release|Any CPU.ActiveCfg = Release|Any CPU 62 | {3BB3E243-467A-42D5-878F-0F1AA26195A5}.Release|Any CPU.Build.0 = Release|Any CPU 63 | EndGlobalSection 64 | GlobalSection(SolutionProperties) = preSolution 65 | HideSolutionNode = FALSE 66 | EndGlobalSection 67 | GlobalSection(NestedProjects) = preSolution 68 | {F2D19CBA-40C0-4AD4-809F-E5039A323348} = {A3A3F624-117A-4E0C-9F84-02D8283BA55D} 69 | {44555B43-900C-4F80-B77B-D2C751788BA1} = {A3A3F624-117A-4E0C-9F84-02D8283BA55D} 70 | {93C7AB9E-ACE5-4586-9C7D-B3C1697C4D9D} = {847E0D3D-9E31-4923-9F5F-42C3FAD06A95} 71 | {4C23E864-A81E-45FC-B62E-A85E3B521864} = {847E0D3D-9E31-4923-9F5F-42C3FAD06A95} 72 | EndGlobalSection 73 | EndGlobal 74 | -------------------------------------------------------------------------------- /MetaProgramming/README.md: -------------------------------------------------------------------------------- 1 | #MetaProgramming using RoslynCTP and T4 2 | ## Code-as-Data approach 3 | 4 | * Runtime template transformation using T4 5 | * Generate types, models and algorithms from JSON input using Roslyn CTP 6 | * Tested using [ApprovalTests](http://approvaltests.sourceforge.net/) 7 | 8 | 9 | ## Introspection 10 | 11 | * Search for `return null;` `yeild return null;`, `default(T)` and value/reference types check among all sources of solution 12 | * Calculate code cyclomatic complexity 13 | -------------------------------------------------------------------------------- /Presentation/README.md: -------------------------------------------------------------------------------- 1 | #Presentation Metaprogramming in .NET 2 | ##MSSwit'2013: Microsoft® “Roslyn” CTP 3 | * [Version online](http://bit.ly/188vhSA) 4 | * [Video recording](http://bit.ly/10XulNP) 5 | 6 | ##ItBrunch: Architectural Validation in .Net 7 | * [Version online](http://bit.ly/15VqZCF) 8 | * [Video recording](http://youtu.be/YN2ldqnSXMY) 9 | 10 | ##Metaprogramming in .NET “Roslyn” CTP and Nemerle for #HotCode 11 | * [Version online](http://bit.ly/146eD78) 12 | * [Video recording](http://bit.ly/MPDotNet) 13 | 14 | ##KievAltNet: ScriptCs for Project-less development 15 | * [Version online](http://bit.ly/ProjectLess) 16 | -------------------------------------------------------------------------------- /Presentation/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/apple-touch-icon.png -------------------------------------------------------------------------------- /Presentation/images/CodeAsData_ConvertVBtoCSharp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/CodeAsData_ConvertVBtoCSharp.png -------------------------------------------------------------------------------- /Presentation/images/FreeBSD-No-Bikeshed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/FreeBSD-No-Bikeshed.png -------------------------------------------------------------------------------- /Presentation/images/IronPythonScript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/IronPythonScript.png -------------------------------------------------------------------------------- /Presentation/images/JavaScriptMetaprogrammingViaScripting.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/JavaScriptMetaprogrammingViaScripting.pdn -------------------------------------------------------------------------------- /Presentation/images/JavaScriptMetaprogrammingViaScripting_00_Begin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/JavaScriptMetaprogrammingViaScripting_00_Begin.png -------------------------------------------------------------------------------- /Presentation/images/JavaScriptMetaprogrammingViaScripting_01_SimpleMultiplication.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/JavaScriptMetaprogrammingViaScripting_01_SimpleMultiplication.png -------------------------------------------------------------------------------- /Presentation/images/JavaScriptMetaprogrammingViaScripting_02_UseFunctionDynamicly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/JavaScriptMetaprogrammingViaScripting_02_UseFunctionDynamicly.png -------------------------------------------------------------------------------- /Presentation/images/JavaScriptMetaprogrammingViaScripting_03_InjectionValuesIntoLocalExecutionScope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/JavaScriptMetaprogrammingViaScripting_03_InjectionValuesIntoLocalExecutionScope.png -------------------------------------------------------------------------------- /Presentation/images/JavaScript_Eval_vs_Roslyn_ScriptEngine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/JavaScript_Eval_vs_Roslyn_ScriptEngine.png -------------------------------------------------------------------------------- /Presentation/images/RoslynInspection_CalculateCyclomaticComplexity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/RoslynInspection_CalculateCyclomaticComplexity.png -------------------------------------------------------------------------------- /Presentation/images/RoslynSyntaxTree_00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/RoslynSyntaxTree_00.png -------------------------------------------------------------------------------- /Presentation/images/chocolatey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/chocolatey.png -------------------------------------------------------------------------------- /Presentation/images/hotcode_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/hotcode_logo.png -------------------------------------------------------------------------------- /Presentation/images/introspection_return_null_with_approvaltests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/introspection_return_null_with_approvaltests.png -------------------------------------------------------------------------------- /Presentation/images/itera_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/itera_logo.png -------------------------------------------------------------------------------- /Presentation/images/nemerle_compiletime_macro_execution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/nemerle_compiletime_macro_execution.png -------------------------------------------------------------------------------- /Presentation/images/nodejs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/nodejs.png -------------------------------------------------------------------------------- /Presentation/images/npm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/npm.png -------------------------------------------------------------------------------- /Presentation/images/nuget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/nuget.png -------------------------------------------------------------------------------- /Presentation/images/postsharp_validation_aspect-virtual_keyword_is_required.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/postsharp_validation_aspect-virtual_keyword_is_required.png -------------------------------------------------------------------------------- /Presentation/images/roslyn_ctp_compiler_pipeline_api_and_services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/roslyn_ctp_compiler_pipeline_api_and_services.png -------------------------------------------------------------------------------- /Presentation/images/roslyn_syntax_tree_for_return_null.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/roslyn_syntax_tree_for_return_null.png -------------------------------------------------------------------------------- /Presentation/images/scriptcs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/scriptcs.png -------------------------------------------------------------------------------- /Presentation/images/scriptcs_execution_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/scriptcs_execution_screenshot.png -------------------------------------------------------------------------------- /Presentation/images/type_name_collision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akimboyko/MetaProgramming/a07eeccf0f32a5a1f645ffe57e23c715cbcc55a4/Presentation/images/type_name_collision.png -------------------------------------------------------------------------------- /Presentation/js/architectural_validation.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | "use strict"; 3 | jsPlumb.ready(function() { 4 | jsPlumb.importDefaults({ 5 | // default drag options 6 | DragOptions : { cursor: 'pointer', zIndex: 2000 }, 7 | // default to blue at one end and green at the other 8 | EndpointStyles : [{ fillStyle: '#ffffff' }, { fillStyle: '#000000' }], 9 | // blue endpoints 7 px; green endpoints 11. 10 | Endpoints : [ [ "Dot", {radius: 3} ], [ "Dot", { radius: 3 } ]], 11 | // the overlays to decorate each connection with. note that the label overlay uses a function to generate the label text; in this 12 | // case it returns the 'labelText' member that we set on each connection in the 'init' method below. 13 | ConnectionOverlays : [ 14 | [ "Arrow", { location: 1.0 } ], 15 | [ "Label", { 16 | location: 0.1, 17 | id: "label", 18 | cssClass: "aLabel" 19 | } ] 20 | ] 21 | }); 22 | 23 | // this is the paint style for the connecting lines.. 24 | var connectorPaintStyle = { 25 | lineWidth: 4, 26 | strokeStyle: "#deea18", 27 | joinstyle: "round", 28 | outlineColor: "#EAEDEF", 29 | outlineWidth: 7 30 | }, 31 | 32 | // .. and this is the hover style. 33 | connectorHoverStyle = { 34 | lineWidth: 4, 35 | strokeStyle: "#2e2aF8" 36 | }, 37 | 38 | endpointHoverStyle = {fillStyle: "#2e2aF8"}, 39 | 40 | // the definition of source endpoints (the small blue ones) 41 | sourceEndpoint = { 42 | endpoint: "Rectangle", 43 | paintStyle: { fillStyle: "#225588", radius: 4 }, 44 | isSource: true, 45 | connector: [ "Flowchart", { stub: [40, 60], gap: 10, cornerRadius: 5 } ], 46 | connectorStyle: connectorPaintStyle, 47 | hoverPaintStyle: endpointHoverStyle, 48 | connectorHoverStyle: connectorHoverStyle, 49 | dragOptions: {}, 50 | overlays: [ 51 | [ "Label", { 52 | location: [0.5, 1.5], 53 | label: " ", 54 | cssClass: "endpointSourceLabel" 55 | } ] 56 | ] 57 | }, 58 | 59 | // a source endpoint that sits at BottomCenter 60 | // the definition of target endpoints (will appear when the user drags a connection) 61 | targetEndpoint = { 62 | endpoint: "Rectangle", 63 | paintStyle: { fillStyle: "#558822", radius: 4 }, 64 | hoverPaintStyle: endpointHoverStyle, 65 | maxConnections: -1, 66 | dropOptions: { hoverClass: "hover", activeClass: "active" }, 67 | isTarget: true, 68 | overlays: [ 69 | [ "Label", { location: [ 0.5, -0.5 ], label: " ", cssClass: "endpointTargetLabel" } ] 70 | ] 71 | }, 72 | 73 | init = function(connection) { 74 | connection.getOverlay("label"); 75 | connection.bind("editCompleted", function(o) { 76 | if (typeof console !== "undefined") { 77 | console.log("connection edited. path is now ", o.path); 78 | } 79 | }); 80 | }, 81 | 82 | allSourceEndpoints = [], 83 | 84 | addEndpointsFunc, 85 | 86 | allTargetEndpoints = []; 87 | addEndpointsFunc = function(toId, sourceAnchors, targetAnchors) { 88 | for (var i = 0; i < sourceAnchors.length; i++) { 89 | var sourceUUID = toId + sourceAnchors[i]; 90 | allSourceEndpoints.push(jsPlumb.addEndpoint(toId, sourceEndpoint, { anchor:sourceAnchors[i], uuid:sourceUUID })); 91 | } 92 | 93 | for (var j = 0; j < targetAnchors.length; j++) { 94 | var targetUUID = toId + targetAnchors[j]; 95 | allTargetEndpoints.push(jsPlumb.addEndpoint(toId, targetEndpoint, { anchor:targetAnchors[j], uuid:targetUUID })); 96 | } 97 | }; 98 | 99 | addEndpointsFunc("code", ["RightMiddle"], [ ]); 100 | addEndpointsFunc("cil", ["RightMiddle"], ["LeftMiddle"]); 101 | addEndpointsFunc("asm", [], ["LeftMiddle"]); 102 | addEndpointsFunc("modified", ["RightMiddle"], ["LeftMiddle"]); 103 | addEndpointsFunc("validate", ["RightMiddle"], ["LeftMiddle"]); 104 | addEndpointsFunc("initialize", ["RightMiddle"], ["LeftMiddle"]); 105 | 106 | // listen for new connections; initialise them the same way we initialise the connections at startup. 107 | jsPlumb.bind("jsPlumbConnection", function(connInfo, originalEvent) { 108 | init(connInfo.connection); 109 | }); 110 | 111 | // make all the window divs draggable 112 | jsPlumb.draggable(jsPlumb.getSelector(".window"), { grid: [20, 20] }); 113 | // THIS DEMO ONLY USES getSelector FOR CONVENIENCE. Use your library's appropriate selector method! 114 | //jsPlumb.draggable(jsPlumb.getSelector(".window")); 115 | 116 | 117 | // connect a few up 118 | jsPlumb.connect({uuids:["codeRightMiddle", "cilLeftMiddle"], editable:false}); 119 | jsPlumb.connect({uuids:["cilRightMiddle", "asmLeftMiddle"], editable:true}); 120 | // 121 | 122 | // 123 | // listen for clicks on connections, and offer to delete connections on click. 124 | // 125 | jsPlumb.bind("click", function(conn, originalEvent) { 126 | if (confirm("Delete connection from " + conn.sourceId + " to " + conn.targetId + "?")) 127 | jsPlumb.detach(conn); 128 | }); 129 | 130 | jsPlumb.bind("connectionDrag", function(connection) { 131 | console.log("connection " + connection.id + " is being dragged"); 132 | }); 133 | 134 | jsPlumb.bind("connectionDragStop", function(connection) { 135 | console.log("connection " + connection.id + " was dragged"); 136 | }); 137 | }); 138 | })(); 139 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MetaProgramming .Net samples 2 | ================================== 3 | 4 | #Metaprogramming via scripting 5 | * [Brilliant sample from 'Metaprogramming in .Net' book](Snippets/Scripting/JsEvalSample.html) 6 | * Scripting: Roslyn CTP vs. IronPython 7 | * [ScriptCS `eval()`-like](Snippets/Scripting/Roslyn-EvalSample.csx) 8 | * [Roslyn CTP: scripting and results as `dynamic`](Snippets/Scripting/Roslyn-ScriptingWithDynamiclyTypeResult.linq) 9 | * IronPython: scripting, DLR and results as `dynamic` 10 | * [C# code](Snippets/Scripting/IronPython-Scripting.linq) 11 | * [.py code](Snippets/Scripting/sample.py) 12 | 13 | #Dynamically generating .Net assembly at runtime 14 | * [Roslyn CTP: build and load assembly in memory](Snippets/Caas/Roslyn-BuildAtRuntime.linq) 15 | * CodeDOM 16 | * [build and load assembly in memory](Snippets/Caas/CodeDOM-BuildAtRuntime.linq) 17 | * [C# 4.0 and 5.0 features](Snippets/Caas/CodeDOM-BuildAtRuntimeCSharp45.linq), not supported by Roslyn CTP yet 18 | 19 | #Metaprogramming via runtime code generation 20 | * [Hardcoded C# rule: ~900ms to run 1000 iterations](Snippets/Performance/C#-HardCodedRule.linq) 21 | * [Roslyn CTP: scripting and statically typed results: ~950ms to run 1000 iterations](Snippets/Performance/Roslyn-ScriptingWithStaticlyTypedResult.linq) 22 | * [DLR i.e. Dynamic Language Runtime with ExpressionTrees: ~1200ms to run 1000 iterations](Snippets/Performance/DLR-ExpressionTrees.linq) 23 | 24 | #Code-as-Data approach 25 | * [Roslyn CTP convert VB → C#](Snippets/CodeAsData/Roslyn-ConvertVB2C#.linq), and [back](Snippets/CodeAsData/Roslyn-ConvertC#2VB.linq) 26 | * [Roslyn CTP and T4](https://github.com/akimboyko/MetaProgramming/tree/master/MetaProgramming) 27 | * Runtime template transformation using T4 28 | * Generate types, models and algorithms from JSON input using Roslyn CTP 29 | 30 | #Introspection 31 | * Roslyn CTP: Calculate code complexity 32 | * [asynchronously](Snippets/Introspection/Roslyn-CyclomaticComplexity.linq) 33 | * [using Rx](Snippets/Introspection/Roslyn-CyclomaticComplexityRx.linq) 34 | * Roslyn CTP: search for `return null;`. 35 | * [asynchronously](Snippets/Introspection/Roslyn-ReturnNull.linq) 36 | * [using Rx](Snippets/Introspection/Roslyn-ReturnNullRx.linq) 37 | * [using Syntax Walker](Snippets/Introspection/Roslyn-ReturnNullSyntaxWalker.linq) 38 | * [Full sample with `yeild return null;`, `default(T)` and value/reference types check is here](https://github.com/akimboyko/MetaProgramming/blob/7d4d8533d2be673fad2fbad37bb4d7a75399519a/MetaProgramming/MetaProgramming.RoslynCTP/Introspection.cs) 39 | * Using `System.Reflection` to limit dependencies of assemblies 40 | * [Test dependencies of assemblies intersection](/Snippets/Introspection/Reflection-TestReferencesIntersection.linq) 41 | 42 | #Nemerle: compile-time macro 43 | * Nemerle macro: compile- with run- time execution 44 | * [compile-time macro](MetaProgramming/MetaProgramming.Nemerle.Macro/TestMacro.n) 45 | * [compile-time macro usage](MetaProgramming/MetaProgramming.Nemerle/CompileTimeVsRunTimeExecutionSample.n) 46 | * [introduce new syntax keyword `fault`](MetaProgramming/MetaProgramming.Nemerle.Macro/Fault.n) 47 | * [new syntax keyword `fault` usage](MetaProgramming/MetaProgramming.Nemerle/FaultKeywordSample.n) 48 | -------------------------------------------------------------------------------- /Snippets/CaaS/CodeDOM-BuildAtRuntimeCSharp45.linq: -------------------------------------------------------------------------------- 1 | 2 | Roslyn 3 | Roslyn.Compilers 4 | Roslyn.Compilers.Common 5 | Roslyn.Compilers.CSharp 6 | Roslyn.Services.Common 7 | Roslyn.Services.CSharp 8 | Microsoft.CSharp.RuntimeHelpers 9 | Microsoft.Runtime.Hosting 10 | Microsoft.Runtime.Hosting.Interop 11 | Roslyn.Compilers 12 | Roslyn.Compilers.Common 13 | Roslyn.Compilers.Compilation 14 | Roslyn.Compilers.CSharp 15 | Roslyn.Scripting 16 | Roslyn.Scripting.CSharp 17 | Roslyn.Services 18 | Roslyn.Services.Classification 19 | Roslyn.Services.CodeCleanup 20 | Roslyn.Services.CodeGeneration 21 | Roslyn.Services.Completion 22 | Roslyn.Services.CSharp.Classification 23 | Roslyn.Services.FindReferences 24 | Roslyn.Services.Formatting 25 | Roslyn.Services.Host 26 | Roslyn.Services.Interactive 27 | Roslyn.Services.MetadataAsSource 28 | Roslyn.Services.Organizing 29 | Roslyn.Services.Shared.Extensions 30 | Roslyn.Utilities 31 | System 32 | System.Collections.Generic 33 | System.IO 34 | System.Linq 35 | System.Reflection 36 | System.Text 37 | System.CodeDom.Compiler 38 | true 39 | 40 | 41 | void Main() 42 | { 43 | const string programmingLanguage = "C#"; 44 | 45 | // CodeDOM with missing features C# 4 and 5 from RoslynCTP 46 | const string sourceCode = @"namespace DemoNamespace 47 | { 48 | using System; 49 | using System.Collections; 50 | using System.Threading; 51 | using System.Threading.Tasks; 52 | 53 | public static class Printer 54 | { 55 | // C# 5 'async' keyword 56 | public static async void Answer() 57 | { 58 | // Dynamic 59 | dynamic answer = 42; 60 | Console.WriteLine(Thread.CurrentThread.ManagedThreadId); 61 | // C# 5 'await' keyword 62 | var output = await Task.Run(() => string.Format(""Universal [async] answer is '{0}'"", answer)); 63 | System.Console.WriteLine(output); 64 | Console.WriteLine(Thread.CurrentThread.ManagedThreadId); 65 | } 66 | } 67 | }"; 68 | 69 | var sw = Stopwatch.StartNew(); 70 | 71 | var generatedAssembly = CompileAssembly(sourceCode, programmingLanguage); 72 | 73 | Assembly.Load(generatedAssembly.GetName()); 74 | 75 | var generatedType = generatedAssembly.ExportedTypes.Single(); 76 | 77 | generatedType.GetMethods() 78 | .Single(methodInfo => methodInfo.Name == "Answer") 79 | .Invoke(null, null); 80 | 81 | sw.Stop(); 82 | 83 | string.Format("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds).Dump(); 84 | } 85 | 86 | static Assembly CompileAssembly(string sourceCode, string programmingLanguage) 87 | { 88 | var codeProvider = CodeDomProvider.CreateProvider(programmingLanguage); 89 | 90 | var parameters = new CompilerParameters 91 | { 92 | GenerateInMemory = true 93 | }; 94 | 95 | parameters.ReferencedAssemblies.AddRange( 96 | new[] 97 | { 98 | @"System.Core.dll", 99 | @"Microsoft.CSharp.dll" 100 | }); 101 | 102 | var results = codeProvider.CompileAssemblyFromSource(parameters, sourceCode); 103 | 104 | if(results.Errors.HasErrors) 105 | { 106 | var errors = new StringBuilder("Following compilations error(s) found: "); 107 | 108 | errors.AppendLine(); 109 | 110 | foreach (CompilerError error in results.Errors) 111 | { 112 | errors.AppendFormat("Message: '{0}', LineNumber: {1}", error.ErrorText, error.Line); 113 | } 114 | 115 | throw new Exception(errors.ToString()); 116 | } 117 | 118 | return results.CompiledAssembly; 119 | } -------------------------------------------------------------------------------- /Snippets/CaaS/Roslyn-BuildAtRuntime.linq: -------------------------------------------------------------------------------- 1 | 2 | Roslyn 3 | Roslyn.Compilers 4 | Roslyn.Compilers.Common 5 | Roslyn.Compilers.CSharp 6 | Roslyn.Services.Common 7 | Roslyn.Services.CSharp 8 | Microsoft.CSharp.RuntimeHelpers 9 | Microsoft.Runtime.Hosting 10 | Microsoft.Runtime.Hosting.Interop 11 | Roslyn.Compilers 12 | Roslyn.Compilers.Common 13 | Roslyn.Compilers.Compilation 14 | Roslyn.Compilers.CSharp 15 | Roslyn.Scripting 16 | Roslyn.Scripting.CSharp 17 | Roslyn.Services 18 | Roslyn.Services.Classification 19 | Roslyn.Services.CodeCleanup 20 | Roslyn.Services.CodeGeneration 21 | Roslyn.Services.Completion 22 | Roslyn.Services.CSharp.Classification 23 | Roslyn.Services.FindReferences 24 | Roslyn.Services.Formatting 25 | Roslyn.Services.Host 26 | Roslyn.Services.Interactive 27 | Roslyn.Services.MetadataAsSource 28 | Roslyn.Services.Organizing 29 | Roslyn.Services.Shared.Extensions 30 | Roslyn.Utilities 31 | System 32 | System.Collections.Generic 33 | System.IO 34 | System.Linq 35 | System.Reflection 36 | System.Text 37 | true 38 | 39 | 40 | // code snippet with following errors 41 | // * 'dynamic' not supporter 42 | // * 'async'/'await' not supported 43 | const string codeSnippet = @"namespace DemoNamespace 44 | { 45 | using System; 46 | using System.Collections; 47 | using System.Threading; 48 | using System.Threading.Tasks; 49 | 50 | public class Printer 51 | { 52 | public void Answer() 53 | { 54 | // not working with RoslynCTP Set'12 55 | dynamic answer = 42; 56 | //int answer = 42; 57 | Console.WriteLine(Thread.CurrentThread.ManagedThreadId); 58 | 59 | // not working with RoslynCTP Set'12 60 | var output = await Task.Run(() => string.Format(""Universal [async] answer is '{0}'"", answer)); // not working with RoslynCTP Set'12 61 | //var output = Task.Run(() => string.Format(""Universal [async] answer is '{0}'"", answer)).Result; 62 | 63 | System.Console.WriteLine(output); 64 | Console.WriteLine(Thread.CurrentThread.ManagedThreadId); 65 | } 66 | } 67 | }"; 68 | 69 | // parse source code and create syntax tree 70 | var syntaxTree = SyntaxTree.ParseText(codeSnippet, 71 | options: new ParseOptions(languageVersion: LanguageVersion.CSharp5)); 72 | 73 | // check errors 74 | if(syntaxTree.GetDiagnostics().Any()) 75 | { 76 | syntaxTree.GetDiagnostics().Select(diagnostic => diagnostic.Info.ToString()).Dump(); 77 | throw new Exception("Parsing failed"); 78 | } 79 | 80 | // add references 81 | var references = new [] 82 | { 83 | MetadataReference.CreateAssemblyReference(typeof(Console).Assembly.FullName), 84 | MetadataReference.CreateAssemblyReference(typeof(System.Threading.Tasks.Task).Assembly.FullName), 85 | }; 86 | 87 | // create compilation 88 | var compilation = Compilation.Create( 89 | outputName: "Demo", 90 | options: new CompilationOptions(OutputKind.DynamicallyLinkedLibrary), 91 | syntaxTrees: new[] { syntaxTree }, 92 | references: references); 93 | 94 | // check errors 95 | if(compilation.GetDiagnostics().Any()) 96 | { 97 | var exceptionMessage = new StringBuilder("Compilation failed: ") 98 | .Append(string.Join(", ", 99 | compilation.GetDiagnostics() 100 | .Select(diagnostic => diagnostic.Info.ToString()))) 101 | .ToString(); 102 | throw new Exception(exceptionMessage); 103 | } 104 | 105 | // create assembly 106 | Assembly compiledAssembly; 107 | using (var stream = new MemoryStream()) 108 | { 109 | EmitResult compileResult = compilation.Emit(stream); 110 | compiledAssembly = Assembly.Load(stream.GetBuffer()); 111 | } 112 | 113 | // call method from new class 114 | dynamic instance = Activator.CreateInstance(compiledAssembly.GetTypes().First()); 115 | instance.Answer(); 116 | 117 | // check semantic model 118 | SemanticModel semanticModel = compilation.GetSemanticModel(syntaxTree); 119 | 120 | var methodDeclaration = syntaxTree.GetRoot().DescendantNodes().OfType().First(); 121 | 122 | semanticModel.GetDeclaredSymbol(methodDeclaration).Dump(); -------------------------------------------------------------------------------- /Snippets/CodeAsData/Roslyn-ConvertC#2VB.linq: -------------------------------------------------------------------------------- 1 | 2 | D:\work\Courses\MetaProgramming\MetaProgramming\MetaProgramming\MetaProgramming.RoslynCTP\bin\Debug\MetaProgramming.RoslynCTP.dll 3 | MetaProgramming.RoslynCTP 4 | true 5 | 6 | 7 | const string CSharpCode = @" 8 | namespace Generated 9 | { 10 | using System; 11 | 12 | public class GeneartedClass 13 | { 14 | public static Model.ReportModel Test(Model.ProcessingModel model) 15 | { 16 | model.Result = (model.InputA 17 | + (model.InputB * model.Factor)); 18 | model.Delta = (System.Math.Abs(model.Result.GetValueOrDefault(0m)) - model.InputA); 19 | model.Description = ""Some description""; 20 | Model.ReportModel reportModel = new Model.ReportModel(); 21 | reportModel.Σ = model.Result; 22 | reportModel.Δ = model.Delta; 23 | reportModel.λ = model.Description; 24 | return reportModel; 25 | } 26 | } 27 | }"; 28 | 29 | ConvertTo.VisualBasic(CSharpCode).Dump("C# → VB: haters gonna hate!"); -------------------------------------------------------------------------------- /Snippets/CodeAsData/Roslyn-ConvertVB2C#.linq: -------------------------------------------------------------------------------- 1 | 2 | D:\work\Courses\MetaProgramming\MetaProgramming\MetaProgramming\MetaProgramming.RoslynCTP\bin\Debug\MetaProgramming.RoslynCTP.dll 3 | MetaProgramming.RoslynCTP 4 | true 5 | 6 | 7 | // Code-as-Data 8 | const string VbCode = @" 9 | Imports System 10 | 11 | Namespace Generated 12 | Public Class GeneartedClass 13 | Public Shared Function Test(ByVal model As Model.ProcessingModel) As Model.ReportModel 14 | model.Result = (model.InputA _ 15 | + (model.InputB * model.Factor)) 16 | model.Delta = (System.Math.Abs(model.Result.GetValueOrDefault(0D)) - model.InputA) 17 | model.Description = ""Some description"" 18 | Dim reportModel As Model.ReportModel = New Model.ReportModel() 19 | reportModel.Σ = model.Result 20 | reportModel.Δ = model.Delta 21 | reportModel.λ = model.Description 22 | Return reportModel 23 | End Function 24 | End Class 25 | End Namespace"; 26 | 27 | ConvertTo.CSharp(VbCode).Dump("VB → C#: right way to convert code"); -------------------------------------------------------------------------------- /Snippets/Introspection/AfterProgramming-ReturnNull.csx: -------------------------------------------------------------------------------- 1 | // scriptcs -install -pre — run to install dependencies 2 | 3 | using System.Threading; 4 | using System.Diagnostics; 5 | using Roslyn.Compilers.CSharp; 6 | using Roslyn.Compilers.Common; 7 | using Newtonsoft.Json; 8 | using AfterProgramming; 9 | using AfterProgramming.Internal; 10 | 11 | // change path to solution 12 | const string solutionPath = @"D:\temp\nhibernate-core-master\src\NHibernate.Everything.sln"; 13 | 14 | var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5)); 15 | var cancellationToken = cancellationTokenSource.Token; 16 | 17 | Console.WriteLine("Start introspection at {0}…", solutionPath); 18 | 19 | var watch = Stopwatch.StartNew(); 20 | 21 | var results = new ReturnStatement() 22 | .SearchForReturnNullStatements(solutionPath, cancellationToken); 23 | 24 | watch.Stop(); 25 | 26 | Console.WriteLine( 27 | JsonConvert.SerializeObject( 28 | results.Take(10), Formatting.Indented)); 29 | 30 | Console.WriteLine("Finish introspection in {0} ms", watch.Elapsed); -------------------------------------------------------------------------------- /Snippets/Introspection/AfterProgramming-ReturnNull.linq: -------------------------------------------------------------------------------- 1 | 2 | AfterProgramming 3 | Newtonsoft.Json 4 | Roslyn.Compilers.CSharp 5 | AfterProgramming 6 | Newtonsoft.Json 7 | 8 | 9 | const string solutionPath = @"D:\temp\nhibernate-core-master\src\NHibernate.Everything.sln"; 10 | 11 | var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5)); 12 | var cancellationToken = cancellationTokenSource.Token; 13 | 14 | Console.WriteLine("Start introspection…"); 15 | 16 | var watch = Stopwatch.StartNew(); 17 | 18 | var results = new ReturnStatement() 19 | .SearchForReturnNullStatements(solutionPath, cancellationToken); 20 | 21 | watch.Stop(); 22 | 23 | JsonConvert.SerializeObject(results.Take(10), Newtonsoft.Json.Formatting.Indented).Dump(); 24 | 25 | Console.WriteLine("Finish introspection in {0} ms", watch.Elapsed); -------------------------------------------------------------------------------- /Snippets/Introspection/OptionTypeAndNull.linq: -------------------------------------------------------------------------------- 1 | 2 | 3 | // Sample from 4 | // Real-World Functional Programming 5 | // With examples in F# and C# 6 | // Tomas Petricek with Jon Skeet 7 | // http://www.manning.com/petricek/ 8 | 9 | void Main() 10 | { 11 | ReadInput().Dump("Option read from input"); 12 | } 13 | 14 | Option ReadInput() { 15 | string s = Util.ReadLine(); 16 | int parsed; 17 | if (Int32.TryParse(s, out parsed)) 18 | return Option.Some(parsed); 19 | else 20 | return Option.None(); 21 | } 22 | 23 | enum OptionType { Some, None }; 24 | abstract class Option { 25 | private readonly OptionType tag; 26 | protected Option(OptionType tag) { 27 | this.tag = tag; 28 | } 29 | public OptionType Tag { get { return tag; } } 30 | } 31 | 32 | class None : Option { 33 | public None() : base(OptionType.None) { } 34 | } 35 | 36 | class Some : Option { 37 | public Some(T value) : base(OptionType.Some) { 38 | this.value = value; 39 | } 40 | private readonly T value; 41 | public T Value { get { return value; } } 42 | } 43 | 44 | static class Option { 45 | public static Option None() { 46 | return new None(); 47 | } 48 | public static Option Some(T value) { 49 | return new Some(value); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Snippets/Introspection/Reflection-TestReferencesIntersection.linq: -------------------------------------------------------------------------------- 1 | 2 | D:\work\Courses\MetaProgramming\MetaProgramming\MetaProgramming.RoslynCTP.Tests\CodeSmells.Samples\CodeSmells.FakeBusinessLogic\bin\Debug\CodeSmells.FakeBusinessLogic.dll 3 | D:\work\Courses\MetaProgramming\MetaProgramming\MetaProgramming.RoslynCTP.Tests\CodeSmells.Samples\CodeSmells.FakeDataAccessLibrary\bin\Debug\CodeSmells.FakeDataAccessLibrary.dll 4 | D:\work\Courses\MetaProgramming\MetaProgramming\MetaProgramming.RoslynCTP.Tests\CodeSmells.Samples\CodeSmells.FakeWebApplication\bin\CodeSmells.FakeWebApplication.dll 5 | C:\Chocolatey\lib\NUnit.Runners.2.6.2\tools\nunit.framework.dll 6 | C:\Chocolatey\lib\NUnit.Runners.2.6.2\tools\lib\nunit-console-runner.dll 7 | <RuntimeDirectory>\System.Web.dll 8 | NUnit.Framework 9 | 10 | 11 | void Main() 12 | { 13 | // nunit runner 14 | NUnit.ConsoleRunner.Runner.Main(new string[] 15 | { 16 | Assembly.GetExecutingAssembly().Location, 17 | }); 18 | } 19 | 20 | public IEnumerable Assemblies 21 | { 22 | get 23 | { 24 | yield return typeof(CodeSmells.FakeDataAccessLibrary.Repository).Assembly; 25 | yield return typeof(CodeSmells.FakeBusinessLogic.BusinessRule).Assembly; 26 | yield return typeof(CodeSmells.FakeWebApplication.MvcApplication).Assembly; 27 | } 28 | } 29 | 30 | [Test, Combinatorial] 31 | public void TestReferencesIntersection( 32 | [ValueSource("Assemblies")] Assembly leftAssembly, 33 | [ValueSource("Assemblies")] Assembly rightAssembly) 34 | { 35 | if (leftAssembly == rightAssembly) return; 36 | 37 | var rightReferences = FilterOutAssemblies(rightAssembly); 38 | var leftReferences = FilterOutAssemblies(leftAssembly); 39 | 40 | Assert.That(leftReferences.Intersect(rightReferences), 41 | Is.Not.Null.And.Empty); 42 | } 43 | 44 | private static IEnumerable FilterOutAssemblies(Assembly source) 45 | { 46 | return new HashSet(source 47 | .GetReferencedAssemblies() 48 | .Where(assembly => assembly.Name != @"mscorlib" 49 | && assembly.Name != @"Microsoft.CSharp" 50 | && !assembly.Name.StartsWith(@"System") 51 | && !assembly.Name.StartsWith(@"AutoMapper") 52 | && !assembly.Name.StartsWith(@"nCrunch.TestRuntime") 53 | && !assembly.Name.StartsWith(@"PostSharp")) 54 | .Select(assembly => assembly.Name)); 55 | } -------------------------------------------------------------------------------- /Snippets/Introspection/Roslyn-CyclomaticComplexity.linq: -------------------------------------------------------------------------------- 1 | 2 | Roslyn.Services.CSharp 3 | Roslyn.Compilers.CSharp 4 | Roslyn.Services 5 | Roslyn.Compilers.Common 6 | System.Threading.Tasks 7 | System.Collections.Concurrent 8 | true 9 | 10 | 11 | void Main() 12 | { 13 | // prepare cancellationToken for async operations 14 | var cancellationTokenSource = new CancellationTokenSource(); 15 | cancellationTokenSource.CancelAfter(TimeSpan.FromMinutes(1)); 16 | var cancellationToken = cancellationTokenSource.Token; 17 | 18 | IEnumerable complexities; 19 | 20 | var stopwatch = new Stopwatch(); 21 | stopwatch.Start(); 22 | 23 | // load workspace, i.e. solution from Visual Studio 24 | using(var workspace = Workspace.LoadSolution(solutionPath)) 25 | { 26 | // save a reference to original state 27 | var origianlSolution = workspace.CurrentSolution; 28 | 29 | // build syntax root asynchronously in parallel for all documents from all projects 30 | complexities = 31 | origianlSolution 32 | .Projects 33 | .AsParallel() 34 | .AsUnordered() 35 | .WithCancellation(cancellationToken) 36 | .SelectMany(project => project.Documents) 37 | .Select(document => document.GetSyntaxRootAsync(cancellationToken)) 38 | // calculate complexity for all methods in parallel 39 | .SelectMany(syntaxRootAsync => 40 | CalculateComplexity(syntaxRootAsync, cancellationToken).Result) 41 | .ToArray(); 42 | 43 | // throw an exception if more then 1 minute passed since start 44 | cancellationToken.ThrowIfCancellationRequested(); 45 | } 46 | 47 | stopwatch.Stop(); 48 | stopwatch.Elapsed.Dump("Elapsed time"); 49 | 50 | // show results 51 | complexities 52 | .GroupBy(complexity => complexity.TypeIdentifier) 53 | .OrderByDescending(@group => @group.Sum(complexity => complexity.nStatementSyntax)) 54 | .Select(@group => @group.OrderByDescending(complexity => complexity.nStatementSyntax)) 55 | .Dump(); 56 | } 57 | 58 | // cloc info about hibernate-core-master from github 59 | // 5680 text files. 60 | // 5515 unique files. 61 | // 997 files ignored. 62 | // 63 | //http://cloc.sourceforge.net v 1.58 T=50.0 s (108.4 files/s, 15539.8 lines/s) 64 | //------------------------------------------------------------------------------- 65 | //Language files blank comment code 66 | //------------------------------------------------------------------------------- 67 | //C# 4007 61226 44433 341068 68 | //MSBuild scripts 6 0 42 5899 69 | const string solutionPath = @"D:\temp\nhibernate-core-master\src\NHibernate.Everything.sln"; 70 | 71 | // statements for independent paths through a program's source code 72 | private static readonly Func cyclomaticComplexityStatements = 73 | PredicateBuilder 74 | .False() 75 | .Or(s => s is DoStatementSyntax) 76 | .Or(s => s is ForEachStatementSyntax) 77 | .Or(s => s is ForStatementSyntax) 78 | .Or(s => s is IfStatementSyntax) 79 | .Or(s => s is SwitchStatementSyntax) 80 | .Or(s => s is UsingStatementSyntax) 81 | .Or(s => s is WhileStatementSyntax) 82 | .Compile(); 83 | 84 | // process descendant nodes of syntaxRoot 85 | private static async Task> CalculateComplexity( 86 | Task syntaxRootAsync, 87 | CancellationToken cancellationToken) 88 | { 89 | return 90 | (await syntaxRootAsync) 91 | .DescendantNodes() 92 | .OfType() 93 | .Select(methodDeclaration => 94 | new Complexity 95 | { 96 | TypeIdentifier = ((TypeDeclarationSyntax)methodDeclaration.Parent).Identifier.ValueText, 97 | MethodIdentifier = methodDeclaration.Identifier.ValueText, 98 | SourcesSample = methodDeclaration.ToString(), 99 | nStatementSyntax = methodDeclaration.DescendantNodes() 100 | .OfType() 101 | .Where(cyclomaticComplexityStatements) 102 | .Count() + 1, 103 | FilePath = methodDeclaration.GetLocation().SourceTree.FilePath, 104 | SourceLine = methodDeclaration.GetLocation().SourceTree.GetLineSpan(methodDeclaration.Span, true, cancellationToken).StartLinePosition.Line 105 | }) 106 | .Where(complexity => complexity.nStatementSyntax > 10) 107 | .ToArray(); 108 | } 109 | 110 | private class Complexity 111 | { 112 | public string TypeIdentifier { get; set; } 113 | public string MethodIdentifier { get; set; } 114 | public string SourcesSample { get; set; } 115 | public int nStatementSyntax { get; set; } 116 | public string FilePath { get; set; } 117 | public int SourceLine { get; set; } 118 | } -------------------------------------------------------------------------------- /Snippets/Introspection/Roslyn-ReturnNull.linq: -------------------------------------------------------------------------------- 1 | 2 | <RuntimeDirectory>\System.Runtime.dll 3 | <RuntimeDirectory>\System.Threading.Tasks.dll 4 | Microsoft.Bcl.Immutable 5 | Roslyn.Services.CSharp 6 | Roslyn.Compilers.Common 7 | Roslyn.Compilers.CSharp 8 | Roslyn.Services 9 | System.Collections.Concurrent 10 | System.Threading.Tasks 11 | true 12 | 13 | 14 | void Main() 15 | { 16 | // prepare cancellationToken for async operations 17 | var cancellationTokenSource = new CancellationTokenSource(); 18 | cancellationTokenSource.CancelAfter(TimeSpan.FromMinutes(1)); 19 | var cancellationToken = cancellationTokenSource.Token; 20 | 21 | IEnumerable returnNulls; 22 | 23 | var stopwatch = new Stopwatch(); 24 | stopwatch.Start(); 25 | 26 | // load workspace, i.e. solution from Visual Studio 27 | using(var workspace = Workspace.LoadSolution(solutionPath)) 28 | { 29 | // save a reference to original state 30 | var origianlSolution = workspace.CurrentSolution; 31 | 32 | // build syntax root and semantic model asynchronously in parallel 33 | // for all documents from all projects 34 | returnNulls = 35 | origianlSolution 36 | .Projects 37 | .AsParallel() 38 | .AsUnordered() 39 | .WithCancellation(cancellationToken) 40 | .SelectMany(project => project.Documents) 41 | .Select(document => document.GetSyntaxRootAsync(cancellationToken)) 42 | // calculate complexity for all methods in parallel 43 | .SelectMany(syntaxRootAsync => 44 | FindReturnNull(syntaxRootAsync, cancellationToken).Result) 45 | .ToArray(); 46 | 47 | // throw an exception if more then 1 minute passed since start 48 | cancellationToken.ThrowIfCancellationRequested(); 49 | } 50 | 51 | stopwatch.Stop(); 52 | stopwatch.Elapsed.Dump("Elapsed time"); 53 | 54 | // show results 55 | returnNulls 56 | .GroupBy(returnNull => returnNull.FilePath) 57 | .OrderBy(returnNullByFilePath => returnNullByFilePath.Key) 58 | .Select(returnNullByFilePath => new 59 | { 60 | FilePath = returnNullByFilePath.Key, 61 | ReturnNulls = 62 | returnNullByFilePath 63 | .OrderBy(returnNull => returnNull.SourceLine) 64 | .Select(returnNull => new { returnNull.SourceLine, returnNull.SourcesSample }) 65 | }) 66 | .Dump(); 67 | } 68 | 69 | // cloc info about hibernate-core-master from github 70 | // 5680 text files. 71 | // 5515 unique files. 72 | // 997 files ignored. 73 | // 74 | //http://cloc.sourceforge.net v 1.58 T=50.0 s (108.4 files/s, 15539.8 lines/s) 75 | //------------------------------------------------------------------------------- 76 | //Language files blank comment code 77 | //------------------------------------------------------------------------------- 78 | //C# 4007 61226 44433 341068 79 | //MSBuild scripts 6 0 42 5899 80 | const string solutionPath = 81 | @"D:\temp\nhibernate-core-master\src\NHibernate.Everything.sln"; 82 | 83 | // statements for `return null;` 84 | private static readonly Func returnNullStatement = 85 | PredicateBuilder 86 | .True() 87 | // all return statements 88 | .And(s => s is ReturnStatementSyntax) 89 | // with expression 90 | .And(s => (s as ReturnStatementSyntax).Expression != null) 91 | // with expression "null" 92 | .And(s => (s as ReturnStatementSyntax).Expression.Kind == SyntaxKind.NullLiteralExpression) 93 | .Compile(); 94 | 95 | // process descendant nodes of syntaxRoot 96 | private static async Task> FindReturnNull( 97 | Task syntaxRootAsync, 98 | CancellationToken cancellationToken) 99 | { 100 | return 101 | (await syntaxRootAsync) 102 | .DescendantNodes() 103 | .OfType() 104 | .Where(returnNull => returnNullStatement(returnNull)) 105 | .Select(returnNull => 106 | new ReturnNull 107 | { 108 | TypeIdentifier = GetParentSyntax(returnNull).Identifier.ValueText, 109 | SourcesSample = returnNull.ToString(), 110 | FilePath = returnNull.GetLocation().SourceTree.FilePath, 111 | SourceLine = returnNull 112 | .GetLocation().SourceTree 113 | .GetLineSpan(returnNull.Span, true, cancellationToken) 114 | .StartLinePosition.Line + 1 115 | }); 116 | } 117 | 118 | private class ReturnNull 119 | { 120 | public string TypeIdentifier { get; set; } 121 | public string SourcesSample { get; set; } 122 | public string FilePath { get; set; } 123 | public int SourceLine { get; set; } 124 | } 125 | 126 | private static TDeclarationSyntax GetParentSyntax(SyntaxNode statementSyntax) 127 | where TDeclarationSyntax : MemberDeclarationSyntax 128 | { 129 | SyntaxNode statement = statementSyntax; 130 | while(statement != null && !(statement is TDeclarationSyntax)) 131 | { 132 | statement = statement.Parent; 133 | } 134 | 135 | if(statement == null || !(statement is TDeclarationSyntax)) 136 | { 137 | throw new Exception(string.Format("Can't find parent {0} node", typeof(TDeclarationSyntax))); 138 | } 139 | 140 | return (TDeclarationSyntax)statement; 141 | } -------------------------------------------------------------------------------- /Snippets/Introspection/Roslyn-ReturnNullSyntaxWalker.linq: -------------------------------------------------------------------------------- 1 | 2 | <RuntimeDirectory>\System.Runtime.dll 3 | <RuntimeDirectory>\System.Threading.Tasks.dll 4 | Microsoft.Bcl.Immutable 5 | Roslyn.Services.CSharp 6 | Roslyn.Compilers.Common 7 | Roslyn.Compilers.CSharp 8 | Roslyn.Services 9 | System.Collections.Concurrent 10 | System.Threading.Tasks 11 | true 12 | 13 | 14 | void Main() 15 | { 16 | // prepare cancellationToken for async operations 17 | var cancellationTokenSource = new CancellationTokenSource(); 18 | cancellationTokenSource.CancelAfter(TimeSpan.FromMinutes(1)); 19 | var cancellationToken = cancellationTokenSource.Token; 20 | 21 | IEnumerable returnNulls; 22 | 23 | var stopwatch = new Stopwatch(); 24 | stopwatch.Start(); 25 | 26 | // load workspace, i.e. solution from Visual Studio 27 | using(var workspace = Workspace.LoadSolution(solutionPath)) 28 | { 29 | // save a reference to original state 30 | var origianlSolution = workspace.CurrentSolution; 31 | 32 | // build syntax root and semantic model asynchronously in parallel 33 | // for all documents from all projects 34 | returnNulls = 35 | origianlSolution 36 | .Projects 37 | .AsParallel() 38 | .AsUnordered() 39 | .WithCancellation(cancellationToken) 40 | .SelectMany(project => project.Documents) 41 | .Select(document => document.GetSyntaxRootAsync(cancellationToken)) 42 | // calculate complexity for all methods in parallel 43 | .SelectMany(syntaxRootAsync => 44 | FindReturnNull(syntaxRootAsync, cancellationToken).Result) 45 | .ToArray(); 46 | 47 | // throw an exception if more then 1 minute passed since start 48 | cancellationToken.ThrowIfCancellationRequested(); 49 | } 50 | 51 | stopwatch.Stop(); 52 | stopwatch.Elapsed.Dump("Elapsed time"); 53 | 54 | // show results 55 | returnNulls 56 | .GroupBy(returnNull => returnNull.FilePath) 57 | .OrderBy(returnNullByFilePath => returnNullByFilePath.Key) 58 | .Select(returnNullByFilePath => new 59 | { 60 | FilePath = returnNullByFilePath.Key, 61 | ReturnNulls = 62 | returnNullByFilePath 63 | .OrderBy(returnNull => returnNull.SourceLine) 64 | .Select(returnNull => new { returnNull.SourceLine, returnNull.SourcesSample }) 65 | }) 66 | .Dump(); 67 | } 68 | 69 | // cloc info about hibernate-core-master from github 70 | // 5680 text files. 71 | // 5515 unique files. 72 | // 997 files ignored. 73 | // 74 | //http://cloc.sourceforge.net v 1.58 T=50.0 s (108.4 files/s, 15539.8 lines/s) 75 | //------------------------------------------------------------------------------- 76 | //Language files blank comment code 77 | //------------------------------------------------------------------------------- 78 | //C# 4007 61226 44433 341068 79 | //MSBuild scripts 6 0 42 5899 80 | const string solutionPath = 81 | @"D:\temp\nhibernate-core-master\src\NHibernate.Everything.sln"; 82 | 83 | // statements for `return null;` 84 | private static readonly Func returnNullStatement = 85 | PredicateBuilder 86 | .True() 87 | .And(s => s is ReturnStatementSyntax) 88 | .And(s => (s as ReturnStatementSyntax).Expression != null) 89 | .And(s => (s as ReturnStatementSyntax).Expression.Kind == SyntaxKind.NullLiteralExpression) 90 | .Compile(); 91 | 92 | // process descendant nodes of syntaxRoot 93 | private static async Task> FindReturnNull( 94 | Task syntaxRootAsync, 95 | CancellationToken cancellationToken) 96 | { 97 | var walker = new ReturnNullWalker(cancellationToken); 98 | 99 | walker.Visit((await syntaxRootAsync) as SyntaxNode); 100 | 101 | return walker.Results; 102 | } 103 | 104 | private class ReturnNullWalker : SyntaxWalker 105 | { 106 | private readonly List results = new List(); 107 | private readonly CancellationToken cancellationToken; 108 | 109 | public ReturnNullWalker(CancellationToken cancellationToken) 110 | { 111 | this.cancellationToken = cancellationToken; 112 | } 113 | 114 | public IEnumerable Results { get { return results; } } 115 | 116 | public override void VisitReturnStatement(ReturnStatementSyntax returnNull) 117 | { 118 | base.VisitReturnStatement(returnNull); 119 | 120 | if(returnNullStatement(returnNull)) 121 | { 122 | results.Add( 123 | new ReturnNull 124 | { 125 | TypeIdentifier = GetParentSyntax(returnNull).Identifier.ValueText, 126 | SourcesSample = returnNull.ToString(), 127 | FilePath = returnNull.GetLocation().SourceTree.FilePath, 128 | SourceLine = returnNull 129 | .GetLocation().SourceTree 130 | .GetLineSpan(returnNull.Span, true, cancellationToken) 131 | .StartLinePosition.Line + 1 132 | }); 133 | } 134 | } 135 | } 136 | 137 | private class ReturnNull 138 | { 139 | public string TypeIdentifier { get; set; } 140 | public string SourcesSample { get; set; } 141 | public string FilePath { get; set; } 142 | public int SourceLine { get; set; } 143 | } 144 | 145 | private static TDeclarationSyntax GetParentSyntax(SyntaxNode statementSyntax) 146 | where TDeclarationSyntax : MemberDeclarationSyntax 147 | { 148 | SyntaxNode statement = statementSyntax; 149 | while(statement != null && !(statement is TDeclarationSyntax)) 150 | { 151 | statement = statement.Parent; 152 | } 153 | 154 | if(statement == null || !(statement is TDeclarationSyntax)) 155 | { 156 | throw new Exception(string.Format("Can't find parent {0} node", typeof(TDeclarationSyntax))); 157 | } 158 | 159 | return (TDeclarationSyntax)statement; 160 | } -------------------------------------------------------------------------------- /Snippets/Introspection/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Snippets/Other/Roslyn-C#compilerIssues.csx: -------------------------------------------------------------------------------- 1 | #region sample01 2 | var list = new List { 1, 2, 3 }; 3 | 4 | // Criterion 1: within a using statement... 5 | using (var e = list.GetEnumerator()) 6 | { 7 | // Criterion 2: ...which includes a closure... 8 | Func closure = () => e.Current; 9 | 10 | // Criterion 3: ...a mutable value type... 11 | while (e.MoveNext()) 12 | { 13 | Console.WriteLine(e.Current); 14 | } 15 | } 16 | #endregion 17 | 18 | #region sample02 19 | int x = 0; 20 | 21 | Action incrementX = () => x += 1; 22 | 23 | incrementX(); 24 | incrementX(); 25 | 26 | Console.WriteLine(x); 27 | #endregion -------------------------------------------------------------------------------- /Snippets/Other/SyntaxTreesSamples.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | public class Examples 4 | { 5 | public void Function() 6 | { 7 | var x = 6; 8 | System.Math.Sqrt(x * 7); 9 | } 10 | 11 | public IEnumerable Cases() 12 | { 13 | yield return "Foo"; 14 | } 15 | 16 | public object FactoryMethod() 17 | { 18 | if (true) 19 | return new object(); 20 | 21 | return null; 22 | } 23 | 24 | public object FactoryMethodWithDefault() 25 | { 26 | if (true) 27 | return new object(); 28 | 29 | return default(object); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Snippets/Performance/C#-HardCodedRule.linq: -------------------------------------------------------------------------------- 1 | 2 | true 3 | 4 | 5 | void Main() 6 | { 7 | // // input data sample 8 | // IEnumerable models = new[] 9 | // { 10 | // new Model.ProcessingModel { InputA = 10M, InputB = 5M, Factor = 0.050M } 11 | // }; 12 | 13 | // generate input data 14 | IEnumerable models = 15 | Enumerable.Range(0, 1000000) 16 | .Select(n => new Model.ProcessingModel { InputA = n, InputB = n * 0.5M, Factor = 0.050M }); 17 | 18 | var sw = Stopwatch.StartNew(); 19 | 20 | // process input data 21 | IEnumerable results = 22 | models 23 | .Select(model => 24 | { 25 | model.Result = model.InputA + model.InputB * model.Factor; 26 | model.Delta = Math.Abs((model.Result ?? 0M) - model.InputA); 27 | model.Description = @"Some description"; 28 | return new Model.ReportModel { Σ = model.Result, Δ = model.Delta, λ = model.Description }; 29 | }) 30 | .ToList(); 31 | 32 | sw.Stop(); 33 | 34 | string.Format("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds).Dump(); 35 | 36 | // merge results 37 | results 38 | .Zip(models, (result, model) => new { result, model }) 39 | .Select(@group => 40 | new 41 | { 42 | @return = @group.result, 43 | ResultModel = @group.model 44 | }) 45 | .Take(10) 46 | .Dump(); 47 | } 48 | } 49 | 50 | namespace Model 51 | { 52 | public class ProcessingModel 53 | { 54 | public decimal InputA { get; set; } 55 | public decimal InputB { get; set; } 56 | public decimal Factor { get; set; } 57 | 58 | public decimal? Result { get; set; } 59 | public decimal? Delta { get; set; } 60 | public string Description { get; set; } 61 | public decimal? Addition { get; set; } 62 | } 63 | 64 | public class ReportModel 65 | { 66 | public decimal? Σ { get; set; } 67 | public decimal? Δ { get; set; } 68 | public string λ { get; set; } 69 | } -------------------------------------------------------------------------------- /Snippets/Performance/DLR-ExpressionTrees.linq: -------------------------------------------------------------------------------- 1 | 2 | <RuntimeDirectory>\System.Linq.Expressions.dll 3 | true 4 | 5 | 6 | void Main() 7 | { 8 | // generate data 9 | IEnumerable models = 10 | Enumerable.Range(0, 1000000) 11 | .Select(n => new Model.ProcessingModel { InputA = n, InputB = n * 0.5M, Factor = 0.050M }); 12 | 13 | var sw = Stopwatch.StartNew(); 14 | 15 | // INFO: λ-expression has mathematical origin, while Rolsyn CodeDOM/Roslyn trees represent abstraction over code 16 | var modelParameter = Expression.Parameter(typeof(Model.ProcessingModel)); 17 | 18 | var resultExpression = Expression.Parameter(typeof(Model.ReportModel)); 19 | 20 | var expressionTree = 21 | Expression.Lambda>( 22 | Expression.Block(new Expression[] 23 | { 24 | // model.Result = model.InputA + model.InputB * model.Factor; 25 | Expression.Assign( 26 | Expression.Property(modelParameter, "Result"), 27 | Expression.TypeAs( 28 | Expression.Add( 29 | Expression.Property(modelParameter, "InputA"), 30 | Expression.Multiply( 31 | Expression.Property(modelParameter, "InputB"), 32 | Expression.Property(modelParameter, "Factor"))), typeof(decimal?))), 33 | 34 | // model.Delta = Math.Abs((model.Result ?? 0M) - model.InputA); 35 | Expression.Assign( 36 | Expression.Property(modelParameter, "Delta"), 37 | Expression.TypeAs( 38 | Expression.Subtract( 39 | Expression.Call(typeof(Math).GetMethod("Abs", new [] { typeof(decimal) }), 40 | Expression.Coalesce( 41 | Expression.Property(modelParameter, "Result"), 42 | Expression.Constant(0m, typeof(decimal))) 43 | ), 44 | Expression.Property(modelParameter, "InputA")), typeof(decimal?))), 45 | 46 | // model.Description = @"Some description"; 47 | Expression.Assign( 48 | Expression.Property(modelParameter, "Description"), 49 | Expression.Constant(@"Some description", typeof(string))), 50 | 51 | // return new Model.ReportModel { Σ = model.Result, Δ = model.Delta, λ = model.Description }; 52 | Expression.MemberInit( 53 | Expression.New(typeof(Model.ReportModel)), 54 | Expression.Bind( 55 | typeof(Model.ReportModel).GetMember("Σ").Single(), 56 | Expression.Property(modelParameter, "Result")), 57 | Expression.Bind( 58 | typeof(Model.ReportModel).GetMember("Δ").Single(), 59 | Expression.Property(modelParameter, "Delta")), 60 | Expression.Bind( 61 | typeof(Model.ReportModel).GetMember("λ").Single(), 62 | Expression.Property(modelParameter, "Description"))) 63 | 64 | }), modelParameter); 65 | 66 | var compiledFunctionOutOfExpressionTree = expressionTree.Compile(); 67 | 68 | IEnumerable results = 69 | models 70 | .Select(compiledFunctionOutOfExpressionTree) 71 | .ToList(); 72 | 73 | sw.Stop(); 74 | 75 | string.Format("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds).Dump(); 76 | 77 | results 78 | .Zip(models, (result, model) => new { result, model }) 79 | .Select(@group => 80 | new 81 | { 82 | @return = @group.result, 83 | ResultModel = @group.model 84 | }) 85 | .Take(10) 86 | .Dump(); 87 | } 88 | } 89 | 90 | namespace Model 91 | { 92 | public class ProcessingModel 93 | { 94 | public decimal InputA { get; set; } 95 | public decimal InputB { get; set; } 96 | public decimal Factor { get; set; } 97 | 98 | public decimal? Result { get; set; } 99 | public decimal? Delta { get; set; } 100 | public string Description { get; set; } 101 | public decimal? Addition { get; set; } 102 | } 103 | 104 | public class ReportModel 105 | { 106 | public decimal? Σ { get; set; } 107 | public decimal? Δ { get; set; } 108 | public string λ { get; set; } 109 | } -------------------------------------------------------------------------------- /Snippets/Performance/Roslyn-ScriptingWithStaticlyTypedResult.linq: -------------------------------------------------------------------------------- 1 | 2 | Roslyn 3 | Roslyn.Compilers 4 | Roslyn.Compilers.Common 5 | Roslyn.Compilers.CSharp 6 | Roslyn.Services.Common 7 | Roslyn.Services.CSharp 8 | Microsoft.CSharp.RuntimeHelpers 9 | Microsoft.Runtime.Hosting 10 | Microsoft.Runtime.Hosting.Interop 11 | Roslyn.Compilers 12 | Roslyn.Compilers.Common 13 | Roslyn.Compilers.Compilation 14 | Roslyn.Compilers.CSharp 15 | Roslyn.Scripting 16 | Roslyn.Scripting.CSharp 17 | Roslyn.Services 18 | Roslyn.Services.Classification 19 | Roslyn.Services.CodeCleanup 20 | Roslyn.Services.CodeGeneration 21 | Roslyn.Services.Completion 22 | Roslyn.Services.CSharp.Classification 23 | Roslyn.Services.FindReferences 24 | Roslyn.Services.Formatting 25 | Roslyn.Services.Host 26 | Roslyn.Services.Interactive 27 | Roslyn.Services.MetadataAsSource 28 | Roslyn.Services.Organizing 29 | Roslyn.Services.Shared.Extensions 30 | Roslyn.Utilities 31 | System 32 | System.Collections.Generic 33 | System.Dynamic 34 | System.IO 35 | System.Linq 36 | System.Reflection 37 | System.Text 38 | true 39 | 40 | 41 | void Main() 42 | { 43 | // generate input data 44 | IEnumerable models = 45 | Enumerable.Range(0, 1000000) 46 | .Select(n => new Model.ProcessingModel { InputA = n, InputB = n * 0.5M, Factor = 0.050M }); 47 | 48 | var sw = Stopwatch.StartNew(); 49 | 50 | // create scriot engine 51 | var engine = new ScriptEngine(); 52 | 53 | // add references 54 | new[] 55 | { 56 | typeof (Math).Assembly, 57 | this.GetType().Assembly 58 | }.ToList().ForEach(assembly => engine.AddReference(assembly)); 59 | 60 | // import assemblies 61 | new[] 62 | { 63 | "System", "System.Math", 64 | typeof(Model.ProcessingModel).Namespace 65 | } .ToList().ForEach(@namespace => engine.ImportNamespace(@namespace)); 66 | 67 | // limitations of script: 68 | // * no dynamic allowed 69 | // * no async/await allowed 70 | var script = 71 | @" 72 | Result = InputA + InputB * Factor; 73 | Delta = Math.Abs((Result ?? 0M) - InputA); 74 | Description = ""Some description""; 75 | new Model.ReportModel { Σ = Result, Δ = Delta, λ = Description } 76 | "; 77 | 78 | // create submission 79 | var submissionModel = new Model.ProcessingModel(); 80 | var session = engine.CreateSession(submissionModel); 81 | var submission = session.CompileSubmission(script); 82 | 83 | // process input data 84 | IEnumerable results = 85 | models 86 | .Select(model => 87 | { 88 | submissionModel.InputA = model.InputA; 89 | submissionModel.InputB = model.InputB; 90 | submissionModel.Factor = model.Factor; 91 | 92 | return submission.Execute(); 93 | }) 94 | .ToList(); 95 | 96 | sw.Stop(); 97 | 98 | string.Format("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds).Dump(); 99 | 100 | // merge results 101 | results 102 | .Zip(models, (result, model) => new { result, model }) 103 | .Select(@group => 104 | new 105 | { 106 | @return = @group.result, 107 | ResultModel = @group.model 108 | }) 109 | .Take(10) 110 | .Dump(); 111 | } 112 | } 113 | 114 | namespace Model 115 | { 116 | public class ProcessingModel 117 | { 118 | public decimal InputA { get; set; } 119 | public decimal InputB { get; set; } 120 | public decimal Factor { get; set; } 121 | 122 | public decimal? Result { get; set; } 123 | public decimal? Delta { get; set; } 124 | public string Description { get; set; } 125 | public decimal? Addition { get; set; } 126 | } 127 | 128 | public class ReportModel 129 | { 130 | public decimal? Σ { get; set; } 131 | public decimal? Δ { get; set; } 132 | public string λ { get; set; } 133 | } -------------------------------------------------------------------------------- /Snippets/README.md: -------------------------------------------------------------------------------- 1 | #Metaprogramming via... 2 | 3 | * Compiler-as-a-Service 4 | * Code-as-Data 5 | * Introspection 6 | * Scripting 7 | 8 | #C# snippets for LinqPAD 9 | 10 | * Roslyn CTP September 2012 11 | * Dynamic Language Runtime 12 | * CodeCOM 13 | * IronPython 14 | * ScriptCS 15 | * etc 16 | 17 | #Scripting/ScriptCs snippets 18 | 19 | * Scripting from C# using ScriptCs.Core 20 | * Automation using Selenium and FluentAutomation 21 | * Edge.js: Node.js ↔ .Net == two platforms 22 | * ScriptCs and PowerShell 23 | * Nake ScriptCs based build system 24 | -------------------------------------------------------------------------------- /Snippets/Scripting/IronPython-Scripting.linq: -------------------------------------------------------------------------------- 1 | 2 | IronPython 3 | IronPython.Hosting 4 | Microsoft.Scripting 5 | System.Threading.Tasks 6 | true 7 | 8 | 9 | async void Main() 10 | { 11 | var linqPadAssemblyName = GetType().Assembly.FullName.Split(new [] { ',' })[0]; 12 | 13 | IEnumerable models = 14 | Enumerable.Range(0, 1000000) 15 | .Select(n => new Model.ProcessingModel { InputA = n, InputB = n * 0.5M, Factor = 0.050M }); 16 | 17 | var sw = Stopwatch.StartNew(); 18 | 19 | var pyCodeReadingTask = Task.FromResult( 20 | File.ReadAllText(@"D:\work\Courses\MetaProgramming\Snippets\sample.py") 21 | .Replace("LinqPadAssemblyName", linqPadAssemblyName)); 22 | 23 | // create IronPython engine 24 | var pyEngine = Python.CreateEngine(); 25 | var pyScope = pyEngine.CreateScope(); 26 | var source = pyEngine.CreateScriptSourceFromString(await pyCodeReadingTask, SourceCodeKind.File); 27 | 28 | // execute script 29 | source.Execute(pyScope); 30 | 31 | dynamic businessRule = pyEngine.Operations.Invoke(pyScope.GetVariable("BusinessRule")); 32 | 33 | IEnumerable results = 34 | models 35 | .Select(model => businessRule.calculate(model)) 36 | .ToList(); 37 | 38 | sw.Stop(); 39 | 40 | string.Format("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds).Dump(); 41 | 42 | results 43 | .Zip(models, (result, model) => new { result, model }) 44 | .Select(@group => 45 | new 46 | { 47 | @return = @group.result, 48 | ResultModel = @group.model 49 | }) 50 | .Take(10) 51 | .Dump(); 52 | } 53 | } 54 | 55 | namespace Model 56 | { 57 | public class ProcessingModel 58 | { 59 | public decimal InputA { get; set; } 60 | public decimal InputB { get; set; } 61 | public decimal Factor { get; set; } 62 | 63 | public decimal? Result { get; set; } 64 | public decimal? Delta { get; set; } 65 | public string Description { get; set; } 66 | public decimal? Addition { get; set; } 67 | } 68 | 69 | public class ReportModel 70 | { 71 | public decimal? Σ { get; set; } 72 | public decimal? Δ { get; set; } 73 | public string λ { get; set; } 74 | } -------------------------------------------------------------------------------- /Snippets/Scripting/JsEvalSample.html: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 16 | 17 | 18 | fromValue:  19 |
20 | formula:  21 |
22 |
24 | toValue:  25 | 26 | -------------------------------------------------------------------------------- /Snippets/Scripting/JsEvalSample.md: -------------------------------------------------------------------------------- 1 | #JavaScript metaprogramming via scripting 2 | From [book 'Metaprogramming in .NET' by Kevin Hazzard and Jason Bock](http://www.manning.com/hazzard/) 3 | 4 | ```javascript 5 | function convert() { 6 | // get _string_ value from `fromVal` textbox and _evaluate_ it 7 | var fromValue = eval(fromVal.value); 8 | 9 | // get _string_ value from `formula` textbox, 10 | // and _evaluate_ using _local executing scope_ 11 | toVal.innerHTML = eval(formula.value).toString(); 12 | } 13 | ``` 14 | 15 | #Simple multiplication 16 | * fromValue: `6` 17 | * formula: `7 * fromValue` 18 | 19 | #Using function `Math.sqrt` dynamically 20 | * fromValue: `6` 21 | * formula: `Math.sqrt(7 * fromValue)` 22 | 23 | #Injection values into local execution scope 24 | * fromValue: `var someValue = 3` 25 | * formula: `Math.sqrt(7 * someValue)` -------------------------------------------------------------------------------- /Snippets/Scripting/README.md: -------------------------------------------------------------------------------- 1 | ##How to run AfterProgramming sample from ScriptCs 2 | * [Install Chocolatey](http://chocolatey.org/) 3 | * [Install ScriptCs using chocolatey](http://chocolatey.org/packages?q=scriptcs) 4 | * Install dependencies using `scriptcs -install -pre` 5 | * Edit `solutionPath` const to point to solution 6 | * Run `scriptcs .\AfterProgramming-ReturnNull.csx` 7 | -------------------------------------------------------------------------------- /Snippets/Scripting/Roslyn-EvalSample.csx: -------------------------------------------------------------------------------- 1 | // Steps: 2 | // * Get NuGet packages: `scriptcs -install` 3 | // * Run scriptcs: `scriptcs .\Roslyn-EvalSample.csx` 4 | 5 | using System; 6 | using Roslyn.Services.Interactive; 7 | using Roslyn.Scripting; 8 | using Roslyn.Scripting.CSharp; 9 | 10 | // limitations of scripts: 11 | // * no `dynamic` keyword allowed 12 | // * no async/await allowed 13 | 14 | System.Console.WriteLine("Enter two commands to execute"); 15 | System.Console.WriteLine("For example:"); 16 | System.Console.WriteLine("var x = 6;"); 17 | System.Console.WriteLine("System.Math.Sqrt(x * 7)"); 18 | System.Console.WriteLine(); 19 | 20 | var scripts = new [] 21 | { 22 | System.Console.ReadLine(), //fromValue: 23 | System.Console.ReadLine() //formula: 24 | }; 25 | 26 | var engine = new ScriptEngine(); // create script engine 27 | 28 | Array.ForEach( // add references to assembiles 29 | new[] { typeof(object).Assembly, GetType().Assembly }, 30 | @assembly => engine.AddReference(@assembly)); 31 | 32 | Array.ForEach( // import namespaces 33 | new[] { "System" }, 34 | @namespace => engine.ImportNamespace(@namespace)); 35 | 36 | var session = engine.CreateSession(); // create session 37 | 38 | object resultModel = null; 39 | 40 | // INFO: scripts are using same session 41 | foreach(var script in scripts) 42 | { 43 | resultModel = session // process scripts 44 | .CompileSubmission(script) 45 | .Execute(); 46 | } 47 | 48 | Console.WriteLine(resultModel); -------------------------------------------------------------------------------- /Snippets/Scripting/Roslyn-EvalSample.linq: -------------------------------------------------------------------------------- 1 | 2 | Roslyn 3 | Roslyn.Compilers 4 | Roslyn.Compilers.Common 5 | Roslyn.Compilers.CSharp 6 | Roslyn.Services.Common 7 | Roslyn.Services.CSharp 8 | Roslyn.Services.Interactive 9 | Roslyn.Scripting.CSharp 10 | System.Dynamic 11 | true 12 | 13 | 14 | // limitations of scripts: 15 | // * no `dynamic` keyword allowed 16 | // * no async/await allowed 17 | // For example: 18 | // var x = 6; 19 | // System.Math.Sqrt(x * 7) 20 | var scripts = new [] 21 | { 22 | Util.ReadLine(@"fromValue:"), //fromValue: 23 | Util.ReadLine(@"formula:") //formula: 24 | }; 25 | 26 | var engine = new ScriptEngine(); // create script engine 27 | 28 | Array.ForEach( // add references to assembiles 29 | new[] { typeof(object).Assembly, GetType().Assembly }, 30 | @assembly => engine.AddReference(@assembly)); 31 | 32 | Array.ForEach( // import namespaces 33 | new[] { "System" }, 34 | @namespace => engine.ImportNamespace(@namespace)); 35 | 36 | var session = engine.CreateSession(); // create session 37 | 38 | dynamic resultModel = null; 39 | 40 | // INFO: scripts are using same session 41 | foreach(var script in scripts) 42 | { 43 | resultModel = session // process scripts 44 | .CompileSubmission(script) 45 | .Execute(); 46 | } 47 | 48 | (resultModel as object).Dump(); -------------------------------------------------------------------------------- /Snippets/Scripting/Roslyn-ScriptingWithDynamiclyTypeResult.linq: -------------------------------------------------------------------------------- 1 | 2 | Roslyn 3 | Roslyn.Compilers 4 | Roslyn.Compilers.Common 5 | Roslyn.Compilers.CSharp 6 | Roslyn.Services.Common 7 | Roslyn.Services.CSharp 8 | Microsoft.CSharp.RuntimeHelpers 9 | Microsoft.Runtime.Hosting 10 | Microsoft.Runtime.Hosting.Interop 11 | Roslyn.Compilers 12 | Roslyn.Compilers.Common 13 | Roslyn.Compilers.Compilation 14 | Roslyn.Compilers.CSharp 15 | Roslyn.Scripting 16 | Roslyn.Scripting.CSharp 17 | Roslyn.Services 18 | Roslyn.Services.Classification 19 | Roslyn.Services.CodeCleanup 20 | Roslyn.Services.CodeGeneration 21 | Roslyn.Services.Completion 22 | Roslyn.Services.CSharp.Classification 23 | Roslyn.Services.FindReferences 24 | Roslyn.Services.Formatting 25 | Roslyn.Services.Host 26 | Roslyn.Services.Interactive 27 | Roslyn.Services.MetadataAsSource 28 | Roslyn.Services.Organizing 29 | Roslyn.Services.Shared.Extensions 30 | Roslyn.Utilities 31 | System 32 | System.Collections.Generic 33 | System.Dynamic 34 | System.IO 35 | System.Linq 36 | System.Reflection 37 | System.Text 38 | true 39 | 40 | 41 | void Main() 42 | { 43 | // generate input data 44 | IEnumerable models = 45 | Enumerable.Range(0, 1000000) 46 | .Select(n => new Model.ProcessingModel { InputA = n, InputB = n * 0.5M, Factor = 0.050M }); 47 | 48 | var sw = Stopwatch.StartNew(); 49 | 50 | // create scriot engine 51 | var engine = new ScriptEngine(); 52 | 53 | // add references 54 | new[] 55 | { 56 | typeof (Math).Assembly, 57 | this.GetType().Assembly 58 | }.ToList().ForEach(assembly => engine.AddReference(assembly)); 59 | 60 | // import assemblies 61 | new[] 62 | { 63 | "System", "System.Math", 64 | typeof(Model.ProcessingModel).Namespace 65 | } .ToList().ForEach(@namespace => engine.ImportNamespace(@namespace)); 66 | 67 | // limitations of script: 68 | // * no dynamic allowed 69 | // * no async/await allowed 70 | var script = 71 | @" 72 | Result = InputA + InputB * Factor; 73 | Delta = Math.Abs((Result ?? 0M) - InputA); 74 | Description = ""Some description""; 75 | new Model.ReportModel { Σ = Result, Δ = Delta, λ = Description } 76 | "; 77 | 78 | // create submission 79 | var submissionModel = new Model.ProcessingModel(); 80 | var session = engine.CreateSession(submissionModel); 81 | var submission = session.CompileSubmission(script); 82 | 83 | // process input data 84 | IEnumerable results = 85 | models 86 | .Select(model => 87 | { 88 | submissionModel.InputA = model.InputA; 89 | submissionModel.InputB = model.InputB; 90 | submissionModel.Factor = model.Factor; 91 | 92 | return submission.Execute(); 93 | }) 94 | .ToList(); 95 | 96 | sw.Stop(); 97 | 98 | string.Format("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds).Dump(); 99 | 100 | // merge results 101 | results 102 | .Zip(models, (result, model) => new { result, model }) 103 | .Select(@group => 104 | new 105 | { 106 | @return = @group.result, 107 | ResultModel = @group.model 108 | }) 109 | .Take(10) 110 | .Dump(); 111 | } 112 | } 113 | 114 | namespace Model 115 | { 116 | public class ProcessingModel 117 | { 118 | public decimal InputA { get; set; } 119 | public decimal InputB { get; set; } 120 | public decimal Factor { get; set; } 121 | 122 | public decimal? Result { get; set; } 123 | public decimal? Delta { get; set; } 124 | public string Description { get; set; } 125 | public decimal? Addition { get; set; } 126 | } 127 | 128 | public class ReportModel 129 | { 130 | public decimal? Σ { get; set; } 131 | public decimal? Δ { get; set; } 132 | public string λ { get; set; } 133 | } -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/Edge.js/EdgeJs2ClrSample.js: -------------------------------------------------------------------------------- 1 | var edge = require('edge'); 2 | 3 | // Call C# async lambda from node.js 4 | // Compile source code on the fly 5 | // Use C# dynamics to access objects passed from JavaScript 6 | var funcCs = edge.func('cs', function() { /* 7 | using System.Threading.Tasks; 8 | 9 | async (dynamic input) => 10 | { 11 | // with dynamics and callbacks 12 | return new 13 | { 14 | message = string.Format(@"C# welcomes {0}, {1} happens at {2}", 15 | input.platform.ToString(), 16 | await input.something(null), 17 | DateTime.Now), 18 | origin = "from C#" 19 | }; 20 | } 21 | */}); 22 | 23 | // Use C# function at Node.js 24 | var callbackFromCs = edge.func(function () {/* 25 | async (input) => { 26 | // C# function is also data 27 | return (Func>)(async (i) => { 28 | return "Callback from .NET returned to Node.Js"; 29 | }); 30 | } 31 | */}); 32 | 33 | // Pass data from node.js to C# 34 | var payload = { 35 | platform: 'Node.js', 36 | 37 | // Node.js function is also data 38 | something: function(input, callback) { 39 | callback(null, "callback to Node.js"); 40 | } 41 | }; 42 | 43 | // Make asynchronous call to C# function 44 | funcCs(payload, function(error, result) { 45 | if(error) throw error; 46 | console.log(result); 47 | }); 48 | 49 | // C# function is also data, call it from Node.js 50 | var callbackCs = callbackFromCs(null, true); 51 | console.log(callbackCs(null, true)); -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/Edge.js/EdgeJs2ProjectlessCsx.js: -------------------------------------------------------------------------------- 1 | var edge = require('edge'); 2 | 3 | var csx = edge.func("ProjectlessCsx.csx"); 4 | 5 | var payload = { 6 | platform: 'Node.js', 7 | something: function(input, callback) { 8 | callback(null, "callback to Node.js"); 9 | } 10 | }; 11 | 12 | // Make asynchronous call to projectless csx 13 | csx(payload, function(error, result) { 14 | if(error) throw error; 15 | console.log(result); 16 | }); 17 | 18 | console.log("Node.js continues!"); -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/Edge.js/ProjectlessCsx.csx: -------------------------------------------------------------------------------- 1 | // use #r "SomeDotNetLibrary.dll" to load assembly 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Threading.Tasks; 6 | 7 | // Edge.js has floowing convention: 8 | // start `class Startup::public async Task Invoke(object input)` 9 | public class Startup 10 | { 11 | public async Task Invoke(object input) 12 | { 13 | // we are on V8 thread here 14 | var dictionary = (IDictionary)input; 15 | 16 | // Run CPU-bound background work on CLR thread pool 17 | return await Task.Run(async() => 18 | { 19 | Console.WriteLine("CLR simulates CPU bound operation"); 20 | Console.Out.FlushAsync(); 21 | 22 | // we are on CLR thread pool thread here 23 | await Task.Delay(2000); // simulate CPU bound 24 | 25 | Console.WriteLine("CLR continues..."); 26 | Console.Out.FlushAsync(); 27 | 28 | // Pass data from C# to node.js 29 | return new 30 | { 31 | message = 32 | string.Format(@"CSX welcomes {0}, {1} happens at {2}", 33 | dictionary["platform"].ToString(), 34 | await(dictionary["something"] as Func>)(null), 35 | DateTime.Now), 36 | origin = "from Projectless CSX" 37 | }; 38 | }); 39 | } 40 | } -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/EmbededScriptCsWithNuGetSupport.csx: -------------------------------------------------------------------------------- 1 | // ScriptCs sample with Newtonsoft.Json — just for test 2 | using Newtonsoft.Json; 3 | 4 | var message = new { messaeg = "Hello, new JSON world!", timestamp = DateTime.Now }; 5 | 6 | Console.WriteLine( 7 | JsonConvert.SerializeObject( 8 | message, 9 | Newtonsoft.Json.Formatting.Indented)); -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/FluentAutomation.SeleniumWebDriver/FluentAutomation.SeleniumWebDriver.csx: -------------------------------------------------------------------------------- 1 | #r "D:\work\Courses\MetaProgramming\Snippets\Scripting\ScriptCs\FluentAutomation.SeleniumWebDriver\bin\FluentAutomation.Core.dll" 2 | #r "D:\work\Courses\MetaProgramming\Snippets\Scripting\ScriptCs\FluentAutomation.SeleniumWebDriver\bin\FluentAutomation.SeleniumWebDriver.dll" 3 | 4 | using System; 5 | using System.IO; 6 | using System.Reflection; 7 | using FluentAutomation; 8 | using FluentAutomation.Interfaces; 9 | 10 | Settings.ScreenshotPath = @"d:\temp\"; 11 | Settings.ScreenshotOnFailedExpect = false; 12 | Settings.ScreenshotOnFailedAction = false; 13 | Settings.DefaultWaitTimeout = TimeSpan.FromSeconds(1); 14 | Settings.DefaultWaitUntilTimeout = TimeSpan.FromSeconds(5); 15 | Settings.MinimizeAllWindowsOnTestStart = false; 16 | 17 | private static INativeActionSyntaxProvider I = null; 18 | 19 | public static void Bootstrap(string browserName) 20 | { 21 | MethodInfo bootstrapMethod = null; 22 | ParameterInfo[] bootstrapParams = null; 23 | 24 | MethodInfo[] methods = typeof(T).GetMethods(BindingFlags.Static | BindingFlags.Public); 25 | foreach (var methodInfo in methods) 26 | { 27 | if (methodInfo.Name.Equals("Bootstrap")) 28 | { 29 | bootstrapMethod = methodInfo; 30 | bootstrapParams = methodInfo.GetParameters(); 31 | if (bootstrapParams.Length == 1) 32 | { 33 | break; 34 | } 35 | } 36 | } 37 | 38 | var browserEnumValue = Enum.Parse(bootstrapParams[0].ParameterType, browserName); 39 | bootstrapMethod.Invoke(null, new object[] { browserEnumValue }); 40 | 41 | I = new FluentTest().I; 42 | 43 | // hack to move drivers into bin so they can be located by Selenium (only prob on scriptcs atm) 44 | foreach (var driver in Directory.GetFiles(Environment.CurrentDirectory, "*.exe")) 45 | { 46 | var newFileName = Path.Combine(Environment.CurrentDirectory, "bin", Path.GetFileName(driver)); 47 | if (!File.Exists(newFileName)) File.Move(driver, newFileName); 48 | } 49 | } 50 | 51 | Bootstrap("InternetExplorer"); 52 | 53 | try 54 | { 55 | I.Open(@"http://localhost:8080/knockout.js/index.html"); 56 | 57 | var firstInput = I.Find("input#firstName"); 58 | I.Expect.Value("John").In(firstInput); 59 | 60 | var secondInput = I.Find("input#lastName"); 61 | I.Expect.Value("Doe").In(secondInput); 62 | 63 | I.Enter("Ole").In(firstInput); 64 | 65 | I.Press("{TAB}"); 66 | 67 | I.Enter("Hansenn").In(secondInput); 68 | 69 | I.Press("{TAB}"); 70 | 71 | I.WaitUntil(() => I.Expect.Value("Ole Hansenn").In("span#fullName")); 72 | 73 | I.TakeScreenshot(@"test"); 74 | } 75 | finally 76 | { 77 | I.Dispose(); 78 | 79 | const string ieDriverServerExeFile = @".\bin\IEDriverServer.exe"; 80 | 81 | if(File.Exists(ieDriverServerExeFile)) 82 | { 83 | File.Delete(ieDriverServerExeFile); 84 | } 85 | } -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/FluentAutomation.SeleniumWebDriver/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/README.md: -------------------------------------------------------------------------------- 1 | ScriptCs for Project-less development 2 | ===================================== 3 | 4 | Install ScriptCS 5 | ---------------- 6 | 7 | * Install [Chocolatey](http://chocolatey.org/) 8 | * Install [ScriptCs](http://chocolatey.org/packages/ScriptCs): `cinst ScriptCs` 9 | 10 | REPL 11 | ---- 12 | 1. `scriptcs -install` 13 | 2. `scriptcs` 14 | 3. `> using Newtonsoft.Json;` 15 | 4. `> JsonConvert.SerializeObject(DateTime.Now);` 16 | 17 | ScriptCs and project-less environment and prototyping 18 | ----------------------------------------------------- 19 | 20 | 1. run shell with administrative rights, to be able to open port for listening 21 | 2. install WebApi script pack: `scriptcs -install ScriptCs.WebApi` 22 | 3. run script: `scriptcs.exe .\ScriptCs.WebApi.Sample.csx` 23 | 24 | Scripting from C# using ScriptCs.Core 25 | ------------------------------------- 26 | 27 | ```csharp 28 | // preserve current directory 29 | var previousCurrentDirectory = Environment.CurrentDirectory; 30 | 31 | try 32 | { 33 | // set directory to where script is 34 | // required to find NuGet dependencies 35 | Environment.CurrentDirectory = Path.GetDirectoryName(scriptPath); 36 | 37 | // prepare NuGet dependencies, download them if required 38 | var nuGetReferences = PreparePackages( 39 | scriptPath, 40 | fileSystem, packageAssemblyResolver, 41 | packageInstaller, logger.Info); 42 | 43 | // get script packs: not fully tested yet 44 | var scriptPacks = scriptPackResolver.GetPacks(); 45 | 46 | // execute script from file 47 | scriptExecutor.Initialize(nuGetReferences, scriptPacks); 48 | scriptExecutor.Execute(scriptPath); 49 | } 50 | finally 51 | { 52 | // restore current directory 53 | Environment.CurrentDirectory = previousCurrentDirectory; 54 | } 55 | ``` 56 | 57 | ScriptCs and Selenium/FluentAutomation 58 | -------------------------------------- 59 | 60 | 1. Add WebDriver to packages.config 61 | 2. `scriptcs -install` 62 | 3. WebDriver + FireFox: `scriptcs.exe .\SeleniumWebDriver.FireFox.csx` 63 | 4. WebDriver + PhantomJs: `scriptcs.exe .\SeleniumWebDriver.PhantomJs.csx` 64 | 65 | Edge.js: Node.js ↔ .Net == two platforms 66 | ---------------------------------------- 67 | 68 | 1. Edge.js samples: `node EdgeJs2ClrSample.js` 69 | 2. Edge.js with *.csx file `node EdgeJs2ProjectlessCsx.js` 70 | 71 | ScriptCs and PowerShell 72 | ----------------------- 73 | 74 | * `import-module scriptcs` 75 | * `invoke-scriptcs '"Hello PowerShell!"'` 76 | 77 | see [ScriptCS-PowerShell-Module](https://github.com/beefarino/ScriptCS-PowerShell-Module) for details 78 | 79 | ScriptCs and Nake 80 | ----------------------- 81 | 82 | [Nake is a C# script-based build tool for .NET inspired by Jake/Rake](https://github.com/yevhen/Nake/blob/dev/Nake.csx) -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/ScriptCs.WebApi.Sample.csx: -------------------------------------------------------------------------------- 1 | // 1. run shell with administrative rights, to be able to open port for listening 2 | // 2. install WebApi script pack: `scriptcs -install ScriptCs.WebApi` 3 | // 3. run script: `scriptcs.exe .\ScriptCs.WebApi.Sample.csx` 4 | 5 | using System; 6 | using System.Web.Http; 7 | using System.Web.Http.SelfHost; 8 | 9 | // will listen at http://localhost:8888/test/ 10 | public class TestController : ApiController 11 | { 12 | public string Get() 13 | { 14 | return "Hello world from ScriptCs.WebApi!"; 15 | } 16 | } 17 | 18 | // require/load script pack for WebAPI 19 | var webApi = Require(); 20 | var server = webApi.CreateServer("http://localhost:8888"); 21 | server.OpenAsync().Wait(); 22 | 23 | Console.WriteLine("Listening..."); 24 | Console.ReadKey(); 25 | server.CloseAsync().Wait(); -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/SeleniumWebDriver/SeleniumWebDriver.FireFox.csx: -------------------------------------------------------------------------------- 1 | #r "System.Drawing" 2 | #r "D:\work\Courses\MetaProgramming\Snippets\Scripting\ScriptCs\SeleniumWebDriver\bin\WebDriver.dll" 3 | #r "D:\work\Courses\MetaProgramming\Snippets\Scripting\ScriptCs\SeleniumWebDriver\bin\WebDriver.Support.dll" 4 | #r "D:\work\Courses\MetaProgramming\Snippets\Scripting\ScriptCs\SeleniumWebDriver\bin\nunit.framework.dll" 5 | #r "D:\work\Courses\MetaProgramming\Snippets\Scripting\ScriptCs\SeleniumWebDriver\bin\FluentAssertions.dll" 6 | 7 | using System; 8 | using System.Drawing.Imaging; 9 | using OpenQA.Selenium; 10 | using OpenQA.Selenium.Firefox; 11 | using OpenQA.Selenium.Support.UI; 12 | using FluentAssertions; 13 | 14 | // create WebDriver instance 15 | using (var driver = new FirefoxDriver()) 16 | { 17 | try 18 | { 19 | driver.Navigate().GoToUrl(@"http://localhost:8080/knockout.js/index.html"); 20 | 21 | var firstName = driver.FindElement(By.Id("firstName")); 22 | 23 | firstName.Clear(); 24 | firstName.SendKeys("Ole"); 25 | firstName.SendKeys(Keys.Tab); 26 | 27 | var lastName = driver.FindElement(By.Id("lastName")); 28 | 29 | lastName.Clear(); 30 | lastName.SendKeys("Hansenn"); 31 | lastName.SendKeys(Keys.Tab); 32 | 33 | WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(3)); 34 | wait.Until(c => c.FindElement(By.Id("fullName")).Text.Contains("Ole Hansenn")); 35 | 36 | driver.FindElement(By.Id("fullName")).Text.Should().Be("Ole Hansenn"); 37 | } 38 | finally 39 | { 40 | // create screenshot 41 | driver 42 | .GetScreenshot() 43 | .SaveAsFile("./test_firefox.png", ImageFormat.Png); 44 | 45 | driver.Quit(); 46 | } 47 | } -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/SeleniumWebDriver/SeleniumWebDriver.PhantomJs.csx: -------------------------------------------------------------------------------- 1 | #r "System.Drawing" 2 | #r "D:\work\Courses\MetaProgramming\Snippets\Scripting\ScriptCs\SeleniumWebDriver\bin\WebDriver.dll" 3 | #r "D:\work\Courses\MetaProgramming\Snippets\Scripting\ScriptCs\SeleniumWebDriver\bin\WebDriver.Support.dll" 4 | #r "D:\work\Courses\MetaProgramming\Snippets\Scripting\ScriptCs\SeleniumWebDriver\bin\nunit.framework.dll" 5 | #r "D:\work\Courses\MetaProgramming\Snippets\Scripting\ScriptCs\SeleniumWebDriver\bin\FluentAssertions.dll" 6 | 7 | using System; 8 | using System.IO; 9 | using OpenQA.Selenium; 10 | using OpenQA.Selenium.PhantomJS; 11 | using OpenQA.Selenium.Support.UI; 12 | using FluentAssertions; 13 | 14 | // hack to move drivers into bin so they can be located by Selenium (only prob on scriptcs atm) 15 | foreach (var driver in Directory.GetFiles(Environment.CurrentDirectory, "*.exe", SearchOption.AllDirectories)) 16 | { 17 | var newFileName = Path.Combine(Environment.CurrentDirectory, "bin", Path.GetFileName(driver)); 18 | File.Copy(driver, newFileName); 19 | } 20 | 21 | const string phantomjsExeFile = @".\bin\phantomjs.exe"; 22 | 23 | // create WebDriver instance 24 | using (var driver = new PhantomJSDriver()) 25 | { 26 | try 27 | { 28 | driver.Navigate().GoToUrl(@"http://localhost:8080/knockout.js/index.html"); 29 | 30 | var firstName = driver.FindElement(By.Id("firstName")); 31 | 32 | firstName.Clear(); 33 | firstName.SendKeys("Ole"); 34 | firstName.SendKeys(Keys.Tab); 35 | 36 | var lastName = driver.FindElement(By.Id("lastName")); 37 | 38 | lastName.Clear(); 39 | lastName.SendKeys("Hansenn"); 40 | lastName.SendKeys(Keys.Tab); 41 | 42 | WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(3)); 43 | wait.Until(c => c.FindElement(By.Id("fullName")).Text.Contains("Ole Hansenn")); 44 | 45 | driver.FindElement(By.Id("fullName")).Text.Should().Be("Ole Hansenn"); 46 | } 47 | finally 48 | { 49 | // create screenshot 50 | driver 51 | .GetScreenshot() 52 | .SaveAsFile("./test_phantomjs.png", System.Drawing.Imaging.ImageFormat.Png); 53 | 54 | driver.Quit(); 55 | 56 | // cleanup phantomjs.exe binary 57 | if (File.Exists(phantomjsExeFile)) File.Delete(phantomjsExeFile); 58 | } 59 | } -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/SeleniumWebDriver/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Snippets/Scripting/ScriptCs/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Snippets/Scripting/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Snippets/Scripting/sample.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf8 -*- 2 | 3 | import math 4 | import clr 5 | clr.AddReference("LinqPadAssemblyName") # linq snippet assembly name 6 | 7 | from Model import * 8 | 9 | class BusinessRule: 10 | def calculate(self, model): 11 | result = model.InputA + model.InputB * model.Factor 12 | delta = math.fabs(result - model.InputA) 13 | description = 'Some description' 14 | 15 | resultModel = ReportModel() 16 | resultModel.Σ = result 17 | resultModel.Δ = delta 18 | resultModel.λ = description 19 | 20 | return resultModel --------------------------------------------------------------------------------