diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets
index 305e736c..52f41c60 100644
--- a/.paket/Paket.Restore.targets
+++ b/.paket/Paket.Restore.targets
@@ -11,23 +11,49 @@
$(MSBuildThisFileDirectory)..\
$(PaketRootPath)paket-files\paket.restore.cached
$(PaketRootPath)paket.lock
+ classic
+ proj
+ assembly
+ native
/Library/Frameworks/Mono.framework/Commands/mono
mono
-
- $(PaketRootPath)paket.exe
- $(PaketToolsPath)paket.exe
- "$(PaketExePath)"
- $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)"
-
+
+ $(PaketRootPath)paket.bootstrapper.exe
+ $(PaketToolsPath)paket.bootstrapper.exe
+ $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\
+
+
+
+
+ $(PaketRootPath)paket.exe
+ $(PaketToolsPath)paket.exe
+ $(PaketToolsPath)paket.exe
+ $(_PaketBootStrapperExeDir)paket.exe
+ paket.exe
+
+
+ $(PaketRootPath)paket
+ $(PaketToolsPath)paket
+ $(PaketToolsPath)paket
+
+
+ $(PaketRootPath)paket.exe
+ $(PaketToolsPath)paket.exe
+
+
+ $(PaketBootStrapperExeDir)paket.exe
+
+
+ paket
+
+
<_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)"))
- dotnet "$(PaketExePath)"
+ dotnet "$(PaketExePath)"
+ $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)"
+ "$(PaketExePath)"
-
- "$(PaketExePath)"
- $(PaketRootPath)paket.bootstrapper.exe
- $(PaketToolsPath)paket.bootstrapper.exe
"$(PaketBootStrapperExePath)"
$(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)"
@@ -36,9 +62,16 @@
true
true
+
+
+ True
-
+
+
+
+
+
@@ -72,12 +105,16 @@
true
-
+
+
true
-
+
@@ -141,16 +178,19 @@
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length)
$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0])
$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1])
$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4])
- $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5])
+ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5])
%(PaketReferencesFileLinesInfo.PackageVersion)
All
- runtime
+ runtime
+ runtime
true
+ true
@@ -182,19 +222,27 @@
false
+ $(MSBuildVersion)
+ 15.8.0
<_NuspecFilesNewLocation Include="$(BaseIntermediateOutputPath)$(Configuration)\*.nuspec"/>
+
+
$(MSBuildProjectDirectory)/$(MSBuildProjectFile)
true
- false
- true
+ false
+ true
+ false
+ true
+ false
+ true
$(BaseIntermediateOutputPath)$(Configuration)
$(BaseIntermediateOutputPath)
@@ -209,9 +257,52 @@
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \@\*
+ \*\@
+
+
+
+
+ \@\{
+ \}
+
+
+
+
+ \@\(
+ \)
+
+
+
+
+ @@
+
+
+
+ \@
+ \)|\<
+
+
+
+
+
+
+ .
+
+
+
+
+ @@
+
+
+
+ \@\*
+ \*\@
+
+
+ @
+
+
+ "
+ "
+
+
+
+
+
+
+
+ '
+ '
+
+
+
+
+
+
+
+ this
+ base
+
+
+
+ as
+ is
+ new
+ sizeof
+ typeof
+ stackalloc
+
+
+
+ true
+ false
+
+
+
+ else
+ if
+ switch
+ case
+ default
+ do
+ for
+ foreach
+ in
+ while
+ lock
+
+
+
+ break
+ continue
+ goto
+ return
+
+
+
+ yield
+ partial
+ global
+ where
+ select
+ group
+ by
+ into
+ from
+ ascending
+ descending
+ orderby
+ let
+ join
+ on
+ equals
+ var
+ dynamic
+
+
+
+ try
+ throw
+ catch
+ finally
+
+
+
+ checked
+ unchecked
+
+
+
+ fixed
+ unsafe
+
+
+
+ bool
+ byte
+ char
+ decimal
+ double
+ enum
+ float
+ int
+ long
+ sbyte
+ short
+ struct
+ uint
+ ushort
+ ulong
+
+
+
+ class
+ interface
+ delegate
+ object
+ string
+ void
+
+
+
+ explicit
+ implicit
+ operator
+
+
+
+ params
+ ref
+ out
+
+
+
+ abstract
+ const
+ event
+ extern
+ override
+ readonly
+ sealed
+ static
+ virtual
+ volatile
+
+
+
+ public
+ protected
+ private
+ internal
+
+
+
+ namespace
+ using
+
+
+
+ get
+ set
+ add
+ remove
+
+
+
+ null
+ value
+
+
+
+
+ \b
+ [\d\w_]+ # an identifier
+ (?=\s*\() # followed by (
+
+
+
+
+ \b0[xX][0-9a-fA-F]+ # hex number
+ |
+ ( \b\d+(\.[0-9]+)? #number with optional floating point
+ | \.[0-9]+ #or just starting with floating point
+ )
+ ([eE][+-]?[0-9]+)? # optional exponent
+
+
+
+ [?,.;()\[\]{}+\-/%*<>^+~!|&]+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/REAL.NET.sln b/REAL.NET.sln
index 73878130..44d7ace9 100644
--- a/REAL.NET.sln
+++ b/REAL.NET.sln
@@ -40,6 +40,9 @@ EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Repo", "src\Repo\Repo.fsproj", "{9E7065A4-BA5E-4752-84BF-54D5C00DB60C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "plugins", "plugins", "{F12CD406-E1CD-43B7-B4BC-E2991723C56E}"
+ ProjectSection(SolutionItems) = preProject
+ Highlighter.xshd = Highlighter.xshd
+ EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginManager", "src\PluginManager\PluginManager.csproj", "{8B9C8D76-65B3-4A01-9D6F-B6192A823642}"
EndProject
@@ -55,6 +58,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AirSim", "src\AirSim\AirSim
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfControlsLib.Tests", "tests\WpfControlsLib.Tests\WpfControlsLib.Tests.csproj", "{8EDF4429-251A-416D-BB68-93F227191BCF}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenerationRulesPlugin", "src\plugins\GenerationRulesPlugin\GenerationRulesPlugin.csproj", "{073FFD76-E332-4D14-B90E-08636940D330}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -193,6 +198,18 @@ Global
{8EDF4429-251A-416D-BB68-93F227191BCF}.Release|Any CPU.Build.0 = Release|Any CPU
{8EDF4429-251A-416D-BB68-93F227191BCF}.Release|x64.ActiveCfg = Release|Any CPU
{8EDF4429-251A-416D-BB68-93F227191BCF}.Release|x64.Build.0 = Release|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.Debug|x64.Build.0 = Debug|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.MonoRelease|Any CPU.ActiveCfg = Release|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.MonoRelease|Any CPU.Build.0 = Release|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.MonoRelease|x64.ActiveCfg = Release|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.MonoRelease|x64.Build.0 = Release|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.Release|Any CPU.Build.0 = Release|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.Release|x64.ActiveCfg = Release|Any CPU
+ {073FFD76-E332-4D14-B90E-08636940D330}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -204,6 +221,7 @@ Global
{A0056C25-4EF7-4AF9-99E4-C13B937A3343} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4}
{C57410A1-A86F-418B-9AC7-38249450C497} = {F12CD406-E1CD-43B7-B4BC-E2991723C56E}
{8EDF4429-251A-416D-BB68-93F227191BCF} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4}
+ {073FFD76-E332-4D14-B90E-08636940D330} = {F12CD406-E1CD-43B7-B4BC-E2991723C56E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D0B60BC3-B119-4CD6-8FC4-CD8FA1429BE4}
diff --git a/src/WpfEditor/View/MainWindow.xaml.cs b/src/WpfEditor/View/MainWindow.xaml.cs
index 81cf0f2f..40333e42 100644
--- a/src/WpfEditor/View/MainWindow.xaml.cs
+++ b/src/WpfEditor/View/MainWindow.xaml.cs
@@ -88,8 +88,8 @@ public MainWindow()
this.modelSelector.Init(this.model);
this.modelSelector.ChangeModel(2);
- this.InitAndLaunchPlugins();
this.InitToolbar();
+ this.InitAndLaunchPlugins();
}
private void Reinit(object sender, EventArgs e)
@@ -130,7 +130,7 @@ private void InitAndLaunchPlugins()
foreach (var plugindir in pluginDirs)
{
var dirs = new List(System.IO.Directory.GetDirectories(plugindir + "/bin"));
- var config = new PluginConfig(this.model, null, null, this.Console, null);
+ var config = new PluginConfig(this.model, null, this.Toolbar, this.Console, null);
foreach (var dir in dirs)
{
libs.LaunchPlugins(dir, config);
diff --git a/src/plugins/GenerationRulesPlugin/GenerationRulesPlugin.cs b/src/plugins/GenerationRulesPlugin/GenerationRulesPlugin.cs
new file mode 100644
index 00000000..152faa86
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/GenerationRulesPlugin.cs
@@ -0,0 +1,153 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using EditorPluginInterfaces.Toolbar;
+using GenerationRulesPlugin.plugins.GenerationRulesPlugin;
+using ICSharpCode.AvalonEdit.CodeCompletion;
+using RazorEngine;
+using RazorEngine.Templating;
+using Repo;
+
+namespace GenerationRulesPlugin
+{
+ using System;
+ using EditorPluginInterfaces;
+ using WpfControlsLib.Controls.Toolbar;
+
+ ///
+ ///
+ /// Represents model for Generation Rules Plugin.
+ ///
+ public class GenerationRulesPlugin : IPlugin
+ {
+ public string Name => "Generation Rules Plugin";
+
+ private GenerationRulesWindow window;
+
+ private IConsole console;
+ private IModel model;
+
+ public void SetConfig(PluginConfig config)
+ {
+ if (config == null)
+ {
+ throw new ArgumentException("This is not correct type of configuration");
+ }
+
+ this.console = config.Console;
+ this.console.SendMessage($"{this.Name} successfully launched");
+
+ this.model = config.Model;
+ IToolbar toolbar = config.Toolbar;
+
+ var command = new Command(() =>
+ {
+ this.window = new GenerationRulesWindow { Plugin = this };
+ this.window.Show();
+ });
+ var button = new Button(command, "Opens code generation rules editor", "redo.png");
+ toolbar.AddButton(button);
+ }
+
+ ///
+ /// Compiles template from input and returns the result.
+ ///
+ /// Input to compile from.
+ /// Compilation result.
+ public string CompileTemplate(string input)
+ {
+ input = "@using GenerationRulesPlugin\n" + input;
+ IRepo repo = this.model.Repo;
+ Repo.IModel currentModel = repo.Model("RobotsTestModel");
+ var regex = new Regex(@"@Model\.(?\w+)\.(?\w+)(?\W?)");
+ MatchCollection matches = regex.Matches(input);
+ string template = input;
+ foreach (Match match in matches)
+ {
+ string attribute = match.Groups["attribute"].Captures[0].Value;
+ string element = match.Groups["element"].Captures[0].Value;
+ Group lastCharacterMatchGroup = match.Groups["lastCharacter"];
+ string lastCharacter = lastCharacterMatchGroup.Success
+ ? lastCharacterMatchGroup.Captures[0].Value
+ : string.Empty;
+ // TODO Fix: match.Value is not valid pattern value (it has not escaped parentheses)
+ if (match.Value.Last() == ')')
+ {
+ template = Regex.Replace(template, match.Value.Substring(0, match.Value.Length - 1) + @"\)",
+ $"@Model.FindElement(\"{element}\").FindAttribute(\"{attribute}\").StringValue{lastCharacter}");
+ continue;
+ }
+
+ template = Regex.Replace(template, match.Value,
+ $"@Model.FindElement(\"{element}\").FindAttribute(\"{attribute}\").StringValue{lastCharacter}");
+ }
+
+ try
+ {
+ return Engine.Razor.RunCompile(template, $"key{new Random().Next()}", typeof(Repo.IModel),
+ currentModel).Trim();
+ }
+ catch (Exception e)
+ {
+ return $"[Compiling error]\n{e.Message}";
+ }
+ }
+
+ ///
+ /// Fills IList<ICompletionData> with proper elements or element attributes.
+ ///
+ /// List to fill.
+ /// Defines whether element or attribute data is needed.
+ /// Element name which attributes is needed.
+ public void GenerateCompletionList(IList data, bool isElement, string element = null)
+ {
+ if (isElement)
+ {
+ foreach (IElement el in this.model.Repo.Model("RobotsTestModel").Elements)
+ {
+ data.Add(new GenerationRulesCompletionData(el.Name));
+ }
+ }
+ else
+ {
+ try
+ {
+ foreach (IAttribute attribute in this.model.Repo.Model("RobotsTestModel").FindElement(element).Attributes)
+ {
+ data.Add(new GenerationRulesCompletionData(attribute.Name));
+ }
+ }
+ catch (MultipleElementsException)
+ {
+ data.Clear();
+ }
+ }
+
+ return;
+ }
+ }
+
+ ///
+ /// Represents auxiliary class which contains extension method to find attribute of element.
+ ///
+ public static class ElementExtension
+ {
+ ///
+ /// Finds attribute of the element.
+ ///
+ /// Element to find attribute of.
+ /// Name of the attribute.
+ /// Required attribute.
+ public static IAttribute FindAttribute(this IElement element, string attributeName)
+ {
+ foreach (IAttribute attribute in element.Attributes.Where(a => a.Name == attributeName))
+ {
+ return attribute;
+ }
+
+ throw new AttributeNotFoundException(attributeName);
+ }
+ }
+
+
+}
diff --git a/src/plugins/GenerationRulesPlugin/GenerationRulesPlugin.csproj b/src/plugins/GenerationRulesPlugin/GenerationRulesPlugin.csproj
new file mode 100644
index 00000000..06329406
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/GenerationRulesPlugin.csproj
@@ -0,0 +1,121 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {073FFD76-E332-4D14-B90E-08636940D330}
+ library
+ GenerationRulesPlugin
+ GenerationRulesPlugin
+ v4.7.2
+ 512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\..\..\packages\FSharp.Core.4.5.0\lib\net45\FSharp.Core.dll
+
+
+ ..\..\..\packages\AvalonEdit.5.0.4\lib\Net40\ICSharpCode.AvalonEdit.dll
+
+
+ ..\..\..\packages\RazorEngine.3.10.0\lib\net45\RazorEngine.dll
+
+
+
+
+ ..\..\..\packages\Microsoft.AspNet.Razor.3.0.0\lib\net45\System.Web.Razor.dll
+
+
+
+
+
+
+
+
+ 4.0
+
+
+
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+ GenerationRulesWindow.xaml
+
+
+
+
+ UserControl1.xaml
+ Code
+
+
+
+
+ Code
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ Settings.settings
+ True
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+ {6e5f1b5d-f165-4cec-a240-8887ebd28e3b}
+ EditorPluginInterfaces
+
+
+ {9e7065a4-ba5e-4752-84bf-54d5c00db60c}
+ Repo
+
+
+ {1dcb1d77-ab11-404c-bce4-8eb7bf8f549d}
+ WpfControlsLib
+
+
+
+
\ No newline at end of file
diff --git a/src/plugins/GenerationRulesPlugin/GenerationRulesWindow.xaml b/src/plugins/GenerationRulesPlugin/GenerationRulesWindow.xaml
new file mode 100644
index 00000000..2577a1d1
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/GenerationRulesWindow.xaml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/GenerationRulesPlugin/GenerationRulesWindow.xaml.cs b/src/plugins/GenerationRulesPlugin/GenerationRulesWindow.xaml.cs
new file mode 100644
index 00000000..84c2e05b
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/GenerationRulesWindow.xaml.cs
@@ -0,0 +1,11 @@
+namespace GenerationRulesPlugin
+{
+ using System.Windows;
+
+ ///
+ /// Interaction logic for GenerationRulesWindow.xaml
+ ///
+ public partial class GenerationRulesWindow : Window
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/plugins/GenerationRulesPlugin/Properties/AssemblyInfo.cs b/src/plugins/GenerationRulesPlugin/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..83292a62
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GenerationRulesPlugin")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GenerationRulesPlugin")]
+[assembly: AssemblyCopyright("Copyright © 2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+//In order to begin building localizable applications, set
+//CultureYouAreCodingWith in your .csproj file
+//inside a . For example, if you are using US english
+//in your source files, set the to en-US. Then uncomment
+//the NeutralResourceLanguage attribute below. Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/plugins/GenerationRulesPlugin/Properties/Resources.Designer.cs b/src/plugins/GenerationRulesPlugin/Properties/Resources.Designer.cs
new file mode 100644
index 00000000..5dbba0ba
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/Properties/Resources.Designer.cs
@@ -0,0 +1,62 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace GenerationRulesPlugin.Properties {
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if ((resourceMan == null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GenerationRulesPlugin.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/src/plugins/GenerationRulesPlugin/Properties/Resources.resx b/src/plugins/GenerationRulesPlugin/Properties/Resources.resx
new file mode 100644
index 00000000..af7dbebb
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/src/plugins/GenerationRulesPlugin/Properties/Settings.Designer.cs b/src/plugins/GenerationRulesPlugin/Properties/Settings.Designer.cs
new file mode 100644
index 00000000..2748611d
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace GenerationRulesPlugin.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/src/plugins/GenerationRulesPlugin/Properties/Settings.settings b/src/plugins/GenerationRulesPlugin/Properties/Settings.settings
new file mode 100644
index 00000000..033d7a5e
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/plugins/GenerationRulesPlugin/UserControl1.xaml b/src/plugins/GenerationRulesPlugin/UserControl1.xaml
new file mode 100644
index 00000000..b2fc7cc0
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/UserControl1.xaml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/src/plugins/GenerationRulesPlugin/UserControl1.xaml.cs b/src/plugins/GenerationRulesPlugin/UserControl1.xaml.cs
new file mode 100644
index 00000000..fcc1a0f8
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/UserControl1.xaml.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace GenerationRulesPlugin
+{
+ ///
+ /// Interaction logic for UserControl1.xaml
+ ///
+ public partial class UserControl1 : UserControl
+ {
+ public UserControl1()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/src/plugins/GenerationRulesPlugin/packages.config b/src/plugins/GenerationRulesPlugin/packages.config
new file mode 100644
index 00000000..1023f919
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/packages.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/plugins/GenerationRulesPlugin/plugins/GenerationRulesPlugin/GenerationRulesCompletionData.cs b/src/plugins/GenerationRulesPlugin/plugins/GenerationRulesPlugin/GenerationRulesCompletionData.cs
new file mode 100644
index 00000000..a3b99726
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/plugins/GenerationRulesPlugin/GenerationRulesCompletionData.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Windows.Media;
+using ICSharpCode.AvalonEdit.CodeCompletion;
+using ICSharpCode.AvalonEdit.Document;
+using ICSharpCode.AvalonEdit.Editing;
+
+namespace GenerationRulesPlugin.plugins.GenerationRulesPlugin
+{
+ ///
+ /// Describes an entry in the specified for Generation Rules Plugin.
+ ///
+ ///
+ internal class GenerationRulesCompletionData : ICompletionData
+ {
+ public GenerationRulesCompletionData(string text)
+ {
+ this.Text = text;
+ }
+
+
+ public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs)
+ {
+ if (completionSegment.Offset == completionSegment.EndOffset)
+ {
+ textArea.Document.Insert(completionSegment.Offset, this.Text);
+ }
+ else
+ {
+ textArea.Document.Replace(completionSegment, this.Text);
+ }
+ }
+
+ public ImageSource Image { get; }
+ public string Text { get; }
+ public object Content => this.Text;
+
+ public object Description => "Model property" + this.Text;
+
+ public double Priority { get; }
+ }
+}
diff --git a/src/plugins/GenerationRulesPlugin/plugins/GenerationRulesPlugin/GenerationRulesWindow.cs b/src/plugins/GenerationRulesPlugin/plugins/GenerationRulesPlugin/GenerationRulesWindow.cs
new file mode 100644
index 00000000..e5d34500
--- /dev/null
+++ b/src/plugins/GenerationRulesPlugin/plugins/GenerationRulesPlugin/GenerationRulesWindow.cs
@@ -0,0 +1,145 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.Windows;
+using System.Windows.Input;
+using System.Xml;
+using GenerationRulesPlugin.plugins.GenerationRulesPlugin;
+using ICSharpCode.AvalonEdit.CodeCompletion;
+using ICSharpCode.AvalonEdit.Document;
+using ICSharpCode.AvalonEdit.Highlighting;
+using ICSharpCode.AvalonEdit.Highlighting.Xshd;
+using Microsoft.Win32;
+
+namespace GenerationRulesPlugin
+{
+ ///
+ /// Represents Window for Generations Rules Plugin.
+ ///
+ public partial class GenerationRulesWindow
+ {
+ ///
+ /// Window's plugin
+ ///
+ public GenerationRulesPlugin Plugin { get; set; }
+
+ private CompletionWindow completionWindow;
+
+ public GenerationRulesWindow()
+ {
+ this.InitializeComponent();
+ using (var stream = new FileStream(@"..\..\..\..\Highlighter.xshd", FileMode.Open))
+ {
+ try
+ {
+ this.CodeEditor.SyntaxHighlighting =
+ HighlightingLoader.Load(HighlightingLoader.LoadXshd(new XmlTextReader(stream)),
+ HighlightingManager.Instance);
+ }
+ catch (HighlightingDefinitionInvalidException e)
+ {
+ this.CodeEditor.Text = $"[Invalid Syntax Highlighting Definition]\n{e.Message}";
+ }
+ }
+
+ this.CodeEditor.TextArea.TextEntering += TextEntering;
+ this.CodeEditor.TextArea.TextEntered += TextEntered;
+ }
+
+ private void OnSaveClick(object sender, RoutedEventArgs e)
+ {
+ var saveFileDialog = new SaveFileDialog();
+ if (saveFileDialog.ShowDialog() != true)
+ {
+ return;
+ }
+
+ string filename = saveFileDialog.FileName;
+ File.WriteAllText(filename, this.CodeEditor.Text);
+ MessageBox.Show("File Saved");
+ }
+
+ private void OnSaveGeneratedCodeClick(object sender, RoutedEventArgs e)
+ {
+ var saveFileDialog = new SaveFileDialog();
+ if (saveFileDialog.ShowDialog() != true)
+ {
+ return;
+ }
+
+ string filename = saveFileDialog.FileName;
+ File.WriteAllText(filename, this.ResultBox.Text);
+ MessageBox.Show("File Saved");
+ }
+
+ private void OnGenerateCodeClick(object sender, RoutedEventArgs e)
+ {
+ string result = this.Plugin.CompileTemplate(this.CodeEditor.Text);
+ this.ResultBox.Text = result;
+ }
+
+ private void TextEntered(object sender, TextCompositionEventArgs e)
+ {
+ if (e.Text == "@")
+ {
+ completionWindow = new CompletionWindow(this.CodeEditor.TextArea);
+ IList data = completionWindow.CompletionList.CompletionData;
+ data.Add(new GenerationRulesCompletionData("Model"));
+ data.Add(new GenerationRulesCompletionData("for"));
+ data.Add(new GenerationRulesCompletionData("if"));
+ data.Add(new GenerationRulesCompletionData("while"));
+ data.Add(new GenerationRulesCompletionData("Include"));
+ completionWindow.Show();
+ completionWindow.Closed += (o, args) => this.completionWindow = null;
+ }
+
+ if (e.Text == ".")
+ {
+ completionWindow = new CompletionWindow(this.CodeEditor.TextArea);
+ IList data = completionWindow.CompletionList.CompletionData;
+ DocumentLine line =
+ this.CodeEditor.TextArea.Document.GetLineByNumber(this.CodeEditor.TextArea.Caret.Line);
+ int lineCaretPosition = this.CodeEditor.TextArea.Caret.Offset - line.Offset;
+ MatchCollection matches = new Regex(@"@Model\.").Matches(this.CodeEditor.TextArea.Document.GetText(line));
+ foreach (Match match in matches)
+ {
+ if (match.Index + match.Length == lineCaretPosition)
+ {
+ Plugin.GenerateCompletionList(data, true, null);
+ }
+ }
+
+ if (data.Count != 0)
+ {
+ completionWindow.Show();
+ completionWindow.Closed += (o, args) => this.completionWindow = null;
+ return;
+ }
+
+ var regex = new Regex(@"@Model\.(?\w+)\.");
+ matches = regex.Matches(this.CodeEditor.TextArea.Document.GetText(line));
+ foreach (Match match in matches)
+ {
+ if (match.Index + match.Length == lineCaretPosition)
+ {
+ Plugin.GenerateCompletionList(data, false, match.Groups["element"].Captures[0].Value);
+ }
+ }
+
+ if (data.Count != 0)
+ {
+ completionWindow.Show();
+ completionWindow.Closed += (o, args) => this.completionWindow = null;
+ }
+ }
+ }
+
+ private void TextEntering(object sender, TextCompositionEventArgs e)
+ {
+ if (!char.IsLetterOrDigit(e.Text[0]))
+ {
+ completionWindow?.CompletionList.RequestInsertion(e);
+ }
+ }
+ }
+}
\ No newline at end of file