diff --git a/Installer/DevenvSetupCustomAction/DevenvSetup.Designer.cs b/Installer/DevenvSetupCustomAction/DevenvSetup.Designer.cs new file mode 100644 index 000000000..2a780bb8e --- /dev/null +++ b/Installer/DevenvSetupCustomAction/DevenvSetup.Designer.cs @@ -0,0 +1,36 @@ +namespace DevenvSetupCustomAction +{ + partial class DevenvSetup + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} \ No newline at end of file diff --git a/Installer/DevenvSetupCustomAction/DevenvSetup.cs b/Installer/DevenvSetupCustomAction/DevenvSetup.cs new file mode 100644 index 000000000..9359927da --- /dev/null +++ b/Installer/DevenvSetupCustomAction/DevenvSetup.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Configuration.Install; +using System.Diagnostics; +using System.Linq; +using System.Windows.Forms; +using Microsoft.Win32; + + +namespace DevenvSetupCustomAction +{ + [RunInstaller(true)] + public partial class DevenvSetup : Installer + { + public DevenvSetup() + { + InitializeComponent(); + } + + public override void Install(IDictionary stateSaver) + { + base.Install(stateSaver); + + try + { + + using (RegistryKey setupKey = Registry.LocalMachine.OpenSubKey( + @"SOFTWARE\Microsoft\VisualStudio\9.0\Setup\VS")) + { + if (setupKey != null) + { + string devenv = setupKey.GetValue("EnvironmentPath").ToString(); + if (!string.IsNullOrEmpty(devenv)) + { + Process process = new Process(); + process.StartInfo.FileName = Environment.ExpandEnvironmentVariables(devenv); + //process.StartInfo.Arguments = "/setup"; + process.StartInfo.Arguments = "/installvstemplates"; + process.Start(); + + process.WaitForExit(); + } + } + } + } + catch (Exception ex) + { + MessageBox.Show("Unable to execute 'devenv /setup'. Please perform this action manually." + + Environment.NewLine + ex.Message, "Installer Error", MessageBoxButtons.OK, + MessageBoxIcon.Warning); + } + + } + } +} diff --git a/Installer/DevenvSetupCustomAction/DevenvSetupCustomAction.csproj b/Installer/DevenvSetupCustomAction/DevenvSetupCustomAction.csproj new file mode 100644 index 000000000..58a1787a9 --- /dev/null +++ b/Installer/DevenvSetupCustomAction/DevenvSetupCustomAction.csproj @@ -0,0 +1,71 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {02F3B86D-0421-4D45-A701-44F3C94CF07D} + Library + Properties + DevenvSetupCustomAction + DevenvSetupCustomAction + v3.5 + 512 + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + 3.5 + + + + + 3.5 + + + 3.5 + + + + + + + Component + + + DevenvSetup.cs + + + + + + \ No newline at end of file diff --git a/Installer/DevenvSetupCustomAction/DevenvSetupCustomAction.csproj.vspscc b/Installer/DevenvSetupCustomAction/DevenvSetupCustomAction.csproj.vspscc new file mode 100644 index 000000000..b6d32892f --- /dev/null +++ b/Installer/DevenvSetupCustomAction/DevenvSetupCustomAction.csproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/Installer/DevenvSetupCustomAction/Properties/AssemblyInfo.cs b/Installer/DevenvSetupCustomAction/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..52d645075 --- /dev/null +++ b/Installer/DevenvSetupCustomAction/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 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("DevenvSetupCustomAction")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DevenvSetupCustomAction")] +[assembly: AssemblyCopyright("Copyright © 2009")] +[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)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("46be5ea5-e3f1-400f-b6c0-eaf5b7b4d9c4")] + +// 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/Installer/DevenvSetupCustomAction/bin/Debug/DevenvSetupCustomAction.dll b/Installer/DevenvSetupCustomAction/bin/Debug/DevenvSetupCustomAction.dll new file mode 100644 index 000000000..0ccdde4d5 Binary files /dev/null and b/Installer/DevenvSetupCustomAction/bin/Debug/DevenvSetupCustomAction.dll differ diff --git a/Installer/DevenvSetupCustomAction/bin/Debug/DevenvSetupCustomAction.pdb b/Installer/DevenvSetupCustomAction/bin/Debug/DevenvSetupCustomAction.pdb new file mode 100644 index 000000000..6d0e5de07 Binary files /dev/null and b/Installer/DevenvSetupCustomAction/bin/Debug/DevenvSetupCustomAction.pdb differ diff --git a/Installer/DevenvSetupCustomAction/obj/Debug/DevenvSetupCustomAction.csproj.FileListAbsolute.txt b/Installer/DevenvSetupCustomAction/obj/Debug/DevenvSetupCustomAction.csproj.FileListAbsolute.txt new file mode 100644 index 000000000..9aa5b2a38 --- /dev/null +++ b/Installer/DevenvSetupCustomAction/obj/Debug/DevenvSetupCustomAction.csproj.FileListAbsolute.txt @@ -0,0 +1,5 @@ +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Installer\DevenvSetupCustomAction\bin\Debug\DevenvSetupCustomAction.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Installer\DevenvSetupCustomAction\bin\Debug\DevenvSetupCustomAction.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Installer\DevenvSetupCustomAction\obj\Debug\ResolveAssemblyReference.cache +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Installer\DevenvSetupCustomAction\obj\Debug\DevenvSetupCustomAction.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Installer\DevenvSetupCustomAction\obj\Debug\DevenvSetupCustomAction.pdb diff --git a/Installer/DevenvSetupCustomAction/obj/Debug/DevenvSetupCustomAction.dll b/Installer/DevenvSetupCustomAction/obj/Debug/DevenvSetupCustomAction.dll new file mode 100644 index 000000000..0ccdde4d5 Binary files /dev/null and b/Installer/DevenvSetupCustomAction/obj/Debug/DevenvSetupCustomAction.dll differ diff --git a/Installer/DevenvSetupCustomAction/obj/Debug/DevenvSetupCustomAction.pdb b/Installer/DevenvSetupCustomAction/obj/Debug/DevenvSetupCustomAction.pdb new file mode 100644 index 000000000..6d0e5de07 Binary files /dev/null and b/Installer/DevenvSetupCustomAction/obj/Debug/DevenvSetupCustomAction.pdb differ diff --git a/Installer/SpecFlowSetup/Debug/SpecFlowSetup.msi b/Installer/SpecFlowSetup/Debug/SpecFlowSetup.msi new file mode 100644 index 000000000..0c5b6e861 Binary files /dev/null and b/Installer/SpecFlowSetup/Debug/SpecFlowSetup.msi differ diff --git a/Installer/SpecFlowSetup/Debug/setup.exe b/Installer/SpecFlowSetup/Debug/setup.exe new file mode 100644 index 000000000..80c027a26 Binary files /dev/null and b/Installer/SpecFlowSetup/Debug/setup.exe differ diff --git a/Installer/SpecFlowSetup/SpecFlowSetup.vdproj b/Installer/SpecFlowSetup/SpecFlowSetup.vdproj new file mode 100644 index 000000000..d73ca3f33 --- /dev/null +++ b/Installer/SpecFlowSetup/SpecFlowSetup.vdproj @@ -0,0 +1,2660 @@ +"DeployProject" +{ +"VSVersion" = "3:800" +"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:SpecFlowSetup" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:SAK" +"SccLocalPath" = "8:SAK" +"SccAuxPath" = "8:SAK" +"SccProvider" = "8:SAK" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_019055E8025F50104F4EDCD40D23AB47" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_01EB354B0A90719FCE0DB9F521F23AAA" + "OwnerKey" = "8:_6E18F9AB5609CE08526FEBCCD51B43B2" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_03554302F0E10421A56C1EB024AB937C" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0C0AEB379A994D6380D2AF032EA60E7A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0EFD25C2961F3370383FEDE414DD7238" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_0EFD25C2961F3370383FEDE414DD7238" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1AD5B2DAD15CADF7525F6B4F9791283D" + "OwnerKey" = "8:_76A50A8C2366870C6FF9029C08057BC1" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1AD5B2DAD15CADF7525F6B4F9791283D" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1AD5B2DAD15CADF7525F6B4F9791283D" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1AD5B2DAD15CADF7525F6B4F9791283D" + "OwnerKey" = "8:_76FE53DB004302324A1E0E189ECFF22B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1AD5B2DAD15CADF7525F6B4F9791283D" + "OwnerKey" = "8:_84C757C079461F1C50F74EF2AE7B70B7" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1AD5B2DAD15CADF7525F6B4F9791283D" + "OwnerKey" = "8:_CDB5EF528F7640FEF9EE58B3A2D014B2" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_1AD5B2DAD15CADF7525F6B4F9791283D" + "OwnerKey" = "8:_DDB8AF16D8DBB0CE47C567DBC0C19EE8" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2EB9CD8CC0B58F8EF675A33D260D3FCE" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2EB9CD8CC0B58F8EF675A33D260D3FCE" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2EB9CD8CC0B58F8EF675A33D260D3FCE" + "OwnerKey" = "8:_84C757C079461F1C50F74EF2AE7B70B7" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2EB9CD8CC0B58F8EF675A33D260D3FCE" + "OwnerKey" = "8:_DDB8AF16D8DBB0CE47C567DBC0C19EE8" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2EB9CD8CC0B58F8EF675A33D260D3FCE" + "OwnerKey" = "8:_1AD5B2DAD15CADF7525F6B4F9791283D" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2EB9CD8CC0B58F8EF675A33D260D3FCE" + "OwnerKey" = "8:_76A50A8C2366870C6FF9029C08057BC1" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2EB9CD8CC0B58F8EF675A33D260D3FCE" + "OwnerKey" = "8:_CDB5EF528F7640FEF9EE58B3A2D014B2" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_2EB9CD8CC0B58F8EF675A33D260D3FCE" + "OwnerKey" = "8:_76FE53DB004302324A1E0E189ECFF22B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_3E249700CAD3855C654723A8664E0F0F" + "OwnerKey" = "8:_65BCD078F68F9A3A16106B29194C0B30" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5200717186B38682CC469E61FA770589" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5200717186B38682CC469E61FA770589" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5200717186B38682CC469E61FA770589" + "OwnerKey" = "8:_868F4FD1F4C0AB914DA21D1E95D4EED7" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5200717186B38682CC469E61FA770589" + "OwnerKey" = "8:_D5DE8FFC7C8DF908C525F0D8C61D6537" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5B1AFC4F8443CD366D441E91E926E3F1" + "OwnerKey" = "8:_868F4FD1F4C0AB914DA21D1E95D4EED7" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_65BCD078F68F9A3A16106B29194C0B30" + "OwnerKey" = "8:_6E18F9AB5609CE08526FEBCCD51B43B2" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_65BCD078F68F9A3A16106B29194C0B30" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_65BCD078F68F9A3A16106B29194C0B30" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_65BCD078F68F9A3A16106B29194C0B30" + "OwnerKey" = "8:_76FE53DB004302324A1E0E189ECFF22B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6E18F9AB5609CE08526FEBCCD51B43B2" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_6E18F9AB5609CE08526FEBCCD51B43B2" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7509BA1E21425A74E057338BF4CF0A72" + "OwnerKey" = "8:_0C0AEB379A994D6380D2AF032EA60E7A" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_76A50A8C2366870C6FF9029C08057BC1" + "OwnerKey" = "8:_CDB5EF528F7640FEF9EE58B3A2D014B2" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_76A50A8C2366870C6FF9029C08057BC1" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_76A50A8C2366870C6FF9029C08057BC1" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_76A50A8C2366870C6FF9029C08057BC1" + "OwnerKey" = "8:_76FE53DB004302324A1E0E189ECFF22B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_76A50A8C2366870C6FF9029C08057BC1" + "OwnerKey" = "8:_84C757C079461F1C50F74EF2AE7B70B7" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_76A50A8C2366870C6FF9029C08057BC1" + "OwnerKey" = "8:_DDB8AF16D8DBB0CE47C567DBC0C19EE8" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_76FE53DB004302324A1E0E189ECFF22B" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_76FE53DB004302324A1E0E189ECFF22B" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_84C757C079461F1C50F74EF2AE7B70B7" + "OwnerKey" = "8:_76FE53DB004302324A1E0E189ECFF22B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_84C757C079461F1C50F74EF2AE7B70B7" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_868F4FD1F4C0AB914DA21D1E95D4EED7" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_887B7AF445E3CB62E718707DB1A2DB74" + "OwnerKey" = "8:_0C0AEB379A994D6380D2AF032EA60E7A" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_887B7AF445E3CB62E718707DB1A2DB74" + "OwnerKey" = "8:_F40F425B3B5D4365A81330EA775FCC1B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_887B7AF445E3CB62E718707DB1A2DB74" + "OwnerKey" = "8:_03554302F0E10421A56C1EB024AB937C" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_887B7AF445E3CB62E718707DB1A2DB74" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_887B7AF445E3CB62E718707DB1A2DB74" + "OwnerKey" = "8:_ED3D10E989AADCAA0A7443322308EE1F" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_887B7AF445E3CB62E718707DB1A2DB74" + "OwnerKey" = "8:_ABD5677C265A4D7BC34829F543181C87" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8C9C7FF1DB4641FF874CFFD3CFF10E62" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_ABD5677C265A4D7BC34829F543181C87" + "OwnerKey" = "8:_0C0AEB379A994D6380D2AF032EA60E7A" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_ABD5677C265A4D7BC34829F543181C87" + "OwnerKey" = "8:_F40F425B3B5D4365A81330EA775FCC1B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_AD591DC54D4D279D30A20BC80D4F8AE8" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_AD591DC54D4D279D30A20BC80D4F8AE8" + "OwnerKey" = "8:_DDB8AF16D8DBB0CE47C567DBC0C19EE8" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B090EC1C6CEB405EB055B415CD5F43DD" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_BBBD29910145A3B6E935E8D02FEDA996" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_BBBD29910145A3B6E935E8D02FEDA996" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_CDB5EF528F7640FEF9EE58B3A2D014B2" + "OwnerKey" = "8:_76FE53DB004302324A1E0E189ECFF22B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_CDB5EF528F7640FEF9EE58B3A2D014B2" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_CDB5EF528F7640FEF9EE58B3A2D014B2" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_CDB5EF528F7640FEF9EE58B3A2D014B2" + "OwnerKey" = "8:_84C757C079461F1C50F74EF2AE7B70B7" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D3C51B67E3B5564BEA7AB170962FA29F" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D3C51B67E3B5564BEA7AB170962FA29F" + "OwnerKey" = "8:_76FE53DB004302324A1E0E189ECFF22B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D406CAF4268247A88286DA2188E91F52" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D5DE8FFC7C8DF908C525F0D8C61D6537" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D5DE8FFC7C8DF908C525F0D8C61D6537" + "OwnerKey" = "8:_868F4FD1F4C0AB914DA21D1E95D4EED7" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_DDB8AF16D8DBB0CE47C567DBC0C19EE8" + "OwnerKey" = "8:_CDB5EF528F7640FEF9EE58B3A2D014B2" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_DDB8AF16D8DBB0CE47C567DBC0C19EE8" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E6AD94D42A19F4BF70FED3A0358400E1" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E6AD94D42A19F4BF70FED3A0358400E1" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E6B0EFF78EACE77310B9DF29508F535B" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E6B0EFF78EACE77310B9DF29508F535B" + "OwnerKey" = "8:_03554302F0E10421A56C1EB024AB937C" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_ED3D10E989AADCAA0A7443322308EE1F" + "OwnerKey" = "8:_0C0AEB379A994D6380D2AF032EA60E7A" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_ED3D10E989AADCAA0A7443322308EE1F" + "OwnerKey" = "8:_F40F425B3B5D4365A81330EA775FCC1B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F3E0D5DBC95C9FCB609F519F665BCC92" + "OwnerKey" = "8:_5200717186B38682CC469E61FA770589" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_F40F425B3B5D4365A81330EA775FCC1B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_FCA7A8942BCF47809C58574D51DA4A7B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_AD591DC54D4D279D30A20BC80D4F8AE8" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_F40F425B3B5D4365A81330EA775FCC1B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_8B2D5366F6C941138FF83318D8C65C46" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_03554302F0E10421A56C1EB024AB937C" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_E6B0EFF78EACE77310B9DF29508F535B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_3062EBEC857307CE646864E951AD7CF4" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_E6AD94D42A19F4BF70FED3A0358400E1" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_76FE53DB004302324A1E0E189ECFF22B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_84C757C079461F1C50F74EF2AE7B70B7" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_CDB5EF528F7640FEF9EE58B3A2D014B2" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_DDB8AF16D8DBB0CE47C567DBC0C19EE8" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_76A50A8C2366870C6FF9029C08057BC1" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_1AD5B2DAD15CADF7525F6B4F9791283D" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_D3C51B67E3B5564BEA7AB170962FA29F" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_2EB9CD8CC0B58F8EF675A33D260D3FCE" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_BBBD29910145A3B6E935E8D02FEDA996" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_019055E8025F50104F4EDCD40D23AB47" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_868F4FD1F4C0AB914DA21D1E95D4EED7" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_D5DE8FFC7C8DF908C525F0D8C61D6537" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_5200717186B38682CC469E61FA770589" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_0EFD25C2961F3370383FEDE414DD7238" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_6E18F9AB5609CE08526FEBCCD51B43B2" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_65BCD078F68F9A3A16106B29194C0B30" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_0C0AEB379A994D6380D2AF032EA60E7A" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_7509BA1E21425A74E057338BF4CF0A72" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_ED3D10E989AADCAA0A7443322308EE1F" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_ABD5677C265A4D7BC34829F543181C87" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_887B7AF445E3CB62E718707DB1A2DB74" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\SpecFlowSetup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Net.Framework.3.5.SP1" + { + "Name" = "8:.NET Framework 3.5 SP1" + "ProductCode" = "8:Microsoft.Net.Framework.3.5.SP1" + } + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.3.1" + { + "Name" = "8:Windows Installer 3.1" + "ProductCode" = "8:Microsoft.Windows.Installer.3.1" + } + } + } + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\SpecFlowSetup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Net.Framework.3.5.SP1" + { + "Name" = "8:.NET Framework 3.5 SP1" + "ProductCode" = "8:Microsoft.Net.Framework.3.5.SP1" + } + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Windows.Installer.3.1" + { + "Name" = "8:Windows Installer 3.1" + "ProductCode" = "8:Microsoft.Windows.Installer.3.1" + } + } + } + } + } + "Deployable" + { + "CustomAction" + { + "{4AA51A2D-7D85-4A59-BA75-B0809FC8B380}:_8BE80C3D803648FFA919FA055AE54D1D" + { + "Name" = "8:Primary output from DevenvSetupCustomAction (Active)" + "Condition" = "8:" + "Object" = "8:_F40F425B3B5D4365A81330EA775FCC1B" + "FileType" = "3:1" + "InstallAction" = "3:1" + "Arguments" = "8:" + "EntryPoint" = "8:" + "Sequence" = "3:1" + "Identifier" = "8:_E247026D_04A7_4DCD_91D1_9E7CFC32EDE4" + "InstallerClass" = "11:TRUE" + "CustomActionData" = "8:" + } + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_8C8905E43EE54EA383E630F7E4D3F21B" + { + "Name" = "8:.NET Framework" + "Message" = "8:[VSDNETMSG]" + "Version" = "8:3.5.30729" + "AllowLaterVersions" = "11:FALSE" + "InstallUrl" = "8:http://go.microsoft.com/fwlink/?LinkId=76617" + } + } + } + "File" + { + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_019055E8025F50104F4EDCD40D23AB47" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.Designer.Interfaces, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_019055E8025F50104F4EDCD40D23AB47" + { + "Name" = "8:Microsoft.VisualStudio.Designer.Interfaces.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.Designer.Interfaces.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_01EB354B0A90719FCE0DB9F521F23AAA" + { + "SourcePath" = "8:dte80.olb" + "TargetName" = "8:dte80.olb" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_03554302F0E10421A56C1EB024AB937C" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:TechTalk.SpecFlow.Parser, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_03554302F0E10421A56C1EB024AB937C" + { + "Name" = "8:TechTalk.SpecFlow.Parser.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:TechTalk.SpecFlow.Parser.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_0EFD25C2961F3370383FEDE414DD7238" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.VSHelp, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_0EFD25C2961F3370383FEDE414DD7238" + { + "Name" = "8:Microsoft.VisualStudio.VSHelp.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.VSHelp.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_1AD5B2DAD15CADF7525F6B4F9791283D" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.TextManager.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_1AD5B2DAD15CADF7525F6B4F9791283D" + { + "Name" = "8:Microsoft.VisualStudio.TextManager.Interop.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.TextManager.Interop.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_2EB9CD8CC0B58F8EF675A33D260D3FCE" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.OLE.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_2EB9CD8CC0B58F8EF675A33D260D3FCE" + { + "Name" = "8:Microsoft.VisualStudio.OLE.Interop.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.OLE.Interop.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_3062EBEC857307CE646864E951AD7CF4" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.TextTemplating.VSHost, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_3062EBEC857307CE646864E951AD7CF4" + { + "Name" = "8:Microsoft.VisualStudio.TextTemplating.VSHost.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.TextTemplating.VSHost.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3E249700CAD3855C654723A8664E0F0F" + { + "SourcePath" = "8:dte80a.olb" + "TargetName" = "8:dte80a.olb" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_5200717186B38682CC469E61FA770589" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:VSLangProj, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_5200717186B38682CC469E61FA770589" + { + "Name" = "8:VSLangProj.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:VSLangProj.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5B1AFC4F8443CD366D441E91E926E3F1" + { + "SourcePath" = "8:vslangproj80.olb" + "TargetName" = "8:vslangproj80.olb" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_65BCD078F68F9A3A16106B29194C0B30" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_65BCD078F68F9A3A16106B29194C0B30" + { + "Name" = "8:EnvDTE.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:EnvDTE.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_6E18F9AB5609CE08526FEBCCD51B43B2" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:EnvDTE80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_6E18F9AB5609CE08526FEBCCD51B43B2" + { + "Name" = "8:EnvDTE80.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:EnvDTE80.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_7509BA1E21425A74E057338BF4CF0A72" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:nunit.framework, Version=2.5.1.9189, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_7509BA1E21425A74E057338BF4CF0A72" + { + "Name" = "8:nunit.framework.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:nunit.framework.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_76A50A8C2366870C6FF9029C08057BC1" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.Shell.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_76A50A8C2366870C6FF9029C08057BC1" + { + "Name" = "8:Microsoft.VisualStudio.Shell.Interop.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.Shell.Interop.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_76FE53DB004302324A1E0E189ECFF22B" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.Shell.9.0, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_76FE53DB004302324A1E0E189ECFF22B" + { + "Name" = "8:Microsoft.VisualStudio.Shell.9.0.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.Shell.9.0.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_84C757C079461F1C50F74EF2AE7B70B7" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.Shell.Interop.9.0, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_84C757C079461F1C50F74EF2AE7B70B7" + { + "Name" = "8:Microsoft.VisualStudio.Shell.Interop.9.0.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.Shell.Interop.9.0.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_868F4FD1F4C0AB914DA21D1E95D4EED7" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:VSLangProj80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_868F4FD1F4C0AB914DA21D1E95D4EED7" + { + "Name" = "8:VSLangProj80.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:VSLangProj80.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_887B7AF445E3CB62E718707DB1A2DB74" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_887B7AF445E3CB62E718707DB1A2DB74" + { + "Name" = "8:System.Core.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:System.Core.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8C9C7FF1DB4641FF874CFFD3CFF10E62" + { + "SourcePath" = "8:..\\..\\VsIntegration\\obj\\Debug\\SpecFlowEventDefinition.zip" + "TargetName" = "8:SpecFlowEventDefinition.zip" + "Tag" = "8:" + "Folder" = "8:_12420575FD334397AA439BFC984D6ADD" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_ABD5677C265A4D7BC34829F543181C87" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_ABD5677C265A4D7BC34829F543181C87" + { + "Name" = "8:System.Data.DataSetExtensions.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:System.Data.DataSetExtensions.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_AD591DC54D4D279D30A20BC80D4F8AE8" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:TRUE" + "AssemblyAsmDisplayName" = "8:Microsoft.MSXML, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_AD591DC54D4D279D30A20BC80D4F8AE8" + { + "Name" = "8:Microsoft.MSXML.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.MSXML.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B090EC1C6CEB405EB055B415CD5F43DD" + { + "SourcePath" = "8:..\\..\\changelog.txt" + "TargetName" = "8:changelog.txt" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_BBBD29910145A3B6E935E8D02FEDA996" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.Modeling.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_BBBD29910145A3B6E935E8D02FEDA996" + { + "Name" = "8:Microsoft.VisualStudio.Modeling.Sdk.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.Modeling.Sdk.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_CDB5EF528F7640FEF9EE58B3A2D014B2" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.Shell.Interop.8.0, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_CDB5EF528F7640FEF9EE58B3A2D014B2" + { + "Name" = "8:Microsoft.VisualStudio.Shell.Interop.8.0.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.Shell.Interop.8.0.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_D3C51B67E3B5564BEA7AB170962FA29F" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.ProjectAggregator, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_D3C51B67E3B5564BEA7AB170962FA29F" + { + "Name" = "8:Microsoft.VisualStudio.ProjectAggregator.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.ProjectAggregator.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D406CAF4268247A88286DA2188E91F52" + { + "SourcePath" = "8:..\\..\\VsIntegration\\obj\\Debug\\SpecFlowFeature.zip" + "TargetName" = "8:SpecFlowFeature.zip" + "Tag" = "8:" + "Folder" = "8:_12420575FD334397AA439BFC984D6ADD" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_D5DE8FFC7C8DF908C525F0D8C61D6537" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:VSLangProj2, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_D5DE8FFC7C8DF908C525F0D8C61D6537" + { + "Name" = "8:VSLangProj2.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:VSLangProj2.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_DDB8AF16D8DBB0CE47C567DBC0C19EE8" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.TextManager.Interop.8.0, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" + "ScatterAssemblies" + { + "_DDB8AF16D8DBB0CE47C567DBC0C19EE8" + { + "Name" = "8:Microsoft.VisualStudio.TextManager.Interop.8.0.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.TextManager.Interop.8.0.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_E6AD94D42A19F4BF70FED3A0358400E1" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Microsoft.VisualStudio.TextTemplating, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_E6AD94D42A19F4BF70FED3A0358400E1" + { + "Name" = "8:Microsoft.VisualStudio.TextTemplating.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Microsoft.VisualStudio.TextTemplating.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_E6B0EFF78EACE77310B9DF29508F535B" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Antlr3.Runtime, Version=3.1.2.41038, Culture=neutral, PublicKeyToken=3a9cab8f8d22bfb7, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_E6B0EFF78EACE77310B9DF29508F535B" + { + "Name" = "8:Antlr3.Runtime.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Antlr3.Runtime.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_ED3D10E989AADCAA0A7443322308EE1F" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_ED3D10E989AADCAA0A7443322308EE1F" + { + "Name" = "8:System.Xml.Linq.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:System.Xml.Linq.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F3E0D5DBC95C9FCB609F519F665BCC92" + { + "SourcePath" = "8:vslangproj.olb" + "TargetName" = "8:vslangproj.olb" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FCA7A8942BCF47809C58574D51DA4A7B" + { + "SourcePath" = "8:..\\..\\VsIntegration\\obj\\Debug\\SpecFlowStepDefinition.zip" + "TargetName" = "8:SpecFlowStepDefinition.zip" + "Tag" = "8:" + "Folder" = "8:_12420575FD334397AA439BFC984D6ADD" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + } + "FileType" + { + } + "Folder" + { + "{1525181F-901A-416C-8A58-119130FE478E}:_0D973C38FF244F3385C4A5443206BADC" + { + "Name" = "8:#1912" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramFilesFolder" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_D3CB3FD488E24EA28989947C5F21C83A" + { + "Name" = "8:Microsoft Visual Studio 9.0" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_B896852428AC4C6D97649F0BEDC23020" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_5BDFFF6F4CD04E4DACD1F9242FDE943B" + { + "Name" = "8:Common7" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_881FC7CE7CFA458C89FD776514498158" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_63AAC09E3F3142DCBBBB2B627C18C317" + { + "Name" = "8:IDE" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_B639E0D649354E7D8CA7E33426B80CAF" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_4C8481282A6F4892B1D597D2E9A70EC3" + { + "Name" = "8:ItemTemplates" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_F1064E5043444DCEA6D05B20743DF5F7" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_12420575FD334397AA439BFC984D6ADD" + { + "Name" = "8:CSharp" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_414375239DF94CE1AC2FB4AE722AE08D" + "Folders" + { + } + } + } + } + } + } + } + } + } + } + } + } + "{3C67513D-01DD-4637-8A68-80971EB9504F}:_2D85F2CCE0F64901A8231E38E3C0F2A8" + { + "DefaultLocation" = "8:[ProgramFilesFolder][Manufacturer]\\[ProductName]" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_256850BB5BF44587B0F43F11538A0DA3" + { + "Name" = "8:Setup" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_43B2C86145704B89A45FF1A6079494BB" + "Folders" + { + } + } + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_7245F19CBD31456A88C546138269A2C7" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_C27063BB52F74507B0D11312FC4CF5AD" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + "RequiresElevation" = "11:FALSE" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:SpecFlow" + "ProductCode" = "8:{D9982B5D-3364-407A-A4D2-896920EAA94E}" + "PackageCode" = "8:{93034CCE-E2B0-4CC1-9778-699C8722938B}" + "UpgradeCode" = "8:{A72428B6-8ADB-4EDF-BC23-4BE4E19F01A0}" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:TRUE" + "DetectNewerInstalledVersion" = "11:TRUE" + "InstallAllUsers" = "11:TRUE" + "ProductVersion" = "8:1.0.2" + "Manufacturer" = "8:TechTalk" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:" + "Title" = "8:SpecFlow Setup" + "Subject" = "8:" + "ARPCONTACT" = "8:TechTalk" + "Keywords" = "8:" + "ARPCOMMENTS" = "8:" + "ARPURLINFOABOUT" = "8:http://www.techtalk.at" + "ARPPRODUCTICON" = "8:" + "ARPIconIndex" = "3:0" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + "TargetPlatform" = "3:0" + "PreBuildEvent" = "8:" + "PostBuildEvent" = "8:" + "RunPostBuildEvent" = "3:0" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_363B9008780E4586AF4C3F5EF6FED156" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_3B6B0BD4FA844D4C8B27E8B848E9F1C4" + { + "Name" = "8:Microsoft" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_022539F5784D4832AEF49B04F7282A26" + { + "Name" = "8:VisualStudio" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_FCC39B3DE9814FA7B1A8EC55B09D2EEB" + { + "Name" = "8:9.0" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_631C1751839F4D379D73C9B99F19D7C6" + { + "Name" = "8:Generators" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_639FA0EC01D74BE4AFC951A9EE3D2A42" + { + "Name" = "8:{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_07C34ECC8B7F45A8867F521F0FEB7392" + { + "Name" = "8:SpecFlowSingleFileGenerator" + "Condition" = "8:" + "AlwaysCreate" = "11:TRUE" + "DeleteAtUninstall" = "11:TRUE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_9901238E48724728AAEC4DE8DC2682BF" + { + "Name" = "8:GeneratesDesignTimeSource" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "ValueTypes" = "3:3" + "Value" = "3:1" + } + "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_D3521D326FB54D4D8C1AACCE7AF96641" + { + "Name" = "8:" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "ValueTypes" = "3:1" + "Value" = "8:C# SpecFlow Generator" + } + "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_F2DEB7F18072428E9054176CBB7E8D03" + { + "Name" = "8:CLSID" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "ValueTypes" = "3:1" + "Value" = "8:{3c9cf10a-a9ab-4899-a0fb-4b3be4a36c15}" + } + } + } + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_65E72B6AAC754E2AB4FFBB20039101DF" + { + "Name" = "8:.feature" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_F85DCEABD60A4AEB8B868AD97E74664C" + { + "Name" = "8:" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "ValueTypes" = "3:1" + "Value" = "8:SpecFlowSingleFileGenerator" + } + } + } + } + "Values" + { + } + } + } + "Values" + { + } + } + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_EFC1365941CC4798B22FF6EC4B226FCA" + { + "Name" = "8:CLSID" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_BFE21C66F6A2445FA3867A968B1A7F15" + { + "Name" = "8:{3c9cf10a-a9ab-4899-a0fb-4b3be4a36c15}" + "Condition" = "8:" + "AlwaysCreate" = "11:TRUE" + "DeleteAtUninstall" = "11:TRUE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_1EC902AC326B4460B18B3E0B4050178E" + { + "Name" = "8:ThreadingModel" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "ValueTypes" = "3:1" + "Value" = "8:Both" + } + "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_366C5CE62F4844C28735863A68A28DEB" + { + "Name" = "8:" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "ValueTypes" = "3:1" + "Value" = "8:TechTalk.SpecFlow.VsIntegration.SpecFlowSingleFileGenerator" + } + "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_6CE2FEF912F54CD089CC3E3E31889CAC" + { + "Name" = "8:CodeBase" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "ValueTypes" = "3:1" + "Value" = "8:[TARGETDIR]TechTalk.SpecFlow.VsIntegration.dll" + } + "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_94726C38431249DF8384D23E8BA613B0" + { + "Name" = "8:Class" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "ValueTypes" = "3:1" + "Value" = "8:TechTalk.SpecFlow.VsIntegration.SpecFlowSingleFileGenerator" + } + "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_E2FD31A153DC4C318BD01E2B98955C9D" + { + "Name" = "8:InprocServer32" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "ValueTypes" = "3:1" + "Value" = "8:C:\\\\Windows\\\\SYSTEM32\\\\MSCOREE.DLL" + } + } + } + } + "Values" + { + } + } + } + "Values" + { + } + } + } + "Values" + { + } + } + } + "Values" + { + } + } + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_5F4F0D3B132B4FA68F74A3C4F3204168" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_736C73D4991041BB8C22A98B3A7C4DB0" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_68BD654DF7F74F2C939E877CAA7ABCC4" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + } + "UserInterface" + { + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_78EC5B9BD71848C8B9DE0BCCC562FE2D" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdBasicDialogs.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_8315B5B5D73441BBB1B60197F1306BAF" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_25CD641CE1D848FB9DAEFF3B853538E5" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_2FA24DF28AF440A69CDF2121CC7148B6" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_D899A8B8C71544C494C6A0E3C2A75285" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "InstallAllUsersVisible" + { + "Name" = "8:InstallAllUsersVisible" + "DisplayName" = "8:#1059" + "Description" = "8:#1159" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_885AA5D1FCE948E6BE10176036326C87" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdUserInterface.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_B5DD7A30A0204BD49EF92881466FBDEB" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_472056B25B0444FE853A199EB2863590" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_CD3FFD57F5CC4D4D80F56C89596D39EE" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_7CF40BED5E714A7A818E671FA0E43078" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_CFB112A450AD41559683D756D2C9F164" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_3FFFE72C40F443E89F88D67983940FBA" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_D9560655D69D414BB4A07027DC771D50" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_923CA499284D4B7CB9F7F50EFFE55B48" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_E6D2568384DB48DF92E7A614F789BB0C" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_6EC5FA4AB3B94FEBBB70BA6713536D87" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_861CB73AD432476EB2B105EF984B45B3" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_B5D432FD97D6486DA75CFE0E6DAE0101" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + } + "ProjectOutput" + { + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_0C0AEB379A994D6380D2AF032EA60E7A" + { + "SourcePath" = "8:..\\..\\Runtime\\obj\\Debug\\TechTalk.SpecFlow.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{413EE28C-4F89-4C6F-BA1E-2CDEE4CD43B4}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_8B2D5366F6C941138FF83318D8C65C46" + { + "SourcePath" = "8:..\\..\\VsIntegration\\obj\\Debug\\TechTalk.SpecFlow.VsIntegration.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_2D85F2CCE0F64901A8231E38E3C0F2A8" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{5703CA95-A08A-46AE-AE24-DB6B21FD6F7E}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_F40F425B3B5D4365A81330EA775FCC1B" + { + "SourcePath" = "8:..\\DevenvSetupCustomAction\\obj\\Debug\\DevenvSetupCustomAction.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_256850BB5BF44587B0F43F11538A0DA3" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{02F3B86D-0421-4D45-A701-44F3C94CF07D}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + } + } +} diff --git a/Installer/SpecFlowSetup/SpecFlowSetup.vdproj.vspscc b/Installer/SpecFlowSetup/SpecFlowSetup.vdproj.vspscc new file mode 100644 index 000000000..b6d32892f --- /dev/null +++ b/Installer/SpecFlowSetup/SpecFlowSetup.vdproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/Parser/Grammar/ErrorReporting.cs b/Parser/Grammar/ErrorReporting.cs new file mode 100644 index 000000000..e1ee2d970 --- /dev/null +++ b/Parser/Grammar/ErrorReporting.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace TechTalk.SpecFlow.Parser.Grammar +{ + partial class SpecFlowLangParser + { + public readonly List ParserErrors = new List(); + + public override void DisplayRecognitionError(string[] tokenNames, Antlr.Runtime.RecognitionException e) + { + this.EmitErrorMessage( + string.Format("({0},{1}): parser error: {2}", e.Line, e.CharPositionInLine, this.GetErrorMessage(e, tokenNames))); + } + + public override void EmitErrorMessage(string msg) + { + Debug.WriteLine(msg); + ParserErrors.Add(msg); + } + } + + partial class SpecFlowLangLexer + { + public readonly List LexerErrors = new List(); + + //public override void DisplayRecognitionError(string[] tokenNames, Antlr.Runtime.RecognitionException e) + //{ + // this.EmitErrorMessage( + // string.Format("({0},{1}): lexer error: {2}", e.Line, e.CharPositionInLine, this.GetErrorMessage(e, tokenNames))); + //} + + //public override void EmitErrorMessage(string msg) + //{ + // Debug.WriteLine(msg); + // //LexerErrors.Add(msg); + //} + } +} diff --git a/Parser/Grammar/SpecFlowLang.g b/Parser/Grammar/SpecFlowLang.g new file mode 100644 index 000000000..58ae9fc19 --- /dev/null +++ b/Parser/Grammar/SpecFlowLang.g @@ -0,0 +1,284 @@ +grammar SpecFlowLang; + +options { + language = CSharp2; + output = AST; + backtrack = true; +} + +tokens { + FEATURE; + DESCRIPTIONLINE; + BACKGROUND; + SCENARIOS; + SCENARIO; + SCENARIOOUTLINE; + EXAMPLES; + EXAMPLESET; + STEPS; + //GIVENS; + GIVEN; + //WHENS; + WHEN; + //THENS; + THEN; + TEXT; + AND; + BUT; + TAGS; + TAG; + WORD; + MULTILINETEXT; + INDENT; + LINE; + TABLE; + HEADER; + BODY; + ROW; + CELL; +} + +@lexer::namespace { TechTalk.SpecFlow.Parser.Grammar } +@namespace { TechTalk.SpecFlow.Parser.Grammar } + +feature + : newlineWithSpaces? + tags? + WS? 'Feature:' WS? text newlineWithSpaces + descriptionLine* + background? + scenarioKind* WS? EOF + -> ^(FEATURE tags? text descriptionLine* background? + ^(SCENARIOS scenarioKind*) + ) + ; + +tags + : WS? tag+ + -> ^(TAGS tag+) + ; + +tag + : AT word (newlineWithSpaces|WS) + -> ^(TAG word) + ; + +word + : WORDCHAR+ + -> ^(WORD WORDCHAR+) + ; + +descriptionLine + : WS? descriptionLineText newlineWithSpaces + -> ^(DESCRIPTIONLINE descriptionLineText) + ; + +background + : WS? T_BACKGROUND + (WS title)? + newlineWithSpaces givens + -> ^(BACKGROUND title? givens) + ; + +scenarioKind + : scenarioOutline + | scenario + ; + +scenario + : tags? WS? 'Scenario:' WS? + title newlineWithSpaces + steps + -> ^(SCENARIO tags? title steps) + ; + +scenarioOutline + : + tags? WS? 'Scenario Outline:' WS? + title newlineWithSpaces + steps + examples + -> ^(SCENARIOOUTLINE tags? title steps examples) + ; + +examples + : exampleSet+ + -> ^(EXAMPLES exampleSet+) + ; + +exampleSet + : WS? ('Examples:'|'Scenarios:') WS? + text? newlineWithSpaces table + -> ^(EXAMPLESET text? table) + ; + +steps + : firstStep nextStep* + -> ^(STEPS firstStep nextStep*) + ; +firstStep + : firstGiven -> firstGiven + | firstWhen -> firstWhen + | firstThen -> firstThen + ; +nextStep + : firstStep -> firstStep + | firstAnd -> firstAnd + | firstBut -> firstBut + ; + +firstAnd + : WS? 'And' WS sentenceEnd + -> ^(AND sentenceEnd) + ; + +firstBut + : WS? 'But' WS sentenceEnd + -> ^(BUT sentenceEnd) + ; + +givens + : firstGiven nextStep* + -> ^(STEPS firstGiven nextStep*) + ; +firstGiven + : WS? 'Given' WS sentenceEnd + -> ^(GIVEN sentenceEnd) + ; +/*nextGiven + : andSentence -> ^(GIVEN andSentence) + | firstGiven -> firstGiven + ; + +whens + : firstWhen nextWhen* + -> ^(WHENS firstWhen nextWhen*) + ;*/ +firstWhen + : WS? 'When' WS sentenceEnd + -> ^(WHEN sentenceEnd) + ; +/*nextWhen + : andSentence -> ^(WHEN andSentence) + | firstWhen -> firstWhen + ; + +thens + : firstThen nextThen* + -> ^(THENS firstThen nextThen*) + ;*/ +firstThen + : WS? 'Then' WS sentenceEnd + -> ^(THEN sentenceEnd) + ; +/*nextThen + : andSentence -> ^(THEN andSentence) + | butSentence -> ^(THEN butSentence) + | firstThen -> firstThen + ; + +andSentence + : WS? 'And' WS sentenceEnd + -> sentenceEnd + ; + +butSentence + : WS? 'But' WS sentenceEnd + -> sentenceEnd + ;*/ + +sentenceEnd + : text newlineWithSpaces multilineText? table? + -> text multilineText? table? + ; + +multilineText + : indent '"""' WS? NEWLINE + multilineTextLine* + WS? '"""' WS? newlineWithSpaces + -> ^(MULTILINETEXT multilineTextLine* indent) + ; + +indent + : WS? -> ^(INDENT WS?) + ; + +multilineTextLine + : WS? text? NEWLINE + -> ^(LINE WS? text? NEWLINE) + ; + +table + : tableRow tableRow+ + -> ^(TABLE ^(HEADER tableRow) ^(BODY tableRow+)) + ; + +tableRow + : WS? '|' tableCell+ WS? newlineWithSpaces + -> ^(ROW tableCell+) + ; + +tableCell + : WS? text WS? '|' + -> ^(CELL text) + ; + +descriptionLineText + : WORDCHAR textRest* + -> ^(TEXT WORDCHAR textRest*) + ; + +text + : wordchar textRest* + -> ^(TEXT wordchar textRest*) + ; +textRest + : WS textRest + | wordchar + ; + +title + : wordchar titleRest* + -> ^(TEXT wordchar titleRest*) + ; + +titleRest + : WS titleRest + | NEWLINE titleRest + | wordchar + ; + +titleRestLine + : NEWLINE titleRestLine + | WS titleRestLine + | WORDCHAR + ; + +wordchar + : WORDCHAR + | AT + ; + +newlineWithSpaces + : WS? NEWLINE (WS? NEWLINE)* + ; + +fragment WSCHAR : (' '|'\t'); +fragment NONWCHR : (' '|'\t'|'\r'|'\n'|'#'|'@'); +fragment NEWLINECHR : ('\r'|'\n'); +fragment NONNLCHR : ('\u0000'..'\t')|('\u000B'..'\f')|('\u000E'..'\uFFFF'); + + +T_BACKGROUND : 'Background:'; +AT : '@'; +/*COMMENT : WSCHAR* '#' (~NEWLINECHR)* { $channel = Token.HIDDEN_CHANNEL; };*/ +COMMENT : WSCHAR* '#' NONNLCHR* { $channel = Token.HIDDEN_CHANNEL; }; +WS : WSCHAR+; +NEWLINE : '\r\n' | '\n'; +/*WORDCHAR : ~NONWCHR; */ +WORDCHAR : (('\u0000'..'\b') + | ('\u000B'..'\f') + | ('\u000E'..'\u001F') + | ('!'..'"') + | ('$'..'?') + | ('A'..'\uFFFF'))+ ; diff --git a/Parser/Grammar/SpecFlowLangLexer.cs b/Parser/Grammar/SpecFlowLangLexer.cs new file mode 100644 index 000000000..024ce903d --- /dev/null +++ b/Parser/Grammar/SpecFlowLangLexer.cs @@ -0,0 +1,1420 @@ +// $ANTLR 3.1.2 SpecFlowLang.g 2009-10-16 10:52:12 + +// The variable 'variable' is assigned but its value is never used. +#pragma warning disable 168, 219 +// Unreachable code detected. +#pragma warning disable 162 +namespace TechTalk.SpecFlow.Parser.Grammar +{ + +using System; +using Antlr.Runtime; +using IList = System.Collections.IList; +using ArrayList = System.Collections.ArrayList; +using Stack = Antlr.Runtime.Collections.StackList; + + +public partial class SpecFlowLangLexer : Lexer { + public const int NEWLINECHR = 37; + public const int ROW = 28; + public const int T_BACKGROUND = 33; + public const int TABLE = 25; + public const int CELL = 29; + public const int DESCRIPTIONLINE = 5; + public const int AND = 17; + public const int EOF = -1; + public const int INDENT = 23; + public const int AT = 31; + public const int WORD = 21; + public const int T__51 = 51; + public const int BACKGROUND = 6; + public const int MULTILINETEXT = 22; + public const int THEN = 15; + public const int NONWCHR = 36; + public const int BODY = 27; + public const int GIVEN = 13; + public const int HEADER = 26; + public const int COMMENT = 39; + public const int SCENARIO = 8; + public const int T__50 = 50; + public const int T__42 = 42; + public const int T__43 = 43; + public const int T__40 = 40; + public const int T__41 = 41; + public const int T__46 = 46; + public const int T__47 = 47; + public const int T__44 = 44; + public const int T__45 = 45; + public const int EXAMPLESET = 11; + public const int T__48 = 48; + public const int T__49 = 49; + public const int BUT = 18; + public const int TAGS = 19; + public const int EXAMPLES = 10; + public const int WSCHAR = 35; + public const int TEXT = 16; + public const int NONNLCHR = 38; + public const int LINE = 24; + public const int FEATURE = 4; + public const int TAG = 20; + public const int SCENARIOS = 7; + public const int WORDCHAR = 32; + public const int WS = 30; + public const int NEWLINE = 34; + public const int SCENARIOOUTLINE = 9; + public const int WHEN = 14; + public const int STEPS = 12; + + // delegates + // delegators + + public SpecFlowLangLexer() + { + InitializeCyclicDFAs(); + } + public SpecFlowLangLexer(ICharStream input) + : this(input, null) { + } + public SpecFlowLangLexer(ICharStream input, RecognizerSharedState state) + : base(input, state) { + InitializeCyclicDFAs(); + + } + + override public string GrammarFileName + { + get { return "SpecFlowLang.g";} + } + + // $ANTLR start "T__40" + public void mT__40() // throws RecognitionException [2] + { + try + { + int _type = T__40; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:9:7: ( 'Feature:' ) + // SpecFlowLang.g:9:9: 'Feature:' + { + Match("Feature:"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__40" + + // $ANTLR start "T__41" + public void mT__41() // throws RecognitionException [2] + { + try + { + int _type = T__41; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:10:7: ( 'Scenario:' ) + // SpecFlowLang.g:10:9: 'Scenario:' + { + Match("Scenario:"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__41" + + // $ANTLR start "T__42" + public void mT__42() // throws RecognitionException [2] + { + try + { + int _type = T__42; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:11:7: ( 'Scenario Outline:' ) + // SpecFlowLang.g:11:9: 'Scenario Outline:' + { + Match("Scenario Outline:"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__42" + + // $ANTLR start "T__43" + public void mT__43() // throws RecognitionException [2] + { + try + { + int _type = T__43; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:12:7: ( 'Examples:' ) + // SpecFlowLang.g:12:9: 'Examples:' + { + Match("Examples:"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__43" + + // $ANTLR start "T__44" + public void mT__44() // throws RecognitionException [2] + { + try + { + int _type = T__44; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:13:7: ( 'Scenarios:' ) + // SpecFlowLang.g:13:9: 'Scenarios:' + { + Match("Scenarios:"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__44" + + // $ANTLR start "T__45" + public void mT__45() // throws RecognitionException [2] + { + try + { + int _type = T__45; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:14:7: ( 'And' ) + // SpecFlowLang.g:14:9: 'And' + { + Match("And"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__45" + + // $ANTLR start "T__46" + public void mT__46() // throws RecognitionException [2] + { + try + { + int _type = T__46; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:15:7: ( 'But' ) + // SpecFlowLang.g:15:9: 'But' + { + Match("But"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__46" + + // $ANTLR start "T__47" + public void mT__47() // throws RecognitionException [2] + { + try + { + int _type = T__47; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:16:7: ( 'Given' ) + // SpecFlowLang.g:16:9: 'Given' + { + Match("Given"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__47" + + // $ANTLR start "T__48" + public void mT__48() // throws RecognitionException [2] + { + try + { + int _type = T__48; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:17:7: ( 'When' ) + // SpecFlowLang.g:17:9: 'When' + { + Match("When"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__48" + + // $ANTLR start "T__49" + public void mT__49() // throws RecognitionException [2] + { + try + { + int _type = T__49; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:18:7: ( 'Then' ) + // SpecFlowLang.g:18:9: 'Then' + { + Match("Then"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__49" + + // $ANTLR start "T__50" + public void mT__50() // throws RecognitionException [2] + { + try + { + int _type = T__50; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:19:7: ( '\"\"\"' ) + // SpecFlowLang.g:19:9: '\"\"\"' + { + Match("\"\"\""); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__50" + + // $ANTLR start "T__51" + public void mT__51() // throws RecognitionException [2] + { + try + { + int _type = T__51; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:20:7: ( '|' ) + // SpecFlowLang.g:20:9: '|' + { + Match('|'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T__51" + + // $ANTLR start "WSCHAR" + public void mWSCHAR() // throws RecognitionException [2] + { + try + { + // SpecFlowLang.g:266:21: ( ( ' ' | '\\t' ) ) + // SpecFlowLang.g:266:23: ( ' ' | '\\t' ) + { + if ( input.LA(1) == '\t' || input.LA(1) == ' ' ) + { + input.Consume(); + + } + else + { + MismatchedSetException mse = new MismatchedSetException(null,input); + Recover(mse); + throw mse;} + + + } + + } + finally + { + } + } + // $ANTLR end "WSCHAR" + + // $ANTLR start "NONWCHR" + public void mNONWCHR() // throws RecognitionException [2] + { + try + { + // SpecFlowLang.g:267:21: ( ( ' ' | '\\t' | '\\r' | '\\n' | '#' | '@' ) ) + // SpecFlowLang.g:267:23: ( ' ' | '\\t' | '\\r' | '\\n' | '#' | '@' ) + { + if ( (input.LA(1) >= '\t' && input.LA(1) <= '\n') || input.LA(1) == '\r' || input.LA(1) == ' ' || input.LA(1) == '#' || input.LA(1) == '@' ) + { + input.Consume(); + + } + else + { + MismatchedSetException mse = new MismatchedSetException(null,input); + Recover(mse); + throw mse;} + + + } + + } + finally + { + } + } + // $ANTLR end "NONWCHR" + + // $ANTLR start "NEWLINECHR" + public void mNEWLINECHR() // throws RecognitionException [2] + { + try + { + // SpecFlowLang.g:268:21: ( ( '\\r' | '\\n' ) ) + // SpecFlowLang.g:268:23: ( '\\r' | '\\n' ) + { + if ( input.LA(1) == '\n' || input.LA(1) == '\r' ) + { + input.Consume(); + + } + else + { + MismatchedSetException mse = new MismatchedSetException(null,input); + Recover(mse); + throw mse;} + + + } + + } + finally + { + } + } + // $ANTLR end "NEWLINECHR" + + // $ANTLR start "NONNLCHR" + public void mNONNLCHR() // throws RecognitionException [2] + { + try + { + // SpecFlowLang.g:269:21: ( ( '\\u0000' .. '\\t' ) | ( '\\u000B' .. '\\f' ) | ( '\\u000E' .. '\\uFFFF' ) ) + int alt1 = 3; + int LA1_0 = input.LA(1); + + if ( ((LA1_0 >= '\u0000' && LA1_0 <= '\t')) ) + { + alt1 = 1; + } + else if ( ((LA1_0 >= '\u000B' && LA1_0 <= '\f')) ) + { + alt1 = 2; + } + else if ( ((LA1_0 >= '\u000E' && LA1_0 <= '\uFFFF')) ) + { + alt1 = 3; + } + else + { + NoViableAltException nvae_d1s0 = + new NoViableAltException("", 1, 0, input); + + throw nvae_d1s0; + } + switch (alt1) + { + case 1 : + // SpecFlowLang.g:269:23: ( '\\u0000' .. '\\t' ) + { + // SpecFlowLang.g:269:23: ( '\\u0000' .. '\\t' ) + // SpecFlowLang.g:269:24: '\\u0000' .. '\\t' + { + MatchRange('\u0000','\t'); + + } + + + } + break; + case 2 : + // SpecFlowLang.g:269:40: ( '\\u000B' .. '\\f' ) + { + // SpecFlowLang.g:269:40: ( '\\u000B' .. '\\f' ) + // SpecFlowLang.g:269:41: '\\u000B' .. '\\f' + { + MatchRange('\u000B','\f'); + + } + + + } + break; + case 3 : + // SpecFlowLang.g:269:57: ( '\\u000E' .. '\\uFFFF' ) + { + // SpecFlowLang.g:269:57: ( '\\u000E' .. '\\uFFFF' ) + // SpecFlowLang.g:269:58: '\\u000E' .. '\\uFFFF' + { + MatchRange('\u000E','\uFFFF'); + + } + + + } + break; + + } + } + finally + { + } + } + // $ANTLR end "NONNLCHR" + + // $ANTLR start "T_BACKGROUND" + public void mT_BACKGROUND() // throws RecognitionException [2] + { + try + { + int _type = T_BACKGROUND; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:272:14: ( 'Background:' ) + // SpecFlowLang.g:272:16: 'Background:' + { + Match("Background:"); + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "T_BACKGROUND" + + // $ANTLR start "AT" + public void mAT() // throws RecognitionException [2] + { + try + { + int _type = AT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:273:13: ( '@' ) + // SpecFlowLang.g:273:15: '@' + { + Match('@'); + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "AT" + + // $ANTLR start "COMMENT" + public void mCOMMENT() // throws RecognitionException [2] + { + try + { + int _type = COMMENT; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:275:13: ( ( WSCHAR )* '#' ( NONNLCHR )* ) + // SpecFlowLang.g:275:15: ( WSCHAR )* '#' ( NONNLCHR )* + { + // SpecFlowLang.g:275:15: ( WSCHAR )* + do + { + int alt2 = 2; + int LA2_0 = input.LA(1); + + if ( (LA2_0 == '\t' || LA2_0 == ' ') ) + { + alt2 = 1; + } + + + switch (alt2) + { + case 1 : + // SpecFlowLang.g:275:15: WSCHAR + { + mWSCHAR(); + + } + break; + + default: + goto loop2; + } + } while (true); + + loop2: + ; // Stops C# compiler whining that label 'loop2' has no statements + + Match('#'); + // SpecFlowLang.g:275:27: ( NONNLCHR )* + do + { + int alt3 = 2; + int LA3_0 = input.LA(1); + + if ( ((LA3_0 >= '\u0000' && LA3_0 <= '\t') || (LA3_0 >= '\u000B' && LA3_0 <= '\f') || (LA3_0 >= '\u000E' && LA3_0 <= '\uFFFF')) ) + { + alt3 = 1; + } + + + switch (alt3) + { + case 1 : + // SpecFlowLang.g:275:27: NONNLCHR + { + mNONNLCHR(); + + } + break; + + default: + goto loop3; + } + } while (true); + + loop3: + ; // Stops C# compiler whining that label 'loop3' has no statements + + _channel = Token.HIDDEN_CHANNEL; + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "COMMENT" + + // $ANTLR start "WS" + public void mWS() // throws RecognitionException [2] + { + try + { + int _type = WS; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:276:13: ( ( WSCHAR )+ ) + // SpecFlowLang.g:276:15: ( WSCHAR )+ + { + // SpecFlowLang.g:276:15: ( WSCHAR )+ + int cnt4 = 0; + do + { + int alt4 = 2; + int LA4_0 = input.LA(1); + + if ( (LA4_0 == '\t' || LA4_0 == ' ') ) + { + alt4 = 1; + } + + + switch (alt4) + { + case 1 : + // SpecFlowLang.g:276:15: WSCHAR + { + mWSCHAR(); + + } + break; + + default: + if ( cnt4 >= 1 ) goto loop4; + EarlyExitException eee4 = + new EarlyExitException(4, input); + throw eee4; + } + cnt4++; + } while (true); + + loop4: + ; // Stops C# compiler whinging that label 'loop4' has no statements + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "WS" + + // $ANTLR start "NEWLINE" + public void mNEWLINE() // throws RecognitionException [2] + { + try + { + int _type = NEWLINE; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:277:13: ( '\\r\\n' | '\\n' ) + int alt5 = 2; + int LA5_0 = input.LA(1); + + if ( (LA5_0 == '\r') ) + { + alt5 = 1; + } + else if ( (LA5_0 == '\n') ) + { + alt5 = 2; + } + else + { + NoViableAltException nvae_d5s0 = + new NoViableAltException("", 5, 0, input); + + throw nvae_d5s0; + } + switch (alt5) + { + case 1 : + // SpecFlowLang.g:277:15: '\\r\\n' + { + Match("\r\n"); + + + } + break; + case 2 : + // SpecFlowLang.g:277:24: '\\n' + { + Match('\n'); + + } + break; + + } + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "NEWLINE" + + // $ANTLR start "WORDCHAR" + public void mWORDCHAR() // throws RecognitionException [2] + { + try + { + int _type = WORDCHAR; + int _channel = DEFAULT_TOKEN_CHANNEL; + // SpecFlowLang.g:279:13: ( ( ( '\\u0000' .. '\\b' ) | ( '\\u000B' .. '\\f' ) | ( '\\u000E' .. '\\u001F' ) | ( '!' .. '\"' ) | ( '$' .. '?' ) | ( 'A' .. '\\uFFFF' ) )+ ) + // SpecFlowLang.g:279:15: ( ( '\\u0000' .. '\\b' ) | ( '\\u000B' .. '\\f' ) | ( '\\u000E' .. '\\u001F' ) | ( '!' .. '\"' ) | ( '$' .. '?' ) | ( 'A' .. '\\uFFFF' ) )+ + { + // SpecFlowLang.g:279:15: ( ( '\\u0000' .. '\\b' ) | ( '\\u000B' .. '\\f' ) | ( '\\u000E' .. '\\u001F' ) | ( '!' .. '\"' ) | ( '$' .. '?' ) | ( 'A' .. '\\uFFFF' ) )+ + int cnt6 = 0; + do + { + int alt6 = 7; + int LA6_0 = input.LA(1); + + if ( ((LA6_0 >= '\u0000' && LA6_0 <= '\b')) ) + { + alt6 = 1; + } + else if ( ((LA6_0 >= '\u000B' && LA6_0 <= '\f')) ) + { + alt6 = 2; + } + else if ( ((LA6_0 >= '\u000E' && LA6_0 <= '\u001F')) ) + { + alt6 = 3; + } + else if ( ((LA6_0 >= '!' && LA6_0 <= '\"')) ) + { + alt6 = 4; + } + else if ( ((LA6_0 >= '$' && LA6_0 <= '?')) ) + { + alt6 = 5; + } + else if ( ((LA6_0 >= 'A' && LA6_0 <= '\uFFFF')) ) + { + alt6 = 6; + } + + + switch (alt6) + { + case 1 : + // SpecFlowLang.g:279:16: ( '\\u0000' .. '\\b' ) + { + // SpecFlowLang.g:279:16: ( '\\u0000' .. '\\b' ) + // SpecFlowLang.g:279:17: '\\u0000' .. '\\b' + { + MatchRange('\u0000','\b'); + + } + + + } + break; + case 2 : + // SpecFlowLang.g:280:7: ( '\\u000B' .. '\\f' ) + { + // SpecFlowLang.g:280:7: ( '\\u000B' .. '\\f' ) + // SpecFlowLang.g:280:8: '\\u000B' .. '\\f' + { + MatchRange('\u000B','\f'); + + } + + + } + break; + case 3 : + // SpecFlowLang.g:281:7: ( '\\u000E' .. '\\u001F' ) + { + // SpecFlowLang.g:281:7: ( '\\u000E' .. '\\u001F' ) + // SpecFlowLang.g:281:8: '\\u000E' .. '\\u001F' + { + MatchRange('\u000E','\u001F'); + + } + + + } + break; + case 4 : + // SpecFlowLang.g:282:7: ( '!' .. '\"' ) + { + // SpecFlowLang.g:282:7: ( '!' .. '\"' ) + // SpecFlowLang.g:282:8: '!' .. '\"' + { + MatchRange('!','\"'); + + } + + + } + break; + case 5 : + // SpecFlowLang.g:283:7: ( '$' .. '?' ) + { + // SpecFlowLang.g:283:7: ( '$' .. '?' ) + // SpecFlowLang.g:283:8: '$' .. '?' + { + MatchRange('$','?'); + + } + + + } + break; + case 6 : + // SpecFlowLang.g:284:7: ( 'A' .. '\\uFFFF' ) + { + // SpecFlowLang.g:284:7: ( 'A' .. '\\uFFFF' ) + // SpecFlowLang.g:284:8: 'A' .. '\\uFFFF' + { + MatchRange('A','\uFFFF'); + + } + + + } + break; + + default: + if ( cnt6 >= 1 ) goto loop6; + EarlyExitException eee6 = + new EarlyExitException(6, input); + throw eee6; + } + cnt6++; + } while (true); + + loop6: + ; // Stops C# compiler whinging that label 'loop6' has no statements + + + } + + state.type = _type; + state.channel = _channel; + } + finally + { + } + } + // $ANTLR end "WORDCHAR" + + override public void mTokens() // throws RecognitionException + { + // SpecFlowLang.g:1:8: ( T__40 | T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | T__51 | T_BACKGROUND | AT | COMMENT | WS | NEWLINE | WORDCHAR ) + int alt7 = 18; + alt7 = dfa7.Predict(input); + switch (alt7) + { + case 1 : + // SpecFlowLang.g:1:10: T__40 + { + mT__40(); + + } + break; + case 2 : + // SpecFlowLang.g:1:16: T__41 + { + mT__41(); + + } + break; + case 3 : + // SpecFlowLang.g:1:22: T__42 + { + mT__42(); + + } + break; + case 4 : + // SpecFlowLang.g:1:28: T__43 + { + mT__43(); + + } + break; + case 5 : + // SpecFlowLang.g:1:34: T__44 + { + mT__44(); + + } + break; + case 6 : + // SpecFlowLang.g:1:40: T__45 + { + mT__45(); + + } + break; + case 7 : + // SpecFlowLang.g:1:46: T__46 + { + mT__46(); + + } + break; + case 8 : + // SpecFlowLang.g:1:52: T__47 + { + mT__47(); + + } + break; + case 9 : + // SpecFlowLang.g:1:58: T__48 + { + mT__48(); + + } + break; + case 10 : + // SpecFlowLang.g:1:64: T__49 + { + mT__49(); + + } + break; + case 11 : + // SpecFlowLang.g:1:70: T__50 + { + mT__50(); + + } + break; + case 12 : + // SpecFlowLang.g:1:76: T__51 + { + mT__51(); + + } + break; + case 13 : + // SpecFlowLang.g:1:82: T_BACKGROUND + { + mT_BACKGROUND(); + + } + break; + case 14 : + // SpecFlowLang.g:1:95: AT + { + mAT(); + + } + break; + case 15 : + // SpecFlowLang.g:1:98: COMMENT + { + mCOMMENT(); + + } + break; + case 16 : + // SpecFlowLang.g:1:106: WS + { + mWS(); + + } + break; + case 17 : + // SpecFlowLang.g:1:109: NEWLINE + { + mNEWLINE(); + + } + break; + case 18 : + // SpecFlowLang.g:1:117: WORDCHAR + { + mWORDCHAR(); + + } + break; + + } + + } + + + protected DFA7 dfa7; + private void InitializeCyclicDFAs() + { + this.dfa7 = new DFA7(this); + this.dfa7.specialStateTransitionHandler = new DFA.SpecialStateTransitionHandler(DFA7_SpecialStateTransition); + } + + const string DFA7_eotS = + "\x01\uffff\x09\x0f\x01\x1a\x01\uffff\x01\x1b\x03\uffff\x0a\x0f"+ + "\x02\uffff\x03\x0f\x01\x29\x01\x2a\x04\x0f\x01\x2f\x03\x0f\x02\uffff"+ + "\x02\x0f\x01\x35\x01\x36\x01\uffff\x04\x0f\x01\x3b\x02\uffff\x04"+ + "\x0f\x01\uffff\x04\x0f\x01\x44\x03\x0f\x01\uffff\x01\x4a\x01\uffff"+ + "\x01\x0f\x01\x4c\x01\x0f\x01\uffff\x01\x4e\x01\uffff\x01\x0f\x01"+ + "\uffff\x01\x50\x01\uffff"; + const string DFA7_eofS = + "\x51\uffff"; + const string DFA7_minS = + "\x01\x00\x01\x65\x01\x63\x01\x78\x01\x6e\x01\x61\x01\x69\x02\x68"+ + "\x01\x22\x01\x00\x01\uffff\x01\x09\x03\uffff\x01\x61\x01\x65\x01"+ + "\x61\x01\x64\x01\x74\x01\x63\x01\x76\x02\x65\x01\x22\x02\uffff\x01"+ + "\x74\x01\x6e\x01\x6d\x02\x00\x01\x6b\x01\x65\x02\x6e\x01\x00\x01"+ + "\x75\x01\x61\x01\x70\x02\uffff\x01\x67\x01\x6e\x02\x00\x01\uffff"+ + "\x02\x72\x01\x6c\x01\x72\x01\x00\x02\uffff\x01\x65\x01\x69\x01\x65"+ + "\x01\x6f\x01\uffff\x01\x3a\x01\x6f\x01\x73\x01\x75\x01\x00\x01\x20"+ + "\x01\x3a\x01\x6e\x01\uffff\x01\x00\x01\uffff\x01\x3a\x01\x00\x01"+ + "\x64\x01\uffff\x01\x00\x01\uffff\x01\x3a\x01\uffff\x01\x00\x01\uffff"; + const string DFA7_maxS = + "\x01\uffff\x01\x65\x01\x63\x01\x78\x01\x6e\x01\x75\x01\x69\x02"+ + "\x68\x01\x22\x01\uffff\x01\uffff\x01\x23\x03\uffff\x01\x61\x01\x65"+ + "\x01\x61\x01\x64\x01\x74\x01\x63\x01\x76\x02\x65\x01\x22\x02\uffff"+ + "\x01\x74\x01\x6e\x01\x6d\x02\uffff\x01\x6b\x01\x65\x02\x6e\x01\uffff"+ + "\x01\x75\x01\x61\x01\x70\x02\uffff\x01\x67\x01\x6e\x02\uffff\x01"+ + "\uffff\x02\x72\x01\x6c\x01\x72\x01\uffff\x02\uffff\x01\x65\x01\x69"+ + "\x01\x65\x01\x6f\x01\uffff\x01\x3a\x01\x6f\x01\x73\x01\x75\x01\uffff"+ + "\x01\x73\x01\x3a\x01\x6e\x01\uffff\x01\uffff\x01\uffff\x01\x3a\x01"+ + "\uffff\x01\x64\x01\uffff\x01\uffff\x01\uffff\x01\x3a\x01\uffff\x01"+ + "\uffff\x01\uffff"; + const string DFA7_acceptS = + "\x0b\uffff\x01\x0e\x01\uffff\x01\x0f\x01\x11\x01\x12\x0a\uffff"+ + "\x01\x0c\x01\x10\x0d\uffff\x01\x06\x01\x07\x04\uffff\x01\x0b\x05"+ + "\uffff\x01\x09\x01\x0a\x04\uffff\x01\x08\x08\uffff\x01\x01\x01\uffff"+ + "\x01\x03\x03\uffff\x01\x02\x01\uffff\x01\x04\x01\uffff\x01\x05\x01"+ + "\uffff\x01\x0d"; + const string DFA7_specialS = + "\x01\x06\x09\uffff\x01\x0c\x14\uffff\x01\x03\x01\x04\x04\uffff"+ + "\x01\x09\x07\uffff\x01\x01\x01\x08\x05\uffff\x01\x00\x0b\uffff\x01"+ + "\x05\x04\uffff\x01\x0b\x02\uffff\x01\x0a\x02\uffff\x01\x07\x03\uffff"+ + "\x01\x02\x01\uffff}>"; + static readonly string[] DFA7_transitionS = { + "\x09\x0f\x01\x0c\x01\x0e\x02\x0f\x01\x0e\x12\x0f\x01\x0c\x01"+ + "\x0f\x01\x09\x01\x0d\x1c\x0f\x01\x0b\x01\x04\x01\x05\x02\x0f"+ + "\x01\x03\x01\x01\x01\x06\x0b\x0f\x01\x02\x01\x08\x02\x0f\x01"+ + "\x07\x24\x0f\x01\x0a\uff83\x0f", + "\x01\x10", + "\x01\x11", + "\x01\x12", + "\x01\x13", + "\x01\x15\x13\uffff\x01\x14", + "\x01\x16", + "\x01\x17", + "\x01\x18", + "\x01\x19", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "", + "\x01\x0c\x16\uffff\x01\x0c\x02\uffff\x01\x0d", + "", + "", + "", + "\x01\x1c", + "\x01\x1d", + "\x01\x1e", + "\x01\x1f", + "\x01\x20", + "\x01\x21", + "\x01\x22", + "\x01\x23", + "\x01\x24", + "\x01\x25", + "", + "", + "\x01\x26", + "\x01\x27", + "\x01\x28", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "\x01\x2b", + "\x01\x2c", + "\x01\x2d", + "\x01\x2e", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "\x01\x30", + "\x01\x31", + "\x01\x32", + "", + "", + "\x01\x33", + "\x01\x34", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "", + "\x01\x37", + "\x01\x38", + "\x01\x39", + "\x01\x3a", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "", + "", + "\x01\x3c", + "\x01\x3d", + "\x01\x3e", + "\x01\x3f", + "", + "\x01\x40", + "\x01\x41", + "\x01\x42", + "\x01\x43", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "\x01\x46\x19\uffff\x01\x45\x38\uffff\x01\x47", + "\x01\x48", + "\x01\x49", + "", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "", + "\x01\x4b", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "\x01\x4d", + "", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "", + "\x01\x4f", + "", + "\x09\x0f\x02\uffff\x02\x0f\x01\uffff\x12\x0f\x01\uffff\x02"+ + "\x0f\x01\uffff\x1c\x0f\x01\uffff\uffbf\x0f", + "" + }; + + static readonly short[] DFA7_eot = DFA.UnpackEncodedString(DFA7_eotS); + static readonly short[] DFA7_eof = DFA.UnpackEncodedString(DFA7_eofS); + static readonly char[] DFA7_min = DFA.UnpackEncodedStringToUnsignedChars(DFA7_minS); + static readonly char[] DFA7_max = DFA.UnpackEncodedStringToUnsignedChars(DFA7_maxS); + static readonly short[] DFA7_accept = DFA.UnpackEncodedString(DFA7_acceptS); + static readonly short[] DFA7_special = DFA.UnpackEncodedString(DFA7_specialS); + static readonly short[][] DFA7_transition = DFA.UnpackEncodedStringArray(DFA7_transitionS); + + protected class DFA7 : DFA + { + public DFA7(BaseRecognizer recognizer) + { + this.recognizer = recognizer; + this.decisionNumber = 7; + this.eot = DFA7_eot; + this.eof = DFA7_eof; + this.min = DFA7_min; + this.max = DFA7_max; + this.accept = DFA7_accept; + this.special = DFA7_special; + this.transition = DFA7_transition; + + } + + override public string Description + { + get { return "1:1: Tokens : ( T__40 | T__41 | T__42 | T__43 | T__44 | T__45 | T__46 | T__47 | T__48 | T__49 | T__50 | T__51 | T_BACKGROUND | AT | COMMENT | WS | NEWLINE | WORDCHAR );"; } + } + + } + + + protected internal int DFA7_SpecialStateTransition(DFA dfa, int s, IIntStream _input) //throws NoViableAltException + { + IIntStream input = _input; + int _s = s; + switch ( s ) + { + case 0 : + int LA7_52 = input.LA(1); + + s = -1; + if ( ((LA7_52 >= '\u0000' && LA7_52 <= '\b') || (LA7_52 >= '\u000B' && LA7_52 <= '\f') || (LA7_52 >= '\u000E' && LA7_52 <= '\u001F') || (LA7_52 >= '!' && LA7_52 <= '\"') || (LA7_52 >= '$' && LA7_52 <= '?') || (LA7_52 >= 'A' && LA7_52 <= '\uFFFF')) ) { s = 15; } + + else s = 59; + + if ( s >= 0 ) return s; + break; + case 1 : + int LA7_45 = input.LA(1); + + s = -1; + if ( ((LA7_45 >= '\u0000' && LA7_45 <= '\b') || (LA7_45 >= '\u000B' && LA7_45 <= '\f') || (LA7_45 >= '\u000E' && LA7_45 <= '\u001F') || (LA7_45 >= '!' && LA7_45 <= '\"') || (LA7_45 >= '$' && LA7_45 <= '?') || (LA7_45 >= 'A' && LA7_45 <= '\uFFFF')) ) { s = 15; } + + else s = 53; + + if ( s >= 0 ) return s; + break; + case 2 : + int LA7_79 = input.LA(1); + + s = -1; + if ( ((LA7_79 >= '\u0000' && LA7_79 <= '\b') || (LA7_79 >= '\u000B' && LA7_79 <= '\f') || (LA7_79 >= '\u000E' && LA7_79 <= '\u001F') || (LA7_79 >= '!' && LA7_79 <= '\"') || (LA7_79 >= '$' && LA7_79 <= '?') || (LA7_79 >= 'A' && LA7_79 <= '\uFFFF')) ) { s = 15; } + + else s = 80; + + if ( s >= 0 ) return s; + break; + case 3 : + int LA7_31 = input.LA(1); + + s = -1; + if ( ((LA7_31 >= '\u0000' && LA7_31 <= '\b') || (LA7_31 >= '\u000B' && LA7_31 <= '\f') || (LA7_31 >= '\u000E' && LA7_31 <= '\u001F') || (LA7_31 >= '!' && LA7_31 <= '\"') || (LA7_31 >= '$' && LA7_31 <= '?') || (LA7_31 >= 'A' && LA7_31 <= '\uFFFF')) ) { s = 15; } + + else s = 41; + + if ( s >= 0 ) return s; + break; + case 4 : + int LA7_32 = input.LA(1); + + s = -1; + if ( ((LA7_32 >= '\u0000' && LA7_32 <= '\b') || (LA7_32 >= '\u000B' && LA7_32 <= '\f') || (LA7_32 >= '\u000E' && LA7_32 <= '\u001F') || (LA7_32 >= '!' && LA7_32 <= '\"') || (LA7_32 >= '$' && LA7_32 <= '?') || (LA7_32 >= 'A' && LA7_32 <= '\uFFFF')) ) { s = 15; } + + else s = 42; + + if ( s >= 0 ) return s; + break; + case 5 : + int LA7_64 = input.LA(1); + + s = -1; + if ( ((LA7_64 >= '\u0000' && LA7_64 <= '\b') || (LA7_64 >= '\u000B' && LA7_64 <= '\f') || (LA7_64 >= '\u000E' && LA7_64 <= '\u001F') || (LA7_64 >= '!' && LA7_64 <= '\"') || (LA7_64 >= '$' && LA7_64 <= '?') || (LA7_64 >= 'A' && LA7_64 <= '\uFFFF')) ) { s = 15; } + + else s = 68; + + if ( s >= 0 ) return s; + break; + case 6 : + int LA7_0 = input.LA(1); + + s = -1; + if ( (LA7_0 == 'F') ) { s = 1; } + + else if ( (LA7_0 == 'S') ) { s = 2; } + + else if ( (LA7_0 == 'E') ) { s = 3; } + + else if ( (LA7_0 == 'A') ) { s = 4; } + + else if ( (LA7_0 == 'B') ) { s = 5; } + + else if ( (LA7_0 == 'G') ) { s = 6; } + + else if ( (LA7_0 == 'W') ) { s = 7; } + + else if ( (LA7_0 == 'T') ) { s = 8; } + + else if ( (LA7_0 == '\"') ) { s = 9; } + + else if ( (LA7_0 == '|') ) { s = 10; } + + else if ( (LA7_0 == '@') ) { s = 11; } + + else if ( (LA7_0 == '\t' || LA7_0 == ' ') ) { s = 12; } + + else if ( (LA7_0 == '#') ) { s = 13; } + + else if ( (LA7_0 == '\n' || LA7_0 == '\r') ) { s = 14; } + + else if ( ((LA7_0 >= '\u0000' && LA7_0 <= '\b') || (LA7_0 >= '\u000B' && LA7_0 <= '\f') || (LA7_0 >= '\u000E' && LA7_0 <= '\u001F') || LA7_0 == '!' || (LA7_0 >= '$' && LA7_0 <= '?') || (LA7_0 >= 'C' && LA7_0 <= 'D') || (LA7_0 >= 'H' && LA7_0 <= 'R') || (LA7_0 >= 'U' && LA7_0 <= 'V') || (LA7_0 >= 'X' && LA7_0 <= '{') || (LA7_0 >= '}' && LA7_0 <= '\uFFFF')) ) { s = 15; } + + if ( s >= 0 ) return s; + break; + case 7 : + int LA7_75 = input.LA(1); + + s = -1; + if ( ((LA7_75 >= '\u0000' && LA7_75 <= '\b') || (LA7_75 >= '\u000B' && LA7_75 <= '\f') || (LA7_75 >= '\u000E' && LA7_75 <= '\u001F') || (LA7_75 >= '!' && LA7_75 <= '\"') || (LA7_75 >= '$' && LA7_75 <= '?') || (LA7_75 >= 'A' && LA7_75 <= '\uFFFF')) ) { s = 15; } + + else s = 78; + + if ( s >= 0 ) return s; + break; + case 8 : + int LA7_46 = input.LA(1); + + s = -1; + if ( ((LA7_46 >= '\u0000' && LA7_46 <= '\b') || (LA7_46 >= '\u000B' && LA7_46 <= '\f') || (LA7_46 >= '\u000E' && LA7_46 <= '\u001F') || (LA7_46 >= '!' && LA7_46 <= '\"') || (LA7_46 >= '$' && LA7_46 <= '?') || (LA7_46 >= 'A' && LA7_46 <= '\uFFFF')) ) { s = 15; } + + else s = 54; + + if ( s >= 0 ) return s; + break; + case 9 : + int LA7_37 = input.LA(1); + + s = -1; + if ( ((LA7_37 >= '\u0000' && LA7_37 <= '\b') || (LA7_37 >= '\u000B' && LA7_37 <= '\f') || (LA7_37 >= '\u000E' && LA7_37 <= '\u001F') || (LA7_37 >= '!' && LA7_37 <= '\"') || (LA7_37 >= '$' && LA7_37 <= '?') || (LA7_37 >= 'A' && LA7_37 <= '\uFFFF')) ) { s = 15; } + + else s = 47; + + if ( s >= 0 ) return s; + break; + case 10 : + int LA7_72 = input.LA(1); + + s = -1; + if ( ((LA7_72 >= '\u0000' && LA7_72 <= '\b') || (LA7_72 >= '\u000B' && LA7_72 <= '\f') || (LA7_72 >= '\u000E' && LA7_72 <= '\u001F') || (LA7_72 >= '!' && LA7_72 <= '\"') || (LA7_72 >= '$' && LA7_72 <= '?') || (LA7_72 >= 'A' && LA7_72 <= '\uFFFF')) ) { s = 15; } + + else s = 76; + + if ( s >= 0 ) return s; + break; + case 11 : + int LA7_69 = input.LA(1); + + s = -1; + if ( ((LA7_69 >= '\u0000' && LA7_69 <= '\b') || (LA7_69 >= '\u000B' && LA7_69 <= '\f') || (LA7_69 >= '\u000E' && LA7_69 <= '\u001F') || (LA7_69 >= '!' && LA7_69 <= '\"') || (LA7_69 >= '$' && LA7_69 <= '?') || (LA7_69 >= 'A' && LA7_69 <= '\uFFFF')) ) { s = 15; } + + else s = 74; + + if ( s >= 0 ) return s; + break; + case 12 : + int LA7_10 = input.LA(1); + + s = -1; + if ( ((LA7_10 >= '\u0000' && LA7_10 <= '\b') || (LA7_10 >= '\u000B' && LA7_10 <= '\f') || (LA7_10 >= '\u000E' && LA7_10 <= '\u001F') || (LA7_10 >= '!' && LA7_10 <= '\"') || (LA7_10 >= '$' && LA7_10 <= '?') || (LA7_10 >= 'A' && LA7_10 <= '\uFFFF')) ) { s = 15; } + + else s = 26; + + if ( s >= 0 ) return s; + break; + } + NoViableAltException nvae7 = + new NoViableAltException(dfa.Description, 7, _s, input); + dfa.Error(nvae7); + throw nvae7; + } + + +} +} \ No newline at end of file diff --git a/Parser/Grammar/SpecFlowLangParser.cs b/Parser/Grammar/SpecFlowLangParser.cs new file mode 100644 index 000000000..7afbba3c3 --- /dev/null +++ b/Parser/Grammar/SpecFlowLangParser.cs @@ -0,0 +1,6630 @@ +// $ANTLR 3.1.2 SpecFlowLang.g 2009-10-16 10:52:11 + +// The variable 'variable' is assigned but its value is never used. +#pragma warning disable 168, 219 +// Unreachable code detected. +#pragma warning disable 162 +namespace TechTalk.SpecFlow.Parser.Grammar +{ + +using System; +using Antlr.Runtime; +using IList = System.Collections.IList; +using ArrayList = System.Collections.ArrayList; +using Stack = Antlr.Runtime.Collections.StackList; + +using IDictionary = System.Collections.IDictionary; +using Hashtable = System.Collections.Hashtable; + + +using Antlr.Runtime.Tree; + +public partial class SpecFlowLangParser : Parser +{ + public static readonly string[] tokenNames = new string[] + { + "", + "", + "", + "", + "FEATURE", + "DESCRIPTIONLINE", + "BACKGROUND", + "SCENARIOS", + "SCENARIO", + "SCENARIOOUTLINE", + "EXAMPLES", + "EXAMPLESET", + "STEPS", + "GIVEN", + "WHEN", + "THEN", + "TEXT", + "AND", + "BUT", + "TAGS", + "TAG", + "WORD", + "MULTILINETEXT", + "INDENT", + "LINE", + "TABLE", + "HEADER", + "BODY", + "ROW", + "CELL", + "WS", + "AT", + "WORDCHAR", + "T_BACKGROUND", + "NEWLINE", + "WSCHAR", + "NONWCHR", + "NEWLINECHR", + "NONNLCHR", + "COMMENT", + "'Feature:'", + "'Scenario:'", + "'Scenario Outline:'", + "'Examples:'", + "'Scenarios:'", + "'And'", + "'But'", + "'Given'", + "'When'", + "'Then'", + "'\"\"\"'", + "'|'" + }; + + public const int NEWLINECHR = 37; + public const int ROW = 28; + public const int T_BACKGROUND = 33; + public const int TABLE = 25; + public const int CELL = 29; + public const int DESCRIPTIONLINE = 5; + public const int AND = 17; + public const int EOF = -1; + public const int INDENT = 23; + public const int WORD = 21; + public const int AT = 31; + public const int BACKGROUND = 6; + public const int T__51 = 51; + public const int THEN = 15; + public const int MULTILINETEXT = 22; + public const int NONWCHR = 36; + public const int BODY = 27; + public const int GIVEN = 13; + public const int HEADER = 26; + public const int COMMENT = 39; + public const int SCENARIO = 8; + public const int T__50 = 50; + public const int T__42 = 42; + public const int T__43 = 43; + public const int T__40 = 40; + public const int T__41 = 41; + public const int T__46 = 46; + public const int T__47 = 47; + public const int T__44 = 44; + public const int T__45 = 45; + public const int EXAMPLESET = 11; + public const int T__48 = 48; + public const int T__49 = 49; + public const int BUT = 18; + public const int TAGS = 19; + public const int EXAMPLES = 10; + public const int WSCHAR = 35; + public const int TEXT = 16; + public const int NONNLCHR = 38; + public const int LINE = 24; + public const int FEATURE = 4; + public const int TAG = 20; + public const int SCENARIOS = 7; + public const int WORDCHAR = 32; + public const int WS = 30; + public const int NEWLINE = 34; + public const int SCENARIOOUTLINE = 9; + public const int WHEN = 14; + public const int STEPS = 12; + + // delegates + // delegators + + + + public SpecFlowLangParser(ITokenStream input) + : this(input, new RecognizerSharedState()) { + } + + public SpecFlowLangParser(ITokenStream input, RecognizerSharedState state) + : base(input, state) { + InitializeCyclicDFAs(); + + + } + + protected ITreeAdaptor adaptor = new CommonTreeAdaptor(); + + public ITreeAdaptor TreeAdaptor + { + get { return this.adaptor; } + set { + this.adaptor = value; + } + } + + override public string[] TokenNames { + get { return SpecFlowLangParser.tokenNames; } + } + + override public string GrammarFileName { + get { return "SpecFlowLang.g"; } + } + + + public class feature_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "feature" + // SpecFlowLang.g:44:1: feature : ( newlineWithSpaces )? ( tags )? ( WS )? 'Feature:' ( WS )? text newlineWithSpaces ( descriptionLine )* ( background )? ( scenarioKind )* ( WS )? EOF -> ^( FEATURE ( tags )? text ( descriptionLine )* ( background )? ^( SCENARIOS ( scenarioKind )* ) ) ; + public SpecFlowLangParser.feature_return feature() // throws RecognitionException [1] + { + SpecFlowLangParser.feature_return retval = new SpecFlowLangParser.feature_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS3 = null; + IToken string_literal4 = null; + IToken WS5 = null; + IToken WS11 = null; + IToken EOF12 = null; + SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces1 = default(SpecFlowLangParser.newlineWithSpaces_return); + + SpecFlowLangParser.tags_return tags2 = default(SpecFlowLangParser.tags_return); + + SpecFlowLangParser.text_return text6 = default(SpecFlowLangParser.text_return); + + SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces7 = default(SpecFlowLangParser.newlineWithSpaces_return); + + SpecFlowLangParser.descriptionLine_return descriptionLine8 = default(SpecFlowLangParser.descriptionLine_return); + + SpecFlowLangParser.background_return background9 = default(SpecFlowLangParser.background_return); + + SpecFlowLangParser.scenarioKind_return scenarioKind10 = default(SpecFlowLangParser.scenarioKind_return); + + + object WS3_tree=null; + object string_literal4_tree=null; + object WS5_tree=null; + object WS11_tree=null; + object EOF12_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleTokenStream stream_40 = new RewriteRuleTokenStream(adaptor,"token 40"); + RewriteRuleTokenStream stream_EOF = new RewriteRuleTokenStream(adaptor,"token EOF"); + RewriteRuleSubtreeStream stream_tags = new RewriteRuleSubtreeStream(adaptor,"rule tags"); + RewriteRuleSubtreeStream stream_text = new RewriteRuleSubtreeStream(adaptor,"rule text"); + RewriteRuleSubtreeStream stream_scenarioKind = new RewriteRuleSubtreeStream(adaptor,"rule scenarioKind"); + RewriteRuleSubtreeStream stream_background = new RewriteRuleSubtreeStream(adaptor,"rule background"); + RewriteRuleSubtreeStream stream_newlineWithSpaces = new RewriteRuleSubtreeStream(adaptor,"rule newlineWithSpaces"); + RewriteRuleSubtreeStream stream_descriptionLine = new RewriteRuleSubtreeStream(adaptor,"rule descriptionLine"); + try + { + // SpecFlowLang.g:45:5: ( ( newlineWithSpaces )? ( tags )? ( WS )? 'Feature:' ( WS )? text newlineWithSpaces ( descriptionLine )* ( background )? ( scenarioKind )* ( WS )? EOF -> ^( FEATURE ( tags )? text ( descriptionLine )* ( background )? ^( SCENARIOS ( scenarioKind )* ) ) ) + // SpecFlowLang.g:45:9: ( newlineWithSpaces )? ( tags )? ( WS )? 'Feature:' ( WS )? text newlineWithSpaces ( descriptionLine )* ( background )? ( scenarioKind )* ( WS )? EOF + { + // SpecFlowLang.g:45:9: ( newlineWithSpaces )? + int alt1 = 2; + int LA1_0 = input.LA(1); + + if ( (LA1_0 == WS) ) + { + int LA1_1 = input.LA(2); + + if ( (LA1_1 == NEWLINE) ) + { + alt1 = 1; + } + } + else if ( (LA1_0 == NEWLINE) ) + { + alt1 = 1; + } + switch (alt1) + { + case 1 : + // SpecFlowLang.g:0:0: newlineWithSpaces + { + PushFollow(FOLLOW_newlineWithSpaces_in_feature264); + newlineWithSpaces1 = newlineWithSpaces(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_newlineWithSpaces.Add(newlineWithSpaces1.Tree); + + } + break; + + } + + // SpecFlowLang.g:46:9: ( tags )? + int alt2 = 2; + int LA2_0 = input.LA(1); + + if ( (LA2_0 == WS) ) + { + int LA2_1 = input.LA(2); + + if ( (LA2_1 == AT) ) + { + alt2 = 1; + } + } + else if ( (LA2_0 == AT) ) + { + alt2 = 1; + } + switch (alt2) + { + case 1 : + // SpecFlowLang.g:0:0: tags + { + PushFollow(FOLLOW_tags_in_feature275); + tags2 = tags(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_tags.Add(tags2.Tree); + + } + break; + + } + + // SpecFlowLang.g:47:9: ( WS )? + int alt3 = 2; + int LA3_0 = input.LA(1); + + if ( (LA3_0 == WS) ) + { + alt3 = 1; + } + switch (alt3) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS3=(IToken)Match(input,WS,FOLLOW_WS_in_feature286); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS3); + + + } + break; + + } + + string_literal4=(IToken)Match(input,40,FOLLOW_40_in_feature289); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_40.Add(string_literal4); + + // SpecFlowLang.g:47:24: ( WS )? + int alt4 = 2; + int LA4_0 = input.LA(1); + + if ( (LA4_0 == WS) ) + { + alt4 = 1; + } + switch (alt4) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS5=(IToken)Match(input,WS,FOLLOW_WS_in_feature291); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS5); + + + } + break; + + } + + PushFollow(FOLLOW_text_in_feature294); + text6 = text(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_text.Add(text6.Tree); + PushFollow(FOLLOW_newlineWithSpaces_in_feature296); + newlineWithSpaces7 = newlineWithSpaces(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_newlineWithSpaces.Add(newlineWithSpaces7.Tree); + // SpecFlowLang.g:48:9: ( descriptionLine )* + do + { + int alt5 = 2; + int LA5_0 = input.LA(1); + + if ( (LA5_0 == WS) ) + { + int LA5_1 = input.LA(2); + + if ( (LA5_1 == WORDCHAR) ) + { + alt5 = 1; + } + + + } + else if ( (LA5_0 == WORDCHAR) ) + { + alt5 = 1; + } + + + switch (alt5) + { + case 1 : + // SpecFlowLang.g:0:0: descriptionLine + { + PushFollow(FOLLOW_descriptionLine_in_feature306); + descriptionLine8 = descriptionLine(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_descriptionLine.Add(descriptionLine8.Tree); + + } + break; + + default: + goto loop5; + } + } while (true); + + loop5: + ; // Stops C# compiler whining that label 'loop5' has no statements + + // SpecFlowLang.g:49:9: ( background )? + int alt6 = 2; + int LA6_0 = input.LA(1); + + if ( (LA6_0 == WS) ) + { + int LA6_1 = input.LA(2); + + if ( (LA6_1 == T_BACKGROUND) ) + { + alt6 = 1; + } + } + else if ( (LA6_0 == T_BACKGROUND) ) + { + alt6 = 1; + } + switch (alt6) + { + case 1 : + // SpecFlowLang.g:0:0: background + { + PushFollow(FOLLOW_background_in_feature317); + background9 = background(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_background.Add(background9.Tree); + + } + break; + + } + + // SpecFlowLang.g:50:9: ( scenarioKind )* + do + { + int alt7 = 2; + int LA7_0 = input.LA(1); + + if ( (LA7_0 == WS) ) + { + int LA7_1 = input.LA(2); + + if ( (LA7_1 == AT || (LA7_1 >= 41 && LA7_1 <= 42)) ) + { + alt7 = 1; + } + + + } + else if ( (LA7_0 == AT || (LA7_0 >= 41 && LA7_0 <= 42)) ) + { + alt7 = 1; + } + + + switch (alt7) + { + case 1 : + // SpecFlowLang.g:0:0: scenarioKind + { + PushFollow(FOLLOW_scenarioKind_in_feature328); + scenarioKind10 = scenarioKind(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_scenarioKind.Add(scenarioKind10.Tree); + + } + break; + + default: + goto loop7; + } + } while (true); + + loop7: + ; // Stops C# compiler whining that label 'loop7' has no statements + + // SpecFlowLang.g:50:23: ( WS )? + int alt8 = 2; + int LA8_0 = input.LA(1); + + if ( (LA8_0 == WS) ) + { + alt8 = 1; + } + switch (alt8) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS11=(IToken)Match(input,WS,FOLLOW_WS_in_feature331); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS11); + + + } + break; + + } + + EOF12=(IToken)Match(input,EOF,FOLLOW_EOF_in_feature334); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_EOF.Add(EOF12); + + + + // AST REWRITE + // elements: text, scenarioKind, tags, background, descriptionLine + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 51:9: -> ^( FEATURE ( tags )? text ( descriptionLine )* ( background )? ^( SCENARIOS ( scenarioKind )* ) ) + { + // SpecFlowLang.g:51:12: ^( FEATURE ( tags )? text ( descriptionLine )* ( background )? ^( SCENARIOS ( scenarioKind )* ) ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(FEATURE, "FEATURE"), root_1); + + // SpecFlowLang.g:51:22: ( tags )? + if ( stream_tags.HasNext() ) + { + adaptor.AddChild(root_1, stream_tags.NextTree()); + + } + stream_tags.Reset(); + adaptor.AddChild(root_1, stream_text.NextTree()); + // SpecFlowLang.g:51:33: ( descriptionLine )* + while ( stream_descriptionLine.HasNext() ) + { + adaptor.AddChild(root_1, stream_descriptionLine.NextTree()); + + } + stream_descriptionLine.Reset(); + // SpecFlowLang.g:51:50: ( background )? + if ( stream_background.HasNext() ) + { + adaptor.AddChild(root_1, stream_background.NextTree()); + + } + stream_background.Reset(); + // SpecFlowLang.g:52:13: ^( SCENARIOS ( scenarioKind )* ) + { + object root_2 = (object)adaptor.GetNilNode(); + root_2 = (object)adaptor.BecomeRoot((object)adaptor.Create(SCENARIOS, "SCENARIOS"), root_2); + + // SpecFlowLang.g:52:25: ( scenarioKind )* + while ( stream_scenarioKind.HasNext() ) + { + adaptor.AddChild(root_2, stream_scenarioKind.NextTree()); + + } + stream_scenarioKind.Reset(); + + adaptor.AddChild(root_1, root_2); + } + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "feature" + + public class tags_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "tags" + // SpecFlowLang.g:56:1: tags : ( WS )? ( tag )+ -> ^( TAGS ( tag )+ ) ; + public SpecFlowLangParser.tags_return tags() // throws RecognitionException [1] + { + SpecFlowLangParser.tags_return retval = new SpecFlowLangParser.tags_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS13 = null; + SpecFlowLangParser.tag_return tag14 = default(SpecFlowLangParser.tag_return); + + + object WS13_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleSubtreeStream stream_tag = new RewriteRuleSubtreeStream(adaptor,"rule tag"); + try + { + // SpecFlowLang.g:57:5: ( ( WS )? ( tag )+ -> ^( TAGS ( tag )+ ) ) + // SpecFlowLang.g:57:9: ( WS )? ( tag )+ + { + // SpecFlowLang.g:57:9: ( WS )? + int alt9 = 2; + int LA9_0 = input.LA(1); + + if ( (LA9_0 == WS) ) + { + alt9 = 1; + } + switch (alt9) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS13=(IToken)Match(input,WS,FOLLOW_WS_in_tags411); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS13); + + + } + break; + + } + + // SpecFlowLang.g:57:13: ( tag )+ + int cnt10 = 0; + do + { + int alt10 = 2; + int LA10_0 = input.LA(1); + + if ( (LA10_0 == AT) ) + { + alt10 = 1; + } + + + switch (alt10) + { + case 1 : + // SpecFlowLang.g:0:0: tag + { + PushFollow(FOLLOW_tag_in_tags414); + tag14 = tag(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_tag.Add(tag14.Tree); + + } + break; + + default: + if ( cnt10 >= 1 ) goto loop10; + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + EarlyExitException eee10 = + new EarlyExitException(10, input); + throw eee10; + } + cnt10++; + } while (true); + + loop10: + ; // Stops C# compiler whinging that label 'loop10' has no statements + + + + // AST REWRITE + // elements: tag + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 58:9: -> ^( TAGS ( tag )+ ) + { + // SpecFlowLang.g:58:12: ^( TAGS ( tag )+ ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(TAGS, "TAGS"), root_1); + + if ( !(stream_tag.HasNext()) ) { + throw new RewriteEarlyExitException(); + } + while ( stream_tag.HasNext() ) + { + adaptor.AddChild(root_1, stream_tag.NextTree()); + + } + stream_tag.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "tags" + + public class tag_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "tag" + // SpecFlowLang.g:61:1: tag : AT word ( newlineWithSpaces | WS ) -> ^( TAG word ) ; + public SpecFlowLangParser.tag_return tag() // throws RecognitionException [1] + { + SpecFlowLangParser.tag_return retval = new SpecFlowLangParser.tag_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken AT15 = null; + IToken WS18 = null; + SpecFlowLangParser.word_return word16 = default(SpecFlowLangParser.word_return); + + SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces17 = default(SpecFlowLangParser.newlineWithSpaces_return); + + + object AT15_tree=null; + object WS18_tree=null; + RewriteRuleTokenStream stream_AT = new RewriteRuleTokenStream(adaptor,"token AT"); + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleSubtreeStream stream_word = new RewriteRuleSubtreeStream(adaptor,"rule word"); + RewriteRuleSubtreeStream stream_newlineWithSpaces = new RewriteRuleSubtreeStream(adaptor,"rule newlineWithSpaces"); + try + { + // SpecFlowLang.g:62:5: ( AT word ( newlineWithSpaces | WS ) -> ^( TAG word ) ) + // SpecFlowLang.g:62:9: AT word ( newlineWithSpaces | WS ) + { + AT15=(IToken)Match(input,AT,FOLLOW_AT_in_tag451); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_AT.Add(AT15); + + PushFollow(FOLLOW_word_in_tag453); + word16 = word(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_word.Add(word16.Tree); + // SpecFlowLang.g:62:17: ( newlineWithSpaces | WS ) + int alt11 = 2; + int LA11_0 = input.LA(1); + + if ( (LA11_0 == WS) ) + { + int LA11_1 = input.LA(2); + + if ( (LA11_1 == EOF || (LA11_1 >= WS && LA11_1 <= AT) || (LA11_1 >= 40 && LA11_1 <= 42)) ) + { + alt11 = 2; + } + else if ( (LA11_1 == NEWLINE) ) + { + alt11 = 1; + } + else + { + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + NoViableAltException nvae_d11s1 = + new NoViableAltException("", 11, 1, input); + + throw nvae_d11s1; + } + } + else if ( (LA11_0 == NEWLINE) ) + { + alt11 = 1; + } + else + { + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + NoViableAltException nvae_d11s0 = + new NoViableAltException("", 11, 0, input); + + throw nvae_d11s0; + } + switch (alt11) + { + case 1 : + // SpecFlowLang.g:62:18: newlineWithSpaces + { + PushFollow(FOLLOW_newlineWithSpaces_in_tag456); + newlineWithSpaces17 = newlineWithSpaces(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_newlineWithSpaces.Add(newlineWithSpaces17.Tree); + + } + break; + case 2 : + // SpecFlowLang.g:62:36: WS + { + WS18=(IToken)Match(input,WS,FOLLOW_WS_in_tag458); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS18); + + + } + break; + + } + + + + // AST REWRITE + // elements: word + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 63:9: -> ^( TAG word ) + { + // SpecFlowLang.g:63:12: ^( TAG word ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(TAG, "TAG"), root_1); + + adaptor.AddChild(root_1, stream_word.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "tag" + + public class word_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "word" + // SpecFlowLang.g:66:1: word : ( WORDCHAR )+ -> ^( WORD ( WORDCHAR )+ ) ; + public SpecFlowLangParser.word_return word() // throws RecognitionException [1] + { + SpecFlowLangParser.word_return retval = new SpecFlowLangParser.word_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WORDCHAR19 = null; + + object WORDCHAR19_tree=null; + RewriteRuleTokenStream stream_WORDCHAR = new RewriteRuleTokenStream(adaptor,"token WORDCHAR"); + + try + { + // SpecFlowLang.g:67:5: ( ( WORDCHAR )+ -> ^( WORD ( WORDCHAR )+ ) ) + // SpecFlowLang.g:67:9: ( WORDCHAR )+ + { + // SpecFlowLang.g:67:9: ( WORDCHAR )+ + int cnt12 = 0; + do + { + int alt12 = 2; + int LA12_0 = input.LA(1); + + if ( (LA12_0 == WORDCHAR) ) + { + alt12 = 1; + } + + + switch (alt12) + { + case 1 : + // SpecFlowLang.g:0:0: WORDCHAR + { + WORDCHAR19=(IToken)Match(input,WORDCHAR,FOLLOW_WORDCHAR_in_word494); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WORDCHAR.Add(WORDCHAR19); + + + } + break; + + default: + if ( cnt12 >= 1 ) goto loop12; + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + EarlyExitException eee12 = + new EarlyExitException(12, input); + throw eee12; + } + cnt12++; + } while (true); + + loop12: + ; // Stops C# compiler whinging that label 'loop12' has no statements + + + + // AST REWRITE + // elements: WORDCHAR + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 68:9: -> ^( WORD ( WORDCHAR )+ ) + { + // SpecFlowLang.g:68:12: ^( WORD ( WORDCHAR )+ ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(WORD, "WORD"), root_1); + + if ( !(stream_WORDCHAR.HasNext()) ) { + throw new RewriteEarlyExitException(); + } + while ( stream_WORDCHAR.HasNext() ) + { + adaptor.AddChild(root_1, stream_WORDCHAR.NextNode()); + + } + stream_WORDCHAR.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "word" + + public class descriptionLine_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "descriptionLine" + // SpecFlowLang.g:71:1: descriptionLine : ( WS )? descriptionLineText newlineWithSpaces -> ^( DESCRIPTIONLINE descriptionLineText ) ; + public SpecFlowLangParser.descriptionLine_return descriptionLine() // throws RecognitionException [1] + { + SpecFlowLangParser.descriptionLine_return retval = new SpecFlowLangParser.descriptionLine_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS20 = null; + SpecFlowLangParser.descriptionLineText_return descriptionLineText21 = default(SpecFlowLangParser.descriptionLineText_return); + + SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces22 = default(SpecFlowLangParser.newlineWithSpaces_return); + + + object WS20_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleSubtreeStream stream_descriptionLineText = new RewriteRuleSubtreeStream(adaptor,"rule descriptionLineText"); + RewriteRuleSubtreeStream stream_newlineWithSpaces = new RewriteRuleSubtreeStream(adaptor,"rule newlineWithSpaces"); + try + { + // SpecFlowLang.g:72:5: ( ( WS )? descriptionLineText newlineWithSpaces -> ^( DESCRIPTIONLINE descriptionLineText ) ) + // SpecFlowLang.g:72:9: ( WS )? descriptionLineText newlineWithSpaces + { + // SpecFlowLang.g:72:9: ( WS )? + int alt13 = 2; + int LA13_0 = input.LA(1); + + if ( (LA13_0 == WS) ) + { + alt13 = 1; + } + switch (alt13) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS20=(IToken)Match(input,WS,FOLLOW_WS_in_descriptionLine531); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS20); + + + } + break; + + } + + PushFollow(FOLLOW_descriptionLineText_in_descriptionLine534); + descriptionLineText21 = descriptionLineText(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_descriptionLineText.Add(descriptionLineText21.Tree); + PushFollow(FOLLOW_newlineWithSpaces_in_descriptionLine536); + newlineWithSpaces22 = newlineWithSpaces(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_newlineWithSpaces.Add(newlineWithSpaces22.Tree); + + + // AST REWRITE + // elements: descriptionLineText + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 73:9: -> ^( DESCRIPTIONLINE descriptionLineText ) + { + // SpecFlowLang.g:73:12: ^( DESCRIPTIONLINE descriptionLineText ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(DESCRIPTIONLINE, "DESCRIPTIONLINE"), root_1); + + adaptor.AddChild(root_1, stream_descriptionLineText.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "descriptionLine" + + public class background_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "background" + // SpecFlowLang.g:76:1: background : ( WS )? T_BACKGROUND ( WS title )? newlineWithSpaces givens -> ^( BACKGROUND ( title )? givens ) ; + public SpecFlowLangParser.background_return background() // throws RecognitionException [1] + { + SpecFlowLangParser.background_return retval = new SpecFlowLangParser.background_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS23 = null; + IToken T_BACKGROUND24 = null; + IToken WS25 = null; + SpecFlowLangParser.title_return title26 = default(SpecFlowLangParser.title_return); + + SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces27 = default(SpecFlowLangParser.newlineWithSpaces_return); + + SpecFlowLangParser.givens_return givens28 = default(SpecFlowLangParser.givens_return); + + + object WS23_tree=null; + object T_BACKGROUND24_tree=null; + object WS25_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleTokenStream stream_T_BACKGROUND = new RewriteRuleTokenStream(adaptor,"token T_BACKGROUND"); + RewriteRuleSubtreeStream stream_title = new RewriteRuleSubtreeStream(adaptor,"rule title"); + RewriteRuleSubtreeStream stream_givens = new RewriteRuleSubtreeStream(adaptor,"rule givens"); + RewriteRuleSubtreeStream stream_newlineWithSpaces = new RewriteRuleSubtreeStream(adaptor,"rule newlineWithSpaces"); + try + { + // SpecFlowLang.g:77:5: ( ( WS )? T_BACKGROUND ( WS title )? newlineWithSpaces givens -> ^( BACKGROUND ( title )? givens ) ) + // SpecFlowLang.g:77:9: ( WS )? T_BACKGROUND ( WS title )? newlineWithSpaces givens + { + // SpecFlowLang.g:77:9: ( WS )? + int alt14 = 2; + int LA14_0 = input.LA(1); + + if ( (LA14_0 == WS) ) + { + alt14 = 1; + } + switch (alt14) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS23=(IToken)Match(input,WS,FOLLOW_WS_in_background571); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS23); + + + } + break; + + } + + T_BACKGROUND24=(IToken)Match(input,T_BACKGROUND,FOLLOW_T_BACKGROUND_in_background574); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_T_BACKGROUND.Add(T_BACKGROUND24); + + // SpecFlowLang.g:78:9: ( WS title )? + int alt15 = 2; + int LA15_0 = input.LA(1); + + if ( (LA15_0 == WS) ) + { + int LA15_1 = input.LA(2); + + if ( ((LA15_1 >= AT && LA15_1 <= WORDCHAR)) ) + { + alt15 = 1; + } + } + switch (alt15) + { + case 1 : + // SpecFlowLang.g:78:10: WS title + { + WS25=(IToken)Match(input,WS,FOLLOW_WS_in_background586); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS25); + + PushFollow(FOLLOW_title_in_background588); + title26 = title(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_title.Add(title26.Tree); + + } + break; + + } + + PushFollow(FOLLOW_newlineWithSpaces_in_background601); + newlineWithSpaces27 = newlineWithSpaces(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_newlineWithSpaces.Add(newlineWithSpaces27.Tree); + PushFollow(FOLLOW_givens_in_background603); + givens28 = givens(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_givens.Add(givens28.Tree); + + + // AST REWRITE + // elements: givens, title + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 80:9: -> ^( BACKGROUND ( title )? givens ) + { + // SpecFlowLang.g:80:12: ^( BACKGROUND ( title )? givens ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(BACKGROUND, "BACKGROUND"), root_1); + + // SpecFlowLang.g:80:25: ( title )? + if ( stream_title.HasNext() ) + { + adaptor.AddChild(root_1, stream_title.NextTree()); + + } + stream_title.Reset(); + adaptor.AddChild(root_1, stream_givens.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "background" + + public class scenarioKind_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "scenarioKind" + // SpecFlowLang.g:83:1: scenarioKind : ( scenarioOutline | scenario ); + public SpecFlowLangParser.scenarioKind_return scenarioKind() // throws RecognitionException [1] + { + SpecFlowLangParser.scenarioKind_return retval = new SpecFlowLangParser.scenarioKind_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + SpecFlowLangParser.scenarioOutline_return scenarioOutline29 = default(SpecFlowLangParser.scenarioOutline_return); + + SpecFlowLangParser.scenario_return scenario30 = default(SpecFlowLangParser.scenario_return); + + + + try + { + // SpecFlowLang.g:84:5: ( scenarioOutline | scenario ) + int alt16 = 2; + alt16 = dfa16.Predict(input); + switch (alt16) + { + case 1 : + // SpecFlowLang.g:84:9: scenarioOutline + { + root_0 = (object)adaptor.GetNilNode(); + + PushFollow(FOLLOW_scenarioOutline_in_scenarioKind641); + scenarioOutline29 = scenarioOutline(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( state.backtracking == 0 ) adaptor.AddChild(root_0, scenarioOutline29.Tree); + + } + break; + case 2 : + // SpecFlowLang.g:85:9: scenario + { + root_0 = (object)adaptor.GetNilNode(); + + PushFollow(FOLLOW_scenario_in_scenarioKind652); + scenario30 = scenario(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( state.backtracking == 0 ) adaptor.AddChild(root_0, scenario30.Tree); + + } + break; + + } + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "scenarioKind" + + public class scenario_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "scenario" + // SpecFlowLang.g:88:1: scenario : ( tags )? ( WS )? 'Scenario:' ( WS )? title newlineWithSpaces steps -> ^( SCENARIO ( tags )? title steps ) ; + public SpecFlowLangParser.scenario_return scenario() // throws RecognitionException [1] + { + SpecFlowLangParser.scenario_return retval = new SpecFlowLangParser.scenario_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS32 = null; + IToken string_literal33 = null; + IToken WS34 = null; + SpecFlowLangParser.tags_return tags31 = default(SpecFlowLangParser.tags_return); + + SpecFlowLangParser.title_return title35 = default(SpecFlowLangParser.title_return); + + SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces36 = default(SpecFlowLangParser.newlineWithSpaces_return); + + SpecFlowLangParser.steps_return steps37 = default(SpecFlowLangParser.steps_return); + + + object WS32_tree=null; + object string_literal33_tree=null; + object WS34_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleTokenStream stream_41 = new RewriteRuleTokenStream(adaptor,"token 41"); + RewriteRuleSubtreeStream stream_tags = new RewriteRuleSubtreeStream(adaptor,"rule tags"); + RewriteRuleSubtreeStream stream_title = new RewriteRuleSubtreeStream(adaptor,"rule title"); + RewriteRuleSubtreeStream stream_steps = new RewriteRuleSubtreeStream(adaptor,"rule steps"); + RewriteRuleSubtreeStream stream_newlineWithSpaces = new RewriteRuleSubtreeStream(adaptor,"rule newlineWithSpaces"); + try + { + // SpecFlowLang.g:89:5: ( ( tags )? ( WS )? 'Scenario:' ( WS )? title newlineWithSpaces steps -> ^( SCENARIO ( tags )? title steps ) ) + // SpecFlowLang.g:89:9: ( tags )? ( WS )? 'Scenario:' ( WS )? title newlineWithSpaces steps + { + // SpecFlowLang.g:89:9: ( tags )? + int alt17 = 2; + int LA17_0 = input.LA(1); + + if ( (LA17_0 == WS) ) + { + int LA17_1 = input.LA(2); + + if ( (LA17_1 == AT) ) + { + alt17 = 1; + } + } + else if ( (LA17_0 == AT) ) + { + alt17 = 1; + } + switch (alt17) + { + case 1 : + // SpecFlowLang.g:0:0: tags + { + PushFollow(FOLLOW_tags_in_scenario671); + tags31 = tags(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_tags.Add(tags31.Tree); + + } + break; + + } + + // SpecFlowLang.g:89:15: ( WS )? + int alt18 = 2; + int LA18_0 = input.LA(1); + + if ( (LA18_0 == WS) ) + { + alt18 = 1; + } + switch (alt18) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS32=(IToken)Match(input,WS,FOLLOW_WS_in_scenario674); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS32); + + + } + break; + + } + + string_literal33=(IToken)Match(input,41,FOLLOW_41_in_scenario677); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_41.Add(string_literal33); + + // SpecFlowLang.g:89:31: ( WS )? + int alt19 = 2; + int LA19_0 = input.LA(1); + + if ( (LA19_0 == WS) ) + { + alt19 = 1; + } + switch (alt19) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS34=(IToken)Match(input,WS,FOLLOW_WS_in_scenario679); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS34); + + + } + break; + + } + + PushFollow(FOLLOW_title_in_scenario691); + title35 = title(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_title.Add(title35.Tree); + PushFollow(FOLLOW_newlineWithSpaces_in_scenario693); + newlineWithSpaces36 = newlineWithSpaces(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_newlineWithSpaces.Add(newlineWithSpaces36.Tree); + PushFollow(FOLLOW_steps_in_scenario704); + steps37 = steps(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_steps.Add(steps37.Tree); + + + // AST REWRITE + // elements: title, steps, tags + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 92:9: -> ^( SCENARIO ( tags )? title steps ) + { + // SpecFlowLang.g:92:12: ^( SCENARIO ( tags )? title steps ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(SCENARIO, "SCENARIO"), root_1); + + // SpecFlowLang.g:92:23: ( tags )? + if ( stream_tags.HasNext() ) + { + adaptor.AddChild(root_1, stream_tags.NextTree()); + + } + stream_tags.Reset(); + adaptor.AddChild(root_1, stream_title.NextTree()); + adaptor.AddChild(root_1, stream_steps.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "scenario" + + public class scenarioOutline_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "scenarioOutline" + // SpecFlowLang.g:95:1: scenarioOutline : ( tags )? ( WS )? 'Scenario Outline:' ( WS )? title newlineWithSpaces steps examples -> ^( SCENARIOOUTLINE ( tags )? title steps examples ) ; + public SpecFlowLangParser.scenarioOutline_return scenarioOutline() // throws RecognitionException [1] + { + SpecFlowLangParser.scenarioOutline_return retval = new SpecFlowLangParser.scenarioOutline_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS39 = null; + IToken string_literal40 = null; + IToken WS41 = null; + SpecFlowLangParser.tags_return tags38 = default(SpecFlowLangParser.tags_return); + + SpecFlowLangParser.title_return title42 = default(SpecFlowLangParser.title_return); + + SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces43 = default(SpecFlowLangParser.newlineWithSpaces_return); + + SpecFlowLangParser.steps_return steps44 = default(SpecFlowLangParser.steps_return); + + SpecFlowLangParser.examples_return examples45 = default(SpecFlowLangParser.examples_return); + + + object WS39_tree=null; + object string_literal40_tree=null; + object WS41_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleTokenStream stream_42 = new RewriteRuleTokenStream(adaptor,"token 42"); + RewriteRuleSubtreeStream stream_tags = new RewriteRuleSubtreeStream(adaptor,"rule tags"); + RewriteRuleSubtreeStream stream_title = new RewriteRuleSubtreeStream(adaptor,"rule title"); + RewriteRuleSubtreeStream stream_steps = new RewriteRuleSubtreeStream(adaptor,"rule steps"); + RewriteRuleSubtreeStream stream_examples = new RewriteRuleSubtreeStream(adaptor,"rule examples"); + RewriteRuleSubtreeStream stream_newlineWithSpaces = new RewriteRuleSubtreeStream(adaptor,"rule newlineWithSpaces"); + try + { + // SpecFlowLang.g:96:5: ( ( tags )? ( WS )? 'Scenario Outline:' ( WS )? title newlineWithSpaces steps examples -> ^( SCENARIOOUTLINE ( tags )? title steps examples ) ) + // SpecFlowLang.g:97:9: ( tags )? ( WS )? 'Scenario Outline:' ( WS )? title newlineWithSpaces steps examples + { + // SpecFlowLang.g:97:9: ( tags )? + int alt20 = 2; + int LA20_0 = input.LA(1); + + if ( (LA20_0 == WS) ) + { + int LA20_1 = input.LA(2); + + if ( (LA20_1 == AT) ) + { + alt20 = 1; + } + } + else if ( (LA20_0 == AT) ) + { + alt20 = 1; + } + switch (alt20) + { + case 1 : + // SpecFlowLang.g:0:0: tags + { + PushFollow(FOLLOW_tags_in_scenarioOutline750); + tags38 = tags(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_tags.Add(tags38.Tree); + + } + break; + + } + + // SpecFlowLang.g:97:15: ( WS )? + int alt21 = 2; + int LA21_0 = input.LA(1); + + if ( (LA21_0 == WS) ) + { + alt21 = 1; + } + switch (alt21) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS39=(IToken)Match(input,WS,FOLLOW_WS_in_scenarioOutline753); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS39); + + + } + break; + + } + + string_literal40=(IToken)Match(input,42,FOLLOW_42_in_scenarioOutline756); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_42.Add(string_literal40); + + // SpecFlowLang.g:97:39: ( WS )? + int alt22 = 2; + int LA22_0 = input.LA(1); + + if ( (LA22_0 == WS) ) + { + alt22 = 1; + } + switch (alt22) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS41=(IToken)Match(input,WS,FOLLOW_WS_in_scenarioOutline758); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS41); + + + } + break; + + } + + PushFollow(FOLLOW_title_in_scenarioOutline769); + title42 = title(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_title.Add(title42.Tree); + PushFollow(FOLLOW_newlineWithSpaces_in_scenarioOutline771); + newlineWithSpaces43 = newlineWithSpaces(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_newlineWithSpaces.Add(newlineWithSpaces43.Tree); + PushFollow(FOLLOW_steps_in_scenarioOutline781); + steps44 = steps(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_steps.Add(steps44.Tree); + PushFollow(FOLLOW_examples_in_scenarioOutline791); + examples45 = examples(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_examples.Add(examples45.Tree); + + + // AST REWRITE + // elements: title, tags, steps, examples + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 101:9: -> ^( SCENARIOOUTLINE ( tags )? title steps examples ) + { + // SpecFlowLang.g:101:12: ^( SCENARIOOUTLINE ( tags )? title steps examples ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(SCENARIOOUTLINE, "SCENARIOOUTLINE"), root_1); + + // SpecFlowLang.g:101:30: ( tags )? + if ( stream_tags.HasNext() ) + { + adaptor.AddChild(root_1, stream_tags.NextTree()); + + } + stream_tags.Reset(); + adaptor.AddChild(root_1, stream_title.NextTree()); + adaptor.AddChild(root_1, stream_steps.NextTree()); + adaptor.AddChild(root_1, stream_examples.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "scenarioOutline" + + public class examples_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "examples" + // SpecFlowLang.g:104:1: examples : ( exampleSet )+ -> ^( EXAMPLES ( exampleSet )+ ) ; + public SpecFlowLangParser.examples_return examples() // throws RecognitionException [1] + { + SpecFlowLangParser.examples_return retval = new SpecFlowLangParser.examples_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + SpecFlowLangParser.exampleSet_return exampleSet46 = default(SpecFlowLangParser.exampleSet_return); + + + RewriteRuleSubtreeStream stream_exampleSet = new RewriteRuleSubtreeStream(adaptor,"rule exampleSet"); + try + { + // SpecFlowLang.g:105:5: ( ( exampleSet )+ -> ^( EXAMPLES ( exampleSet )+ ) ) + // SpecFlowLang.g:105:9: ( exampleSet )+ + { + // SpecFlowLang.g:105:9: ( exampleSet )+ + int cnt23 = 0; + do + { + int alt23 = 2; + int LA23_0 = input.LA(1); + + if ( (LA23_0 == WS) ) + { + int LA23_1 = input.LA(2); + + if ( ((LA23_1 >= 43 && LA23_1 <= 44)) ) + { + alt23 = 1; + } + + + } + else if ( ((LA23_0 >= 43 && LA23_0 <= 44)) ) + { + alt23 = 1; + } + + + switch (alt23) + { + case 1 : + // SpecFlowLang.g:0:0: exampleSet + { + PushFollow(FOLLOW_exampleSet_in_examples833); + exampleSet46 = exampleSet(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_exampleSet.Add(exampleSet46.Tree); + + } + break; + + default: + if ( cnt23 >= 1 ) goto loop23; + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + EarlyExitException eee23 = + new EarlyExitException(23, input); + throw eee23; + } + cnt23++; + } while (true); + + loop23: + ; // Stops C# compiler whinging that label 'loop23' has no statements + + + + // AST REWRITE + // elements: exampleSet + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 106:9: -> ^( EXAMPLES ( exampleSet )+ ) + { + // SpecFlowLang.g:106:12: ^( EXAMPLES ( exampleSet )+ ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(EXAMPLES, "EXAMPLES"), root_1); + + if ( !(stream_exampleSet.HasNext()) ) { + throw new RewriteEarlyExitException(); + } + while ( stream_exampleSet.HasNext() ) + { + adaptor.AddChild(root_1, stream_exampleSet.NextTree()); + + } + stream_exampleSet.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "examples" + + public class exampleSet_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "exampleSet" + // SpecFlowLang.g:109:1: exampleSet : ( WS )? ( 'Examples:' | 'Scenarios:' ) ( WS )? ( text )? newlineWithSpaces table -> ^( EXAMPLESET ( text )? table ) ; + public SpecFlowLangParser.exampleSet_return exampleSet() // throws RecognitionException [1] + { + SpecFlowLangParser.exampleSet_return retval = new SpecFlowLangParser.exampleSet_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS47 = null; + IToken string_literal48 = null; + IToken string_literal49 = null; + IToken WS50 = null; + SpecFlowLangParser.text_return text51 = default(SpecFlowLangParser.text_return); + + SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces52 = default(SpecFlowLangParser.newlineWithSpaces_return); + + SpecFlowLangParser.table_return table53 = default(SpecFlowLangParser.table_return); + + + object WS47_tree=null; + object string_literal48_tree=null; + object string_literal49_tree=null; + object WS50_tree=null; + RewriteRuleTokenStream stream_43 = new RewriteRuleTokenStream(adaptor,"token 43"); + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleTokenStream stream_44 = new RewriteRuleTokenStream(adaptor,"token 44"); + RewriteRuleSubtreeStream stream_text = new RewriteRuleSubtreeStream(adaptor,"rule text"); + RewriteRuleSubtreeStream stream_table = new RewriteRuleSubtreeStream(adaptor,"rule table"); + RewriteRuleSubtreeStream stream_newlineWithSpaces = new RewriteRuleSubtreeStream(adaptor,"rule newlineWithSpaces"); + try + { + // SpecFlowLang.g:110:5: ( ( WS )? ( 'Examples:' | 'Scenarios:' ) ( WS )? ( text )? newlineWithSpaces table -> ^( EXAMPLESET ( text )? table ) ) + // SpecFlowLang.g:110:9: ( WS )? ( 'Examples:' | 'Scenarios:' ) ( WS )? ( text )? newlineWithSpaces table + { + // SpecFlowLang.g:110:9: ( WS )? + int alt24 = 2; + int LA24_0 = input.LA(1); + + if ( (LA24_0 == WS) ) + { + alt24 = 1; + } + switch (alt24) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS47=(IToken)Match(input,WS,FOLLOW_WS_in_exampleSet870); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS47); + + + } + break; + + } + + // SpecFlowLang.g:110:13: ( 'Examples:' | 'Scenarios:' ) + int alt25 = 2; + int LA25_0 = input.LA(1); + + if ( (LA25_0 == 43) ) + { + alt25 = 1; + } + else if ( (LA25_0 == 44) ) + { + alt25 = 2; + } + else + { + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + NoViableAltException nvae_d25s0 = + new NoViableAltException("", 25, 0, input); + + throw nvae_d25s0; + } + switch (alt25) + { + case 1 : + // SpecFlowLang.g:110:14: 'Examples:' + { + string_literal48=(IToken)Match(input,43,FOLLOW_43_in_exampleSet874); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_43.Add(string_literal48); + + + } + break; + case 2 : + // SpecFlowLang.g:110:26: 'Scenarios:' + { + string_literal49=(IToken)Match(input,44,FOLLOW_44_in_exampleSet876); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_44.Add(string_literal49); + + + } + break; + + } + + // SpecFlowLang.g:110:40: ( WS )? + int alt26 = 2; + int LA26_0 = input.LA(1); + + if ( (LA26_0 == WS) ) + { + int LA26_1 = input.LA(2); + + if ( (synpred26_SpecFlowLang()) ) + { + alt26 = 1; + } + } + switch (alt26) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS50=(IToken)Match(input,WS,FOLLOW_WS_in_exampleSet879); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS50); + + + } + break; + + } + + // SpecFlowLang.g:111:9: ( text )? + int alt27 = 2; + int LA27_0 = input.LA(1); + + if ( ((LA27_0 >= AT && LA27_0 <= WORDCHAR)) ) + { + alt27 = 1; + } + switch (alt27) + { + case 1 : + // SpecFlowLang.g:0:0: text + { + PushFollow(FOLLOW_text_in_exampleSet890); + text51 = text(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_text.Add(text51.Tree); + + } + break; + + } + + PushFollow(FOLLOW_newlineWithSpaces_in_exampleSet893); + newlineWithSpaces52 = newlineWithSpaces(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_newlineWithSpaces.Add(newlineWithSpaces52.Tree); + PushFollow(FOLLOW_table_in_exampleSet895); + table53 = table(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_table.Add(table53.Tree); + + + // AST REWRITE + // elements: table, text + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 112:9: -> ^( EXAMPLESET ( text )? table ) + { + // SpecFlowLang.g:112:12: ^( EXAMPLESET ( text )? table ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(EXAMPLESET, "EXAMPLESET"), root_1); + + // SpecFlowLang.g:112:25: ( text )? + if ( stream_text.HasNext() ) + { + adaptor.AddChild(root_1, stream_text.NextTree()); + + } + stream_text.Reset(); + adaptor.AddChild(root_1, stream_table.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "exampleSet" + + public class steps_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "steps" + // SpecFlowLang.g:115:1: steps : firstStep ( nextStep )* -> ^( STEPS firstStep ( nextStep )* ) ; + public SpecFlowLangParser.steps_return steps() // throws RecognitionException [1] + { + SpecFlowLangParser.steps_return retval = new SpecFlowLangParser.steps_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + SpecFlowLangParser.firstStep_return firstStep54 = default(SpecFlowLangParser.firstStep_return); + + SpecFlowLangParser.nextStep_return nextStep55 = default(SpecFlowLangParser.nextStep_return); + + + RewriteRuleSubtreeStream stream_firstStep = new RewriteRuleSubtreeStream(adaptor,"rule firstStep"); + RewriteRuleSubtreeStream stream_nextStep = new RewriteRuleSubtreeStream(adaptor,"rule nextStep"); + try + { + // SpecFlowLang.g:116:5: ( firstStep ( nextStep )* -> ^( STEPS firstStep ( nextStep )* ) ) + // SpecFlowLang.g:116:9: firstStep ( nextStep )* + { + PushFollow(FOLLOW_firstStep_in_steps933); + firstStep54 = firstStep(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_firstStep.Add(firstStep54.Tree); + // SpecFlowLang.g:116:19: ( nextStep )* + do + { + int alt28 = 2; + int LA28_0 = input.LA(1); + + if ( (LA28_0 == WS) ) + { + int LA28_1 = input.LA(2); + + if ( ((LA28_1 >= 45 && LA28_1 <= 49)) ) + { + alt28 = 1; + } + + + } + else if ( ((LA28_0 >= 45 && LA28_0 <= 49)) ) + { + alt28 = 1; + } + + + switch (alt28) + { + case 1 : + // SpecFlowLang.g:0:0: nextStep + { + PushFollow(FOLLOW_nextStep_in_steps935); + nextStep55 = nextStep(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_nextStep.Add(nextStep55.Tree); + + } + break; + + default: + goto loop28; + } + } while (true); + + loop28: + ; // Stops C# compiler whining that label 'loop28' has no statements + + + + // AST REWRITE + // elements: nextStep, firstStep + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 117:9: -> ^( STEPS firstStep ( nextStep )* ) + { + // SpecFlowLang.g:117:12: ^( STEPS firstStep ( nextStep )* ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(STEPS, "STEPS"), root_1); + + adaptor.AddChild(root_1, stream_firstStep.NextTree()); + // SpecFlowLang.g:117:30: ( nextStep )* + while ( stream_nextStep.HasNext() ) + { + adaptor.AddChild(root_1, stream_nextStep.NextTree()); + + } + stream_nextStep.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "steps" + + public class firstStep_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "firstStep" + // SpecFlowLang.g:119:1: firstStep : ( firstGiven -> firstGiven | firstWhen -> firstWhen | firstThen -> firstThen ); + public SpecFlowLangParser.firstStep_return firstStep() // throws RecognitionException [1] + { + SpecFlowLangParser.firstStep_return retval = new SpecFlowLangParser.firstStep_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + SpecFlowLangParser.firstGiven_return firstGiven56 = default(SpecFlowLangParser.firstGiven_return); + + SpecFlowLangParser.firstWhen_return firstWhen57 = default(SpecFlowLangParser.firstWhen_return); + + SpecFlowLangParser.firstThen_return firstThen58 = default(SpecFlowLangParser.firstThen_return); + + + RewriteRuleSubtreeStream stream_firstWhen = new RewriteRuleSubtreeStream(adaptor,"rule firstWhen"); + RewriteRuleSubtreeStream stream_firstThen = new RewriteRuleSubtreeStream(adaptor,"rule firstThen"); + RewriteRuleSubtreeStream stream_firstGiven = new RewriteRuleSubtreeStream(adaptor,"rule firstGiven"); + try + { + // SpecFlowLang.g:120:2: ( firstGiven -> firstGiven | firstWhen -> firstWhen | firstThen -> firstThen ) + int alt29 = 3; + switch ( input.LA(1) ) + { + case WS: + { + switch ( input.LA(2) ) + { + case 48: + { + alt29 = 2; + } + break; + case 49: + { + alt29 = 3; + } + break; + case 47: + { + alt29 = 1; + } + break; + default: + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + NoViableAltException nvae_d29s1 = + new NoViableAltException("", 29, 1, input); + + throw nvae_d29s1; + } + + } + break; + case 47: + { + alt29 = 1; + } + break; + case 48: + { + alt29 = 2; + } + break; + case 49: + { + alt29 = 3; + } + break; + default: + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + NoViableAltException nvae_d29s0 = + new NoViableAltException("", 29, 0, input); + + throw nvae_d29s0; + } + + switch (alt29) + { + case 1 : + // SpecFlowLang.g:120:4: firstGiven + { + PushFollow(FOLLOW_firstGiven_in_firstStep968); + firstGiven56 = firstGiven(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_firstGiven.Add(firstGiven56.Tree); + + + // AST REWRITE + // elements: firstGiven + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 120:15: -> firstGiven + { + adaptor.AddChild(root_0, stream_firstGiven.NextTree()); + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + break; + case 2 : + // SpecFlowLang.g:121:4: firstWhen + { + PushFollow(FOLLOW_firstWhen_in_firstStep977); + firstWhen57 = firstWhen(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_firstWhen.Add(firstWhen57.Tree); + + + // AST REWRITE + // elements: firstWhen + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 121:14: -> firstWhen + { + adaptor.AddChild(root_0, stream_firstWhen.NextTree()); + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + break; + case 3 : + // SpecFlowLang.g:122:4: firstThen + { + PushFollow(FOLLOW_firstThen_in_firstStep986); + firstThen58 = firstThen(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_firstThen.Add(firstThen58.Tree); + + + // AST REWRITE + // elements: firstThen + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 122:14: -> firstThen + { + adaptor.AddChild(root_0, stream_firstThen.NextTree()); + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + break; + + } + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "firstStep" + + public class nextStep_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "nextStep" + // SpecFlowLang.g:124:1: nextStep : ( firstStep -> firstStep | firstAnd -> firstAnd | firstBut -> firstBut ); + public SpecFlowLangParser.nextStep_return nextStep() // throws RecognitionException [1] + { + SpecFlowLangParser.nextStep_return retval = new SpecFlowLangParser.nextStep_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + SpecFlowLangParser.firstStep_return firstStep59 = default(SpecFlowLangParser.firstStep_return); + + SpecFlowLangParser.firstAnd_return firstAnd60 = default(SpecFlowLangParser.firstAnd_return); + + SpecFlowLangParser.firstBut_return firstBut61 = default(SpecFlowLangParser.firstBut_return); + + + RewriteRuleSubtreeStream stream_firstStep = new RewriteRuleSubtreeStream(adaptor,"rule firstStep"); + RewriteRuleSubtreeStream stream_firstAnd = new RewriteRuleSubtreeStream(adaptor,"rule firstAnd"); + RewriteRuleSubtreeStream stream_firstBut = new RewriteRuleSubtreeStream(adaptor,"rule firstBut"); + try + { + // SpecFlowLang.g:125:5: ( firstStep -> firstStep | firstAnd -> firstAnd | firstBut -> firstBut ) + int alt30 = 3; + switch ( input.LA(1) ) + { + case WS: + { + switch ( input.LA(2) ) + { + case 47: + case 48: + case 49: + { + alt30 = 1; + } + break; + case 45: + { + alt30 = 2; + } + break; + case 46: + { + alt30 = 3; + } + break; + default: + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + NoViableAltException nvae_d30s1 = + new NoViableAltException("", 30, 1, input); + + throw nvae_d30s1; + } + + } + break; + case 47: + case 48: + case 49: + { + alt30 = 1; + } + break; + case 45: + { + alt30 = 2; + } + break; + case 46: + { + alt30 = 3; + } + break; + default: + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + NoViableAltException nvae_d30s0 = + new NoViableAltException("", 30, 0, input); + + throw nvae_d30s0; + } + + switch (alt30) + { + case 1 : + // SpecFlowLang.g:125:9: firstStep + { + PushFollow(FOLLOW_firstStep_in_nextStep1008); + firstStep59 = firstStep(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_firstStep.Add(firstStep59.Tree); + + + // AST REWRITE + // elements: firstStep + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 125:19: -> firstStep + { + adaptor.AddChild(root_0, stream_firstStep.NextTree()); + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + break; + case 2 : + // SpecFlowLang.g:126:4: firstAnd + { + PushFollow(FOLLOW_firstAnd_in_nextStep1017); + firstAnd60 = firstAnd(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_firstAnd.Add(firstAnd60.Tree); + + + // AST REWRITE + // elements: firstAnd + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 126:13: -> firstAnd + { + adaptor.AddChild(root_0, stream_firstAnd.NextTree()); + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + break; + case 3 : + // SpecFlowLang.g:127:4: firstBut + { + PushFollow(FOLLOW_firstBut_in_nextStep1026); + firstBut61 = firstBut(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_firstBut.Add(firstBut61.Tree); + + + // AST REWRITE + // elements: firstBut + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 127:13: -> firstBut + { + adaptor.AddChild(root_0, stream_firstBut.NextTree()); + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + break; + + } + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "nextStep" + + public class firstAnd_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "firstAnd" + // SpecFlowLang.g:130:1: firstAnd : ( WS )? 'And' WS sentenceEnd -> ^( AND sentenceEnd ) ; + public SpecFlowLangParser.firstAnd_return firstAnd() // throws RecognitionException [1] + { + SpecFlowLangParser.firstAnd_return retval = new SpecFlowLangParser.firstAnd_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS62 = null; + IToken string_literal63 = null; + IToken WS64 = null; + SpecFlowLangParser.sentenceEnd_return sentenceEnd65 = default(SpecFlowLangParser.sentenceEnd_return); + + + object WS62_tree=null; + object string_literal63_tree=null; + object WS64_tree=null; + RewriteRuleTokenStream stream_45 = new RewriteRuleTokenStream(adaptor,"token 45"); + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleSubtreeStream stream_sentenceEnd = new RewriteRuleSubtreeStream(adaptor,"rule sentenceEnd"); + try + { + // SpecFlowLang.g:131:5: ( ( WS )? 'And' WS sentenceEnd -> ^( AND sentenceEnd ) ) + // SpecFlowLang.g:131:9: ( WS )? 'And' WS sentenceEnd + { + // SpecFlowLang.g:131:9: ( WS )? + int alt31 = 2; + int LA31_0 = input.LA(1); + + if ( (LA31_0 == WS) ) + { + alt31 = 1; + } + switch (alt31) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS62=(IToken)Match(input,WS,FOLLOW_WS_in_firstAnd1049); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS62); + + + } + break; + + } + + string_literal63=(IToken)Match(input,45,FOLLOW_45_in_firstAnd1052); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_45.Add(string_literal63); + + WS64=(IToken)Match(input,WS,FOLLOW_WS_in_firstAnd1054); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS64); + + PushFollow(FOLLOW_sentenceEnd_in_firstAnd1056); + sentenceEnd65 = sentenceEnd(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_sentenceEnd.Add(sentenceEnd65.Tree); + + + // AST REWRITE + // elements: sentenceEnd + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 132:9: -> ^( AND sentenceEnd ) + { + // SpecFlowLang.g:132:12: ^( AND sentenceEnd ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(AND, "AND"), root_1); + + adaptor.AddChild(root_1, stream_sentenceEnd.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "firstAnd" + + public class firstBut_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "firstBut" + // SpecFlowLang.g:135:1: firstBut : ( WS )? 'But' WS sentenceEnd -> ^( BUT sentenceEnd ) ; + public SpecFlowLangParser.firstBut_return firstBut() // throws RecognitionException [1] + { + SpecFlowLangParser.firstBut_return retval = new SpecFlowLangParser.firstBut_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS66 = null; + IToken string_literal67 = null; + IToken WS68 = null; + SpecFlowLangParser.sentenceEnd_return sentenceEnd69 = default(SpecFlowLangParser.sentenceEnd_return); + + + object WS66_tree=null; + object string_literal67_tree=null; + object WS68_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleTokenStream stream_46 = new RewriteRuleTokenStream(adaptor,"token 46"); + RewriteRuleSubtreeStream stream_sentenceEnd = new RewriteRuleSubtreeStream(adaptor,"rule sentenceEnd"); + try + { + // SpecFlowLang.g:136:5: ( ( WS )? 'But' WS sentenceEnd -> ^( BUT sentenceEnd ) ) + // SpecFlowLang.g:136:9: ( WS )? 'But' WS sentenceEnd + { + // SpecFlowLang.g:136:9: ( WS )? + int alt32 = 2; + int LA32_0 = input.LA(1); + + if ( (LA32_0 == WS) ) + { + alt32 = 1; + } + switch (alt32) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS66=(IToken)Match(input,WS,FOLLOW_WS_in_firstBut1091); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS66); + + + } + break; + + } + + string_literal67=(IToken)Match(input,46,FOLLOW_46_in_firstBut1094); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_46.Add(string_literal67); + + WS68=(IToken)Match(input,WS,FOLLOW_WS_in_firstBut1096); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS68); + + PushFollow(FOLLOW_sentenceEnd_in_firstBut1098); + sentenceEnd69 = sentenceEnd(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_sentenceEnd.Add(sentenceEnd69.Tree); + + + // AST REWRITE + // elements: sentenceEnd + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 137:9: -> ^( BUT sentenceEnd ) + { + // SpecFlowLang.g:137:12: ^( BUT sentenceEnd ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(BUT, "BUT"), root_1); + + adaptor.AddChild(root_1, stream_sentenceEnd.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "firstBut" + + public class givens_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "givens" + // SpecFlowLang.g:140:1: givens : firstGiven ( nextStep )* -> ^( STEPS firstGiven ( nextStep )* ) ; + public SpecFlowLangParser.givens_return givens() // throws RecognitionException [1] + { + SpecFlowLangParser.givens_return retval = new SpecFlowLangParser.givens_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + SpecFlowLangParser.firstGiven_return firstGiven70 = default(SpecFlowLangParser.firstGiven_return); + + SpecFlowLangParser.nextStep_return nextStep71 = default(SpecFlowLangParser.nextStep_return); + + + RewriteRuleSubtreeStream stream_nextStep = new RewriteRuleSubtreeStream(adaptor,"rule nextStep"); + RewriteRuleSubtreeStream stream_firstGiven = new RewriteRuleSubtreeStream(adaptor,"rule firstGiven"); + try + { + // SpecFlowLang.g:141:5: ( firstGiven ( nextStep )* -> ^( STEPS firstGiven ( nextStep )* ) ) + // SpecFlowLang.g:141:9: firstGiven ( nextStep )* + { + PushFollow(FOLLOW_firstGiven_in_givens1133); + firstGiven70 = firstGiven(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_firstGiven.Add(firstGiven70.Tree); + // SpecFlowLang.g:141:20: ( nextStep )* + do + { + int alt33 = 2; + int LA33_0 = input.LA(1); + + if ( (LA33_0 == WS) ) + { + int LA33_1 = input.LA(2); + + if ( ((LA33_1 >= 45 && LA33_1 <= 49)) ) + { + alt33 = 1; + } + + + } + else if ( ((LA33_0 >= 45 && LA33_0 <= 49)) ) + { + alt33 = 1; + } + + + switch (alt33) + { + case 1 : + // SpecFlowLang.g:0:0: nextStep + { + PushFollow(FOLLOW_nextStep_in_givens1135); + nextStep71 = nextStep(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_nextStep.Add(nextStep71.Tree); + + } + break; + + default: + goto loop33; + } + } while (true); + + loop33: + ; // Stops C# compiler whining that label 'loop33' has no statements + + + + // AST REWRITE + // elements: nextStep, firstGiven + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 142:9: -> ^( STEPS firstGiven ( nextStep )* ) + { + // SpecFlowLang.g:142:12: ^( STEPS firstGiven ( nextStep )* ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(STEPS, "STEPS"), root_1); + + adaptor.AddChild(root_1, stream_firstGiven.NextTree()); + // SpecFlowLang.g:142:31: ( nextStep )* + while ( stream_nextStep.HasNext() ) + { + adaptor.AddChild(root_1, stream_nextStep.NextTree()); + + } + stream_nextStep.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "givens" + + public class firstGiven_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "firstGiven" + // SpecFlowLang.g:144:1: firstGiven : ( WS )? 'Given' WS sentenceEnd -> ^( GIVEN sentenceEnd ) ; + public SpecFlowLangParser.firstGiven_return firstGiven() // throws RecognitionException [1] + { + SpecFlowLangParser.firstGiven_return retval = new SpecFlowLangParser.firstGiven_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS72 = null; + IToken string_literal73 = null; + IToken WS74 = null; + SpecFlowLangParser.sentenceEnd_return sentenceEnd75 = default(SpecFlowLangParser.sentenceEnd_return); + + + object WS72_tree=null; + object string_literal73_tree=null; + object WS74_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleTokenStream stream_47 = new RewriteRuleTokenStream(adaptor,"token 47"); + RewriteRuleSubtreeStream stream_sentenceEnd = new RewriteRuleSubtreeStream(adaptor,"rule sentenceEnd"); + try + { + // SpecFlowLang.g:145:5: ( ( WS )? 'Given' WS sentenceEnd -> ^( GIVEN sentenceEnd ) ) + // SpecFlowLang.g:145:9: ( WS )? 'Given' WS sentenceEnd + { + // SpecFlowLang.g:145:9: ( WS )? + int alt34 = 2; + int LA34_0 = input.LA(1); + + if ( (LA34_0 == WS) ) + { + alt34 = 1; + } + switch (alt34) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS72=(IToken)Match(input,WS,FOLLOW_WS_in_firstGiven1173); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS72); + + + } + break; + + } + + string_literal73=(IToken)Match(input,47,FOLLOW_47_in_firstGiven1176); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_47.Add(string_literal73); + + WS74=(IToken)Match(input,WS,FOLLOW_WS_in_firstGiven1178); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS74); + + PushFollow(FOLLOW_sentenceEnd_in_firstGiven1180); + sentenceEnd75 = sentenceEnd(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_sentenceEnd.Add(sentenceEnd75.Tree); + + + // AST REWRITE + // elements: sentenceEnd + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 146:9: -> ^( GIVEN sentenceEnd ) + { + // SpecFlowLang.g:146:12: ^( GIVEN sentenceEnd ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(GIVEN, "GIVEN"), root_1); + + adaptor.AddChild(root_1, stream_sentenceEnd.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "firstGiven" + + public class firstWhen_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "firstWhen" + // SpecFlowLang.g:157:1: firstWhen : ( WS )? 'When' WS sentenceEnd -> ^( WHEN sentenceEnd ) ; + public SpecFlowLangParser.firstWhen_return firstWhen() // throws RecognitionException [1] + { + SpecFlowLangParser.firstWhen_return retval = new SpecFlowLangParser.firstWhen_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS76 = null; + IToken string_literal77 = null; + IToken WS78 = null; + SpecFlowLangParser.sentenceEnd_return sentenceEnd79 = default(SpecFlowLangParser.sentenceEnd_return); + + + object WS76_tree=null; + object string_literal77_tree=null; + object WS78_tree=null; + RewriteRuleTokenStream stream_48 = new RewriteRuleTokenStream(adaptor,"token 48"); + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleSubtreeStream stream_sentenceEnd = new RewriteRuleSubtreeStream(adaptor,"rule sentenceEnd"); + try + { + // SpecFlowLang.g:158:5: ( ( WS )? 'When' WS sentenceEnd -> ^( WHEN sentenceEnd ) ) + // SpecFlowLang.g:158:9: ( WS )? 'When' WS sentenceEnd + { + // SpecFlowLang.g:158:9: ( WS )? + int alt35 = 2; + int LA35_0 = input.LA(1); + + if ( (LA35_0 == WS) ) + { + alt35 = 1; + } + switch (alt35) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS76=(IToken)Match(input,WS,FOLLOW_WS_in_firstWhen1216); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS76); + + + } + break; + + } + + string_literal77=(IToken)Match(input,48,FOLLOW_48_in_firstWhen1219); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_48.Add(string_literal77); + + WS78=(IToken)Match(input,WS,FOLLOW_WS_in_firstWhen1221); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS78); + + PushFollow(FOLLOW_sentenceEnd_in_firstWhen1223); + sentenceEnd79 = sentenceEnd(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_sentenceEnd.Add(sentenceEnd79.Tree); + + + // AST REWRITE + // elements: sentenceEnd + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 159:9: -> ^( WHEN sentenceEnd ) + { + // SpecFlowLang.g:159:12: ^( WHEN sentenceEnd ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(WHEN, "WHEN"), root_1); + + adaptor.AddChild(root_1, stream_sentenceEnd.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "firstWhen" + + public class firstThen_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "firstThen" + // SpecFlowLang.g:170:1: firstThen : ( WS )? 'Then' WS sentenceEnd -> ^( THEN sentenceEnd ) ; + public SpecFlowLangParser.firstThen_return firstThen() // throws RecognitionException [1] + { + SpecFlowLangParser.firstThen_return retval = new SpecFlowLangParser.firstThen_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS80 = null; + IToken string_literal81 = null; + IToken WS82 = null; + SpecFlowLangParser.sentenceEnd_return sentenceEnd83 = default(SpecFlowLangParser.sentenceEnd_return); + + + object WS80_tree=null; + object string_literal81_tree=null; + object WS82_tree=null; + RewriteRuleTokenStream stream_49 = new RewriteRuleTokenStream(adaptor,"token 49"); + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleSubtreeStream stream_sentenceEnd = new RewriteRuleSubtreeStream(adaptor,"rule sentenceEnd"); + try + { + // SpecFlowLang.g:171:5: ( ( WS )? 'Then' WS sentenceEnd -> ^( THEN sentenceEnd ) ) + // SpecFlowLang.g:171:9: ( WS )? 'Then' WS sentenceEnd + { + // SpecFlowLang.g:171:9: ( WS )? + int alt36 = 2; + int LA36_0 = input.LA(1); + + if ( (LA36_0 == WS) ) + { + alt36 = 1; + } + switch (alt36) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS80=(IToken)Match(input,WS,FOLLOW_WS_in_firstThen1259); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS80); + + + } + break; + + } + + string_literal81=(IToken)Match(input,49,FOLLOW_49_in_firstThen1262); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_49.Add(string_literal81); + + WS82=(IToken)Match(input,WS,FOLLOW_WS_in_firstThen1264); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS82); + + PushFollow(FOLLOW_sentenceEnd_in_firstThen1266); + sentenceEnd83 = sentenceEnd(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_sentenceEnd.Add(sentenceEnd83.Tree); + + + // AST REWRITE + // elements: sentenceEnd + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 172:9: -> ^( THEN sentenceEnd ) + { + // SpecFlowLang.g:172:12: ^( THEN sentenceEnd ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(THEN, "THEN"), root_1); + + adaptor.AddChild(root_1, stream_sentenceEnd.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "firstThen" + + public class sentenceEnd_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "sentenceEnd" + // SpecFlowLang.g:190:1: sentenceEnd : text newlineWithSpaces ( multilineText )? ( table )? -> text ( multilineText )? ( table )? ; + public SpecFlowLangParser.sentenceEnd_return sentenceEnd() // throws RecognitionException [1] + { + SpecFlowLangParser.sentenceEnd_return retval = new SpecFlowLangParser.sentenceEnd_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + SpecFlowLangParser.text_return text84 = default(SpecFlowLangParser.text_return); + + SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces85 = default(SpecFlowLangParser.newlineWithSpaces_return); + + SpecFlowLangParser.multilineText_return multilineText86 = default(SpecFlowLangParser.multilineText_return); + + SpecFlowLangParser.table_return table87 = default(SpecFlowLangParser.table_return); + + + RewriteRuleSubtreeStream stream_multilineText = new RewriteRuleSubtreeStream(adaptor,"rule multilineText"); + RewriteRuleSubtreeStream stream_text = new RewriteRuleSubtreeStream(adaptor,"rule text"); + RewriteRuleSubtreeStream stream_table = new RewriteRuleSubtreeStream(adaptor,"rule table"); + RewriteRuleSubtreeStream stream_newlineWithSpaces = new RewriteRuleSubtreeStream(adaptor,"rule newlineWithSpaces"); + try + { + // SpecFlowLang.g:191:5: ( text newlineWithSpaces ( multilineText )? ( table )? -> text ( multilineText )? ( table )? ) + // SpecFlowLang.g:191:9: text newlineWithSpaces ( multilineText )? ( table )? + { + PushFollow(FOLLOW_text_in_sentenceEnd1303); + text84 = text(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_text.Add(text84.Tree); + PushFollow(FOLLOW_newlineWithSpaces_in_sentenceEnd1305); + newlineWithSpaces85 = newlineWithSpaces(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_newlineWithSpaces.Add(newlineWithSpaces85.Tree); + // SpecFlowLang.g:191:32: ( multilineText )? + int alt37 = 2; + int LA37_0 = input.LA(1); + + if ( (LA37_0 == WS) ) + { + int LA37_1 = input.LA(2); + + if ( (LA37_1 == 50) ) + { + alt37 = 1; + } + } + else if ( (LA37_0 == 50) ) + { + alt37 = 1; + } + switch (alt37) + { + case 1 : + // SpecFlowLang.g:0:0: multilineText + { + PushFollow(FOLLOW_multilineText_in_sentenceEnd1307); + multilineText86 = multilineText(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_multilineText.Add(multilineText86.Tree); + + } + break; + + } + + // SpecFlowLang.g:191:47: ( table )? + int alt38 = 2; + int LA38_0 = input.LA(1); + + if ( (LA38_0 == WS) ) + { + int LA38_1 = input.LA(2); + + if ( (LA38_1 == 51) ) + { + alt38 = 1; + } + } + else if ( (LA38_0 == 51) ) + { + alt38 = 1; + } + switch (alt38) + { + case 1 : + // SpecFlowLang.g:0:0: table + { + PushFollow(FOLLOW_table_in_sentenceEnd1310); + table87 = table(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_table.Add(table87.Tree); + + } + break; + + } + + + + // AST REWRITE + // elements: text, table, multilineText + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 192:9: -> text ( multilineText )? ( table )? + { + adaptor.AddChild(root_0, stream_text.NextTree()); + // SpecFlowLang.g:192:17: ( multilineText )? + if ( stream_multilineText.HasNext() ) + { + adaptor.AddChild(root_0, stream_multilineText.NextTree()); + + } + stream_multilineText.Reset(); + // SpecFlowLang.g:192:32: ( table )? + if ( stream_table.HasNext() ) + { + adaptor.AddChild(root_0, stream_table.NextTree()); + + } + stream_table.Reset(); + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "sentenceEnd" + + public class multilineText_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "multilineText" + // SpecFlowLang.g:195:1: multilineText : indent '\"\"\"' ( WS )? NEWLINE ( multilineTextLine )* ( WS )? '\"\"\"' ( WS )? newlineWithSpaces -> ^( MULTILINETEXT ( multilineTextLine )* indent ) ; + public SpecFlowLangParser.multilineText_return multilineText() // throws RecognitionException [1] + { + SpecFlowLangParser.multilineText_return retval = new SpecFlowLangParser.multilineText_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken string_literal89 = null; + IToken WS90 = null; + IToken NEWLINE91 = null; + IToken WS93 = null; + IToken string_literal94 = null; + IToken WS95 = null; + SpecFlowLangParser.indent_return indent88 = default(SpecFlowLangParser.indent_return); + + SpecFlowLangParser.multilineTextLine_return multilineTextLine92 = default(SpecFlowLangParser.multilineTextLine_return); + + SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces96 = default(SpecFlowLangParser.newlineWithSpaces_return); + + + object string_literal89_tree=null; + object WS90_tree=null; + object NEWLINE91_tree=null; + object WS93_tree=null; + object string_literal94_tree=null; + object WS95_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleTokenStream stream_NEWLINE = new RewriteRuleTokenStream(adaptor,"token NEWLINE"); + RewriteRuleTokenStream stream_50 = new RewriteRuleTokenStream(adaptor,"token 50"); + RewriteRuleSubtreeStream stream_multilineTextLine = new RewriteRuleSubtreeStream(adaptor,"rule multilineTextLine"); + RewriteRuleSubtreeStream stream_indent = new RewriteRuleSubtreeStream(adaptor,"rule indent"); + RewriteRuleSubtreeStream stream_newlineWithSpaces = new RewriteRuleSubtreeStream(adaptor,"rule newlineWithSpaces"); + try + { + // SpecFlowLang.g:196:5: ( indent '\"\"\"' ( WS )? NEWLINE ( multilineTextLine )* ( WS )? '\"\"\"' ( WS )? newlineWithSpaces -> ^( MULTILINETEXT ( multilineTextLine )* indent ) ) + // SpecFlowLang.g:196:9: indent '\"\"\"' ( WS )? NEWLINE ( multilineTextLine )* ( WS )? '\"\"\"' ( WS )? newlineWithSpaces + { + PushFollow(FOLLOW_indent_in_multilineText1348); + indent88 = indent(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_indent.Add(indent88.Tree); + string_literal89=(IToken)Match(input,50,FOLLOW_50_in_multilineText1350); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_50.Add(string_literal89); + + // SpecFlowLang.g:196:22: ( WS )? + int alt39 = 2; + int LA39_0 = input.LA(1); + + if ( (LA39_0 == WS) ) + { + alt39 = 1; + } + switch (alt39) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS90=(IToken)Match(input,WS,FOLLOW_WS_in_multilineText1352); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS90); + + + } + break; + + } + + NEWLINE91=(IToken)Match(input,NEWLINE,FOLLOW_NEWLINE_in_multilineText1355); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_NEWLINE.Add(NEWLINE91); + + // SpecFlowLang.g:197:9: ( multilineTextLine )* + do + { + int alt40 = 2; + int LA40_0 = input.LA(1); + + if ( (LA40_0 == WS) ) + { + int LA40_1 = input.LA(2); + + if ( ((LA40_1 >= AT && LA40_1 <= WORDCHAR) || LA40_1 == NEWLINE) ) + { + alt40 = 1; + } + + + } + else if ( ((LA40_0 >= AT && LA40_0 <= WORDCHAR) || LA40_0 == NEWLINE) ) + { + alt40 = 1; + } + + + switch (alt40) + { + case 1 : + // SpecFlowLang.g:0:0: multilineTextLine + { + PushFollow(FOLLOW_multilineTextLine_in_multilineText1365); + multilineTextLine92 = multilineTextLine(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_multilineTextLine.Add(multilineTextLine92.Tree); + + } + break; + + default: + goto loop40; + } + } while (true); + + loop40: + ; // Stops C# compiler whining that label 'loop40' has no statements + + // SpecFlowLang.g:198:9: ( WS )? + int alt41 = 2; + int LA41_0 = input.LA(1); + + if ( (LA41_0 == WS) ) + { + alt41 = 1; + } + switch (alt41) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS93=(IToken)Match(input,WS,FOLLOW_WS_in_multilineText1376); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS93); + + + } + break; + + } + + string_literal94=(IToken)Match(input,50,FOLLOW_50_in_multilineText1379); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_50.Add(string_literal94); + + // SpecFlowLang.g:198:19: ( WS )? + int alt42 = 2; + int LA42_0 = input.LA(1); + + if ( (LA42_0 == WS) ) + { + int LA42_1 = input.LA(2); + + if ( (synpred44_SpecFlowLang()) ) + { + alt42 = 1; + } + } + switch (alt42) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS95=(IToken)Match(input,WS,FOLLOW_WS_in_multilineText1381); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS95); + + + } + break; + + } + + PushFollow(FOLLOW_newlineWithSpaces_in_multilineText1384); + newlineWithSpaces96 = newlineWithSpaces(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_newlineWithSpaces.Add(newlineWithSpaces96.Tree); + + + // AST REWRITE + // elements: indent, multilineTextLine + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 199:9: -> ^( MULTILINETEXT ( multilineTextLine )* indent ) + { + // SpecFlowLang.g:199:12: ^( MULTILINETEXT ( multilineTextLine )* indent ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(MULTILINETEXT, "MULTILINETEXT"), root_1); + + // SpecFlowLang.g:199:28: ( multilineTextLine )* + while ( stream_multilineTextLine.HasNext() ) + { + adaptor.AddChild(root_1, stream_multilineTextLine.NextTree()); + + } + stream_multilineTextLine.Reset(); + adaptor.AddChild(root_1, stream_indent.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "multilineText" + + public class indent_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "indent" + // SpecFlowLang.g:202:1: indent : ( WS )? -> ^( INDENT ( WS )? ) ; + public SpecFlowLangParser.indent_return indent() // throws RecognitionException [1] + { + SpecFlowLangParser.indent_return retval = new SpecFlowLangParser.indent_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS97 = null; + + object WS97_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + + try + { + // SpecFlowLang.g:203:5: ( ( WS )? -> ^( INDENT ( WS )? ) ) + // SpecFlowLang.g:203:9: ( WS )? + { + // SpecFlowLang.g:203:9: ( WS )? + int alt43 = 2; + int LA43_0 = input.LA(1); + + if ( (LA43_0 == WS) ) + { + alt43 = 1; + } + switch (alt43) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS97=(IToken)Match(input,WS,FOLLOW_WS_in_indent1422); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS97); + + + } + break; + + } + + + + // AST REWRITE + // elements: WS + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 203:13: -> ^( INDENT ( WS )? ) + { + // SpecFlowLang.g:203:16: ^( INDENT ( WS )? ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(INDENT, "INDENT"), root_1); + + // SpecFlowLang.g:203:25: ( WS )? + if ( stream_WS.HasNext() ) + { + adaptor.AddChild(root_1, stream_WS.NextNode()); + + } + stream_WS.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "indent" + + public class multilineTextLine_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "multilineTextLine" + // SpecFlowLang.g:206:1: multilineTextLine : ( WS )? ( text )? NEWLINE -> ^( LINE ( WS )? ( text )? NEWLINE ) ; + public SpecFlowLangParser.multilineTextLine_return multilineTextLine() // throws RecognitionException [1] + { + SpecFlowLangParser.multilineTextLine_return retval = new SpecFlowLangParser.multilineTextLine_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS98 = null; + IToken NEWLINE100 = null; + SpecFlowLangParser.text_return text99 = default(SpecFlowLangParser.text_return); + + + object WS98_tree=null; + object NEWLINE100_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleTokenStream stream_NEWLINE = new RewriteRuleTokenStream(adaptor,"token NEWLINE"); + RewriteRuleSubtreeStream stream_text = new RewriteRuleSubtreeStream(adaptor,"rule text"); + try + { + // SpecFlowLang.g:207:5: ( ( WS )? ( text )? NEWLINE -> ^( LINE ( WS )? ( text )? NEWLINE ) ) + // SpecFlowLang.g:207:9: ( WS )? ( text )? NEWLINE + { + // SpecFlowLang.g:207:9: ( WS )? + int alt44 = 2; + int LA44_0 = input.LA(1); + + if ( (LA44_0 == WS) ) + { + alt44 = 1; + } + switch (alt44) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS98=(IToken)Match(input,WS,FOLLOW_WS_in_multilineTextLine1451); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS98); + + + } + break; + + } + + // SpecFlowLang.g:207:13: ( text )? + int alt45 = 2; + int LA45_0 = input.LA(1); + + if ( ((LA45_0 >= AT && LA45_0 <= WORDCHAR)) ) + { + alt45 = 1; + } + switch (alt45) + { + case 1 : + // SpecFlowLang.g:0:0: text + { + PushFollow(FOLLOW_text_in_multilineTextLine1454); + text99 = text(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_text.Add(text99.Tree); + + } + break; + + } + + NEWLINE100=(IToken)Match(input,NEWLINE,FOLLOW_NEWLINE_in_multilineTextLine1457); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_NEWLINE.Add(NEWLINE100); + + + + // AST REWRITE + // elements: NEWLINE, text, WS + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 208:9: -> ^( LINE ( WS )? ( text )? NEWLINE ) + { + // SpecFlowLang.g:208:12: ^( LINE ( WS )? ( text )? NEWLINE ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(LINE, "LINE"), root_1); + + // SpecFlowLang.g:208:19: ( WS )? + if ( stream_WS.HasNext() ) + { + adaptor.AddChild(root_1, stream_WS.NextNode()); + + } + stream_WS.Reset(); + // SpecFlowLang.g:208:23: ( text )? + if ( stream_text.HasNext() ) + { + adaptor.AddChild(root_1, stream_text.NextTree()); + + } + stream_text.Reset(); + adaptor.AddChild(root_1, stream_NEWLINE.NextNode()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "multilineTextLine" + + public class table_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "table" + // SpecFlowLang.g:211:1: table : tableRow ( tableRow )+ -> ^( TABLE ^( HEADER tableRow ) ^( BODY ( tableRow )+ ) ) ; + public SpecFlowLangParser.table_return table() // throws RecognitionException [1] + { + SpecFlowLangParser.table_return retval = new SpecFlowLangParser.table_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + SpecFlowLangParser.tableRow_return tableRow101 = default(SpecFlowLangParser.tableRow_return); + + SpecFlowLangParser.tableRow_return tableRow102 = default(SpecFlowLangParser.tableRow_return); + + + RewriteRuleSubtreeStream stream_tableRow = new RewriteRuleSubtreeStream(adaptor,"rule tableRow"); + try + { + // SpecFlowLang.g:212:5: ( tableRow ( tableRow )+ -> ^( TABLE ^( HEADER tableRow ) ^( BODY ( tableRow )+ ) ) ) + // SpecFlowLang.g:212:9: tableRow ( tableRow )+ + { + PushFollow(FOLLOW_tableRow_in_table1498); + tableRow101 = tableRow(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_tableRow.Add(tableRow101.Tree); + // SpecFlowLang.g:212:18: ( tableRow )+ + int cnt46 = 0; + do + { + int alt46 = 2; + int LA46_0 = input.LA(1); + + if ( (LA46_0 == WS) ) + { + int LA46_1 = input.LA(2); + + if ( (LA46_1 == 51) ) + { + alt46 = 1; + } + + + } + else if ( (LA46_0 == 51) ) + { + alt46 = 1; + } + + + switch (alt46) + { + case 1 : + // SpecFlowLang.g:0:0: tableRow + { + PushFollow(FOLLOW_tableRow_in_table1500); + tableRow102 = tableRow(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_tableRow.Add(tableRow102.Tree); + + } + break; + + default: + if ( cnt46 >= 1 ) goto loop46; + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + EarlyExitException eee46 = + new EarlyExitException(46, input); + throw eee46; + } + cnt46++; + } while (true); + + loop46: + ; // Stops C# compiler whinging that label 'loop46' has no statements + + + + // AST REWRITE + // elements: tableRow, tableRow + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 213:9: -> ^( TABLE ^( HEADER tableRow ) ^( BODY ( tableRow )+ ) ) + { + // SpecFlowLang.g:213:12: ^( TABLE ^( HEADER tableRow ) ^( BODY ( tableRow )+ ) ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(TABLE, "TABLE"), root_1); + + // SpecFlowLang.g:213:20: ^( HEADER tableRow ) + { + object root_2 = (object)adaptor.GetNilNode(); + root_2 = (object)adaptor.BecomeRoot((object)adaptor.Create(HEADER, "HEADER"), root_2); + + adaptor.AddChild(root_2, stream_tableRow.NextTree()); + + adaptor.AddChild(root_1, root_2); + } + // SpecFlowLang.g:213:39: ^( BODY ( tableRow )+ ) + { + object root_2 = (object)adaptor.GetNilNode(); + root_2 = (object)adaptor.BecomeRoot((object)adaptor.Create(BODY, "BODY"), root_2); + + if ( !(stream_tableRow.HasNext()) ) { + throw new RewriteEarlyExitException(); + } + while ( stream_tableRow.HasNext() ) + { + adaptor.AddChild(root_2, stream_tableRow.NextTree()); + + } + stream_tableRow.Reset(); + + adaptor.AddChild(root_1, root_2); + } + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "table" + + public class tableRow_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "tableRow" + // SpecFlowLang.g:216:1: tableRow : ( WS )? '|' ( tableCell )+ ( WS )? newlineWithSpaces -> ^( ROW ( tableCell )+ ) ; + public SpecFlowLangParser.tableRow_return tableRow() // throws RecognitionException [1] + { + SpecFlowLangParser.tableRow_return retval = new SpecFlowLangParser.tableRow_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS103 = null; + IToken char_literal104 = null; + IToken WS106 = null; + SpecFlowLangParser.tableCell_return tableCell105 = default(SpecFlowLangParser.tableCell_return); + + SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces107 = default(SpecFlowLangParser.newlineWithSpaces_return); + + + object WS103_tree=null; + object char_literal104_tree=null; + object WS106_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleTokenStream stream_51 = new RewriteRuleTokenStream(adaptor,"token 51"); + RewriteRuleSubtreeStream stream_tableCell = new RewriteRuleSubtreeStream(adaptor,"rule tableCell"); + RewriteRuleSubtreeStream stream_newlineWithSpaces = new RewriteRuleSubtreeStream(adaptor,"rule newlineWithSpaces"); + try + { + // SpecFlowLang.g:217:5: ( ( WS )? '|' ( tableCell )+ ( WS )? newlineWithSpaces -> ^( ROW ( tableCell )+ ) ) + // SpecFlowLang.g:217:9: ( WS )? '|' ( tableCell )+ ( WS )? newlineWithSpaces + { + // SpecFlowLang.g:217:9: ( WS )? + int alt47 = 2; + int LA47_0 = input.LA(1); + + if ( (LA47_0 == WS) ) + { + alt47 = 1; + } + switch (alt47) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS103=(IToken)Match(input,WS,FOLLOW_WS_in_tableRow1547); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS103); + + + } + break; + + } + + char_literal104=(IToken)Match(input,51,FOLLOW_51_in_tableRow1550); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_51.Add(char_literal104); + + // SpecFlowLang.g:217:17: ( tableCell )+ + int cnt48 = 0; + do + { + int alt48 = 2; + int LA48_0 = input.LA(1); + + if ( (LA48_0 == WS) ) + { + int LA48_1 = input.LA(2); + + if ( ((LA48_1 >= AT && LA48_1 <= WORDCHAR)) ) + { + alt48 = 1; + } + + + } + else if ( ((LA48_0 >= AT && LA48_0 <= WORDCHAR)) ) + { + alt48 = 1; + } + + + switch (alt48) + { + case 1 : + // SpecFlowLang.g:0:0: tableCell + { + PushFollow(FOLLOW_tableCell_in_tableRow1552); + tableCell105 = tableCell(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_tableCell.Add(tableCell105.Tree); + + } + break; + + default: + if ( cnt48 >= 1 ) goto loop48; + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + EarlyExitException eee48 = + new EarlyExitException(48, input); + throw eee48; + } + cnt48++; + } while (true); + + loop48: + ; // Stops C# compiler whinging that label 'loop48' has no statements + + // SpecFlowLang.g:217:28: ( WS )? + int alt49 = 2; + int LA49_0 = input.LA(1); + + if ( (LA49_0 == WS) ) + { + int LA49_1 = input.LA(2); + + if ( (synpred51_SpecFlowLang()) ) + { + alt49 = 1; + } + } + switch (alt49) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS106=(IToken)Match(input,WS,FOLLOW_WS_in_tableRow1555); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS106); + + + } + break; + + } + + PushFollow(FOLLOW_newlineWithSpaces_in_tableRow1558); + newlineWithSpaces107 = newlineWithSpaces(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_newlineWithSpaces.Add(newlineWithSpaces107.Tree); + + + // AST REWRITE + // elements: tableCell + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 218:9: -> ^( ROW ( tableCell )+ ) + { + // SpecFlowLang.g:218:12: ^( ROW ( tableCell )+ ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(ROW, "ROW"), root_1); + + if ( !(stream_tableCell.HasNext()) ) { + throw new RewriteEarlyExitException(); + } + while ( stream_tableCell.HasNext() ) + { + adaptor.AddChild(root_1, stream_tableCell.NextTree()); + + } + stream_tableCell.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "tableRow" + + public class tableCell_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "tableCell" + // SpecFlowLang.g:221:1: tableCell : ( WS )? text ( WS )? '|' -> ^( CELL text ) ; + public SpecFlowLangParser.tableCell_return tableCell() // throws RecognitionException [1] + { + SpecFlowLangParser.tableCell_return retval = new SpecFlowLangParser.tableCell_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS108 = null; + IToken WS110 = null; + IToken char_literal111 = null; + SpecFlowLangParser.text_return text109 = default(SpecFlowLangParser.text_return); + + + object WS108_tree=null; + object WS110_tree=null; + object char_literal111_tree=null; + RewriteRuleTokenStream stream_WS = new RewriteRuleTokenStream(adaptor,"token WS"); + RewriteRuleTokenStream stream_51 = new RewriteRuleTokenStream(adaptor,"token 51"); + RewriteRuleSubtreeStream stream_text = new RewriteRuleSubtreeStream(adaptor,"rule text"); + try + { + // SpecFlowLang.g:222:5: ( ( WS )? text ( WS )? '|' -> ^( CELL text ) ) + // SpecFlowLang.g:222:9: ( WS )? text ( WS )? '|' + { + // SpecFlowLang.g:222:9: ( WS )? + int alt50 = 2; + int LA50_0 = input.LA(1); + + if ( (LA50_0 == WS) ) + { + alt50 = 1; + } + switch (alt50) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS108=(IToken)Match(input,WS,FOLLOW_WS_in_tableCell1594); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS108); + + + } + break; + + } + + PushFollow(FOLLOW_text_in_tableCell1597); + text109 = text(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_text.Add(text109.Tree); + // SpecFlowLang.g:222:18: ( WS )? + int alt51 = 2; + int LA51_0 = input.LA(1); + + if ( (LA51_0 == WS) ) + { + alt51 = 1; + } + switch (alt51) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS110=(IToken)Match(input,WS,FOLLOW_WS_in_tableCell1599); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WS.Add(WS110); + + + } + break; + + } + + char_literal111=(IToken)Match(input,51,FOLLOW_51_in_tableCell1602); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_51.Add(char_literal111); + + + + // AST REWRITE + // elements: text + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 223:9: -> ^( CELL text ) + { + // SpecFlowLang.g:223:12: ^( CELL text ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(CELL, "CELL"), root_1); + + adaptor.AddChild(root_1, stream_text.NextTree()); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "tableCell" + + public class descriptionLineText_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "descriptionLineText" + // SpecFlowLang.g:226:1: descriptionLineText : WORDCHAR ( textRest )* -> ^( TEXT WORDCHAR ( textRest )* ) ; + public SpecFlowLangParser.descriptionLineText_return descriptionLineText() // throws RecognitionException [1] + { + SpecFlowLangParser.descriptionLineText_return retval = new SpecFlowLangParser.descriptionLineText_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WORDCHAR112 = null; + SpecFlowLangParser.textRest_return textRest113 = default(SpecFlowLangParser.textRest_return); + + + object WORDCHAR112_tree=null; + RewriteRuleTokenStream stream_WORDCHAR = new RewriteRuleTokenStream(adaptor,"token WORDCHAR"); + RewriteRuleSubtreeStream stream_textRest = new RewriteRuleSubtreeStream(adaptor,"rule textRest"); + try + { + // SpecFlowLang.g:227:5: ( WORDCHAR ( textRest )* -> ^( TEXT WORDCHAR ( textRest )* ) ) + // SpecFlowLang.g:227:9: WORDCHAR ( textRest )* + { + WORDCHAR112=(IToken)Match(input,WORDCHAR,FOLLOW_WORDCHAR_in_descriptionLineText1637); if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_WORDCHAR.Add(WORDCHAR112); + + // SpecFlowLang.g:227:18: ( textRest )* + do + { + int alt52 = 2; + int LA52_0 = input.LA(1); + + if ( (LA52_0 == WS) ) + { + int LA52_1 = input.LA(2); + + if ( ((LA52_1 >= WS && LA52_1 <= WORDCHAR)) ) + { + alt52 = 1; + } + + + } + else if ( ((LA52_0 >= AT && LA52_0 <= WORDCHAR)) ) + { + alt52 = 1; + } + + + switch (alt52) + { + case 1 : + // SpecFlowLang.g:0:0: textRest + { + PushFollow(FOLLOW_textRest_in_descriptionLineText1639); + textRest113 = textRest(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_textRest.Add(textRest113.Tree); + + } + break; + + default: + goto loop52; + } + } while (true); + + loop52: + ; // Stops C# compiler whining that label 'loop52' has no statements + + + + // AST REWRITE + // elements: textRest, WORDCHAR + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 228:9: -> ^( TEXT WORDCHAR ( textRest )* ) + { + // SpecFlowLang.g:228:12: ^( TEXT WORDCHAR ( textRest )* ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(TEXT, "TEXT"), root_1); + + adaptor.AddChild(root_1, stream_WORDCHAR.NextNode()); + // SpecFlowLang.g:228:28: ( textRest )* + while ( stream_textRest.HasNext() ) + { + adaptor.AddChild(root_1, stream_textRest.NextTree()); + + } + stream_textRest.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "descriptionLineText" + + public class text_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "text" + // SpecFlowLang.g:231:1: text : wordchar ( textRest )* -> ^( TEXT wordchar ( textRest )* ) ; + public SpecFlowLangParser.text_return text() // throws RecognitionException [1] + { + SpecFlowLangParser.text_return retval = new SpecFlowLangParser.text_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + SpecFlowLangParser.wordchar_return wordchar114 = default(SpecFlowLangParser.wordchar_return); + + SpecFlowLangParser.textRest_return textRest115 = default(SpecFlowLangParser.textRest_return); + + + RewriteRuleSubtreeStream stream_textRest = new RewriteRuleSubtreeStream(adaptor,"rule textRest"); + RewriteRuleSubtreeStream stream_wordchar = new RewriteRuleSubtreeStream(adaptor,"rule wordchar"); + try + { + // SpecFlowLang.g:232:5: ( wordchar ( textRest )* -> ^( TEXT wordchar ( textRest )* ) ) + // SpecFlowLang.g:232:9: wordchar ( textRest )* + { + PushFollow(FOLLOW_wordchar_in_text1678); + wordchar114 = wordchar(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_wordchar.Add(wordchar114.Tree); + // SpecFlowLang.g:232:18: ( textRest )* + do + { + int alt53 = 2; + int LA53_0 = input.LA(1); + + if ( (LA53_0 == WS) ) + { + int LA53_1 = input.LA(2); + + if ( ((LA53_1 >= WS && LA53_1 <= WORDCHAR)) ) + { + alt53 = 1; + } + + + } + else if ( ((LA53_0 >= AT && LA53_0 <= WORDCHAR)) ) + { + alt53 = 1; + } + + + switch (alt53) + { + case 1 : + // SpecFlowLang.g:0:0: textRest + { + PushFollow(FOLLOW_textRest_in_text1680); + textRest115 = textRest(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_textRest.Add(textRest115.Tree); + + } + break; + + default: + goto loop53; + } + } while (true); + + loop53: + ; // Stops C# compiler whining that label 'loop53' has no statements + + + + // AST REWRITE + // elements: wordchar, textRest + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 233:9: -> ^( TEXT wordchar ( textRest )* ) + { + // SpecFlowLang.g:233:12: ^( TEXT wordchar ( textRest )* ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(TEXT, "TEXT"), root_1); + + adaptor.AddChild(root_1, stream_wordchar.NextTree()); + // SpecFlowLang.g:233:28: ( textRest )* + while ( stream_textRest.HasNext() ) + { + adaptor.AddChild(root_1, stream_textRest.NextTree()); + + } + stream_textRest.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "text" + + public class textRest_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "textRest" + // SpecFlowLang.g:235:1: textRest : ( WS textRest | wordchar ); + public SpecFlowLangParser.textRest_return textRest() // throws RecognitionException [1] + { + SpecFlowLangParser.textRest_return retval = new SpecFlowLangParser.textRest_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS116 = null; + SpecFlowLangParser.textRest_return textRest117 = default(SpecFlowLangParser.textRest_return); + + SpecFlowLangParser.wordchar_return wordchar118 = default(SpecFlowLangParser.wordchar_return); + + + object WS116_tree=null; + + try + { + // SpecFlowLang.g:236:5: ( WS textRest | wordchar ) + int alt54 = 2; + int LA54_0 = input.LA(1); + + if ( (LA54_0 == WS) ) + { + alt54 = 1; + } + else if ( ((LA54_0 >= AT && LA54_0 <= WORDCHAR)) ) + { + alt54 = 2; + } + else + { + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + NoViableAltException nvae_d54s0 = + new NoViableAltException("", 54, 0, input); + + throw nvae_d54s0; + } + switch (alt54) + { + case 1 : + // SpecFlowLang.g:236:9: WS textRest + { + root_0 = (object)adaptor.GetNilNode(); + + WS116=(IToken)Match(input,WS,FOLLOW_WS_in_textRest1718); if (state.failed) return retval; + if ( state.backtracking == 0 ) + {WS116_tree = (object)adaptor.Create(WS116); + adaptor.AddChild(root_0, WS116_tree); + } + PushFollow(FOLLOW_textRest_in_textRest1720); + textRest117 = textRest(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( state.backtracking == 0 ) adaptor.AddChild(root_0, textRest117.Tree); + + } + break; + case 2 : + // SpecFlowLang.g:237:9: wordchar + { + root_0 = (object)adaptor.GetNilNode(); + + PushFollow(FOLLOW_wordchar_in_textRest1730); + wordchar118 = wordchar(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( state.backtracking == 0 ) adaptor.AddChild(root_0, wordchar118.Tree); + + } + break; + + } + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "textRest" + + public class title_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "title" + // SpecFlowLang.g:240:1: title : wordchar ( titleRest )* -> ^( TEXT wordchar ( titleRest )* ) ; + public SpecFlowLangParser.title_return title() // throws RecognitionException [1] + { + SpecFlowLangParser.title_return retval = new SpecFlowLangParser.title_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + SpecFlowLangParser.wordchar_return wordchar119 = default(SpecFlowLangParser.wordchar_return); + + SpecFlowLangParser.titleRest_return titleRest120 = default(SpecFlowLangParser.titleRest_return); + + + RewriteRuleSubtreeStream stream_wordchar = new RewriteRuleSubtreeStream(adaptor,"rule wordchar"); + RewriteRuleSubtreeStream stream_titleRest = new RewriteRuleSubtreeStream(adaptor,"rule titleRest"); + try + { + // SpecFlowLang.g:241:5: ( wordchar ( titleRest )* -> ^( TEXT wordchar ( titleRest )* ) ) + // SpecFlowLang.g:241:9: wordchar ( titleRest )* + { + PushFollow(FOLLOW_wordchar_in_title1749); + wordchar119 = wordchar(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_wordchar.Add(wordchar119.Tree); + // SpecFlowLang.g:241:18: ( titleRest )* + do + { + int alt55 = 2; + alt55 = dfa55.Predict(input); + switch (alt55) + { + case 1 : + // SpecFlowLang.g:0:0: titleRest + { + PushFollow(FOLLOW_titleRest_in_title1751); + titleRest120 = titleRest(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( (state.backtracking==0) ) stream_titleRest.Add(titleRest120.Tree); + + } + break; + + default: + goto loop55; + } + } while (true); + + loop55: + ; // Stops C# compiler whining that label 'loop55' has no statements + + + + // AST REWRITE + // elements: titleRest, wordchar + // token labels: + // rule labels: retval + // token list labels: + // rule list labels: + // wildcard labels: + if ( (state.backtracking==0) ) { + retval.Tree = root_0; + RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); + + root_0 = (object)adaptor.GetNilNode(); + // 242:9: -> ^( TEXT wordchar ( titleRest )* ) + { + // SpecFlowLang.g:242:12: ^( TEXT wordchar ( titleRest )* ) + { + object root_1 = (object)adaptor.GetNilNode(); + root_1 = (object)adaptor.BecomeRoot((object)adaptor.Create(TEXT, "TEXT"), root_1); + + adaptor.AddChild(root_1, stream_wordchar.NextTree()); + // SpecFlowLang.g:242:28: ( titleRest )* + while ( stream_titleRest.HasNext() ) + { + adaptor.AddChild(root_1, stream_titleRest.NextTree()); + + } + stream_titleRest.Reset(); + + adaptor.AddChild(root_0, root_1); + } + + } + + retval.Tree = root_0;retval.Tree = root_0;} + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "title" + + public class titleRest_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "titleRest" + // SpecFlowLang.g:245:1: titleRest : ( WS titleRest | NEWLINE titleRest | wordchar ); + public SpecFlowLangParser.titleRest_return titleRest() // throws RecognitionException [1] + { + SpecFlowLangParser.titleRest_return retval = new SpecFlowLangParser.titleRest_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS121 = null; + IToken NEWLINE123 = null; + SpecFlowLangParser.titleRest_return titleRest122 = default(SpecFlowLangParser.titleRest_return); + + SpecFlowLangParser.titleRest_return titleRest124 = default(SpecFlowLangParser.titleRest_return); + + SpecFlowLangParser.wordchar_return wordchar125 = default(SpecFlowLangParser.wordchar_return); + + + object WS121_tree=null; + object NEWLINE123_tree=null; + + try + { + // SpecFlowLang.g:246:5: ( WS titleRest | NEWLINE titleRest | wordchar ) + int alt56 = 3; + switch ( input.LA(1) ) + { + case WS: + { + alt56 = 1; + } + break; + case NEWLINE: + { + alt56 = 2; + } + break; + case AT: + case WORDCHAR: + { + alt56 = 3; + } + break; + default: + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + NoViableAltException nvae_d56s0 = + new NoViableAltException("", 56, 0, input); + + throw nvae_d56s0; + } + + switch (alt56) + { + case 1 : + // SpecFlowLang.g:246:9: WS titleRest + { + root_0 = (object)adaptor.GetNilNode(); + + WS121=(IToken)Match(input,WS,FOLLOW_WS_in_titleRest1790); if (state.failed) return retval; + if ( state.backtracking == 0 ) + {WS121_tree = (object)adaptor.Create(WS121); + adaptor.AddChild(root_0, WS121_tree); + } + PushFollow(FOLLOW_titleRest_in_titleRest1792); + titleRest122 = titleRest(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( state.backtracking == 0 ) adaptor.AddChild(root_0, titleRest122.Tree); + + } + break; + case 2 : + // SpecFlowLang.g:247:9: NEWLINE titleRest + { + root_0 = (object)adaptor.GetNilNode(); + + NEWLINE123=(IToken)Match(input,NEWLINE,FOLLOW_NEWLINE_in_titleRest1802); if (state.failed) return retval; + if ( state.backtracking == 0 ) + {NEWLINE123_tree = (object)adaptor.Create(NEWLINE123); + adaptor.AddChild(root_0, NEWLINE123_tree); + } + PushFollow(FOLLOW_titleRest_in_titleRest1804); + titleRest124 = titleRest(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( state.backtracking == 0 ) adaptor.AddChild(root_0, titleRest124.Tree); + + } + break; + case 3 : + // SpecFlowLang.g:248:9: wordchar + { + root_0 = (object)adaptor.GetNilNode(); + + PushFollow(FOLLOW_wordchar_in_titleRest1814); + wordchar125 = wordchar(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( state.backtracking == 0 ) adaptor.AddChild(root_0, wordchar125.Tree); + + } + break; + + } + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "titleRest" + + public class titleRestLine_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "titleRestLine" + // SpecFlowLang.g:251:1: titleRestLine : ( NEWLINE titleRestLine | WS titleRestLine | WORDCHAR ); + public SpecFlowLangParser.titleRestLine_return titleRestLine() // throws RecognitionException [1] + { + SpecFlowLangParser.titleRestLine_return retval = new SpecFlowLangParser.titleRestLine_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken NEWLINE126 = null; + IToken WS128 = null; + IToken WORDCHAR130 = null; + SpecFlowLangParser.titleRestLine_return titleRestLine127 = default(SpecFlowLangParser.titleRestLine_return); + + SpecFlowLangParser.titleRestLine_return titleRestLine129 = default(SpecFlowLangParser.titleRestLine_return); + + + object NEWLINE126_tree=null; + object WS128_tree=null; + object WORDCHAR130_tree=null; + + try + { + // SpecFlowLang.g:252:5: ( NEWLINE titleRestLine | WS titleRestLine | WORDCHAR ) + int alt57 = 3; + switch ( input.LA(1) ) + { + case NEWLINE: + { + alt57 = 1; + } + break; + case WS: + { + alt57 = 2; + } + break; + case WORDCHAR: + { + alt57 = 3; + } + break; + default: + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + NoViableAltException nvae_d57s0 = + new NoViableAltException("", 57, 0, input); + + throw nvae_d57s0; + } + + switch (alt57) + { + case 1 : + // SpecFlowLang.g:252:9: NEWLINE titleRestLine + { + root_0 = (object)adaptor.GetNilNode(); + + NEWLINE126=(IToken)Match(input,NEWLINE,FOLLOW_NEWLINE_in_titleRestLine1833); if (state.failed) return retval; + if ( state.backtracking == 0 ) + {NEWLINE126_tree = (object)adaptor.Create(NEWLINE126); + adaptor.AddChild(root_0, NEWLINE126_tree); + } + PushFollow(FOLLOW_titleRestLine_in_titleRestLine1835); + titleRestLine127 = titleRestLine(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( state.backtracking == 0 ) adaptor.AddChild(root_0, titleRestLine127.Tree); + + } + break; + case 2 : + // SpecFlowLang.g:253:9: WS titleRestLine + { + root_0 = (object)adaptor.GetNilNode(); + + WS128=(IToken)Match(input,WS,FOLLOW_WS_in_titleRestLine1845); if (state.failed) return retval; + if ( state.backtracking == 0 ) + {WS128_tree = (object)adaptor.Create(WS128); + adaptor.AddChild(root_0, WS128_tree); + } + PushFollow(FOLLOW_titleRestLine_in_titleRestLine1847); + titleRestLine129 = titleRestLine(); + state.followingStackPointer--; + if (state.failed) return retval; + if ( state.backtracking == 0 ) adaptor.AddChild(root_0, titleRestLine129.Tree); + + } + break; + case 3 : + // SpecFlowLang.g:254:9: WORDCHAR + { + root_0 = (object)adaptor.GetNilNode(); + + WORDCHAR130=(IToken)Match(input,WORDCHAR,FOLLOW_WORDCHAR_in_titleRestLine1857); if (state.failed) return retval; + if ( state.backtracking == 0 ) + {WORDCHAR130_tree = (object)adaptor.Create(WORDCHAR130); + adaptor.AddChild(root_0, WORDCHAR130_tree); + } + + } + break; + + } + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "titleRestLine" + + public class wordchar_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "wordchar" + // SpecFlowLang.g:257:1: wordchar : ( WORDCHAR | AT ); + public SpecFlowLangParser.wordchar_return wordchar() // throws RecognitionException [1] + { + SpecFlowLangParser.wordchar_return retval = new SpecFlowLangParser.wordchar_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken set131 = null; + + object set131_tree=null; + + try + { + // SpecFlowLang.g:258:5: ( WORDCHAR | AT ) + // SpecFlowLang.g: + { + root_0 = (object)adaptor.GetNilNode(); + + set131 = (IToken)input.LT(1); + if ( (input.LA(1) >= AT && input.LA(1) <= WORDCHAR) ) + { + input.Consume(); + if ( state.backtracking == 0 ) adaptor.AddChild(root_0, (object)adaptor.Create(set131)); + state.errorRecovery = false;state.failed = false; + } + else + { + if ( state.backtracking > 0 ) {state.failed = true; return retval;} + MismatchedSetException mse = new MismatchedSetException(null,input); + throw mse; + } + + + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "wordchar" + + public class newlineWithSpaces_return : ParserRuleReturnScope + { + private object tree; + override public object Tree + { + get { return tree; } + set { tree = (object) value; } + } + }; + + // $ANTLR start "newlineWithSpaces" + // SpecFlowLang.g:262:1: newlineWithSpaces : ( WS )? NEWLINE ( ( WS )? NEWLINE )* ; + public SpecFlowLangParser.newlineWithSpaces_return newlineWithSpaces() // throws RecognitionException [1] + { + SpecFlowLangParser.newlineWithSpaces_return retval = new SpecFlowLangParser.newlineWithSpaces_return(); + retval.Start = input.LT(1); + + object root_0 = null; + + IToken WS132 = null; + IToken NEWLINE133 = null; + IToken WS134 = null; + IToken NEWLINE135 = null; + + object WS132_tree=null; + object NEWLINE133_tree=null; + object WS134_tree=null; + object NEWLINE135_tree=null; + + try + { + // SpecFlowLang.g:263:5: ( ( WS )? NEWLINE ( ( WS )? NEWLINE )* ) + // SpecFlowLang.g:263:9: ( WS )? NEWLINE ( ( WS )? NEWLINE )* + { + root_0 = (object)adaptor.GetNilNode(); + + // SpecFlowLang.g:263:9: ( WS )? + int alt58 = 2; + int LA58_0 = input.LA(1); + + if ( (LA58_0 == WS) ) + { + alt58 = 1; + } + switch (alt58) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS132=(IToken)Match(input,WS,FOLLOW_WS_in_newlineWithSpaces1905); if (state.failed) return retval; + if ( state.backtracking == 0 ) + {WS132_tree = (object)adaptor.Create(WS132); + adaptor.AddChild(root_0, WS132_tree); + } + + } + break; + + } + + NEWLINE133=(IToken)Match(input,NEWLINE,FOLLOW_NEWLINE_in_newlineWithSpaces1908); if (state.failed) return retval; + if ( state.backtracking == 0 ) + {NEWLINE133_tree = (object)adaptor.Create(NEWLINE133); + adaptor.AddChild(root_0, NEWLINE133_tree); + } + // SpecFlowLang.g:263:21: ( ( WS )? NEWLINE )* + do + { + int alt60 = 2; + int LA60_0 = input.LA(1); + + if ( (LA60_0 == WS) ) + { + int LA60_1 = input.LA(2); + + if ( (LA60_1 == NEWLINE) ) + { + alt60 = 1; + } + + + } + else if ( (LA60_0 == NEWLINE) ) + { + alt60 = 1; + } + + + switch (alt60) + { + case 1 : + // SpecFlowLang.g:263:22: ( WS )? NEWLINE + { + // SpecFlowLang.g:263:22: ( WS )? + int alt59 = 2; + int LA59_0 = input.LA(1); + + if ( (LA59_0 == WS) ) + { + alt59 = 1; + } + switch (alt59) + { + case 1 : + // SpecFlowLang.g:0:0: WS + { + WS134=(IToken)Match(input,WS,FOLLOW_WS_in_newlineWithSpaces1911); if (state.failed) return retval; + if ( state.backtracking == 0 ) + {WS134_tree = (object)adaptor.Create(WS134); + adaptor.AddChild(root_0, WS134_tree); + } + + } + break; + + } + + NEWLINE135=(IToken)Match(input,NEWLINE,FOLLOW_NEWLINE_in_newlineWithSpaces1914); if (state.failed) return retval; + if ( state.backtracking == 0 ) + {NEWLINE135_tree = (object)adaptor.Create(NEWLINE135); + adaptor.AddChild(root_0, NEWLINE135_tree); + } + + } + break; + + default: + goto loop60; + } + } while (true); + + loop60: + ; // Stops C# compiler whining that label 'loop60' has no statements + + + } + + retval.Stop = input.LT(-1); + + if ( (state.backtracking==0) ) + { retval.Tree = (object)adaptor.RulePostProcessing(root_0); + adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + // Conversion of the second argument necessary, but harmless + retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); + + } + finally + { + } + return retval; + } + // $ANTLR end "newlineWithSpaces" + + // $ANTLR start "synpred26_SpecFlowLang" + public void synpred26_SpecFlowLang_fragment() { + // SpecFlowLang.g:110:40: ( WS ) + // SpecFlowLang.g:110:40: WS + { + Match(input,WS,FOLLOW_WS_in_synpred26_SpecFlowLang879); if (state.failed) return ; + + } + } + // $ANTLR end "synpred26_SpecFlowLang" + + // $ANTLR start "synpred44_SpecFlowLang" + public void synpred44_SpecFlowLang_fragment() { + // SpecFlowLang.g:198:19: ( WS ) + // SpecFlowLang.g:198:19: WS + { + Match(input,WS,FOLLOW_WS_in_synpred44_SpecFlowLang1381); if (state.failed) return ; + + } + } + // $ANTLR end "synpred44_SpecFlowLang" + + // $ANTLR start "synpred51_SpecFlowLang" + public void synpred51_SpecFlowLang_fragment() { + // SpecFlowLang.g:217:28: ( WS ) + // SpecFlowLang.g:217:28: WS + { + Match(input,WS,FOLLOW_WS_in_synpred51_SpecFlowLang1555); if (state.failed) return ; + + } + } + // $ANTLR end "synpred51_SpecFlowLang" + + // $ANTLR start "synpred57_SpecFlowLang" + public void synpred57_SpecFlowLang_fragment() { + // SpecFlowLang.g:241:18: ( titleRest ) + // SpecFlowLang.g:241:18: titleRest + { + PushFollow(FOLLOW_titleRest_in_synpred57_SpecFlowLang1751); + titleRest(); + state.followingStackPointer--; + if (state.failed) return ; + + } + } + // $ANTLR end "synpred57_SpecFlowLang" + + // Delegated rules + + public bool synpred51_SpecFlowLang() + { + state.backtracking++; + int start = input.Mark(); + try + { + synpred51_SpecFlowLang_fragment(); // can never throw exception + } + catch (RecognitionException re) + { + Console.Error.WriteLine("impossible: "+re); + } + bool success = !state.failed; + input.Rewind(start); + state.backtracking--; + state.failed = false; + return success; + } + public bool synpred44_SpecFlowLang() + { + state.backtracking++; + int start = input.Mark(); + try + { + synpred44_SpecFlowLang_fragment(); // can never throw exception + } + catch (RecognitionException re) + { + Console.Error.WriteLine("impossible: "+re); + } + bool success = !state.failed; + input.Rewind(start); + state.backtracking--; + state.failed = false; + return success; + } + public bool synpred26_SpecFlowLang() + { + state.backtracking++; + int start = input.Mark(); + try + { + synpred26_SpecFlowLang_fragment(); // can never throw exception + } + catch (RecognitionException re) + { + Console.Error.WriteLine("impossible: "+re); + } + bool success = !state.failed; + input.Rewind(start); + state.backtracking--; + state.failed = false; + return success; + } + public bool synpred57_SpecFlowLang() + { + state.backtracking++; + int start = input.Mark(); + try + { + synpred57_SpecFlowLang_fragment(); // can never throw exception + } + catch (RecognitionException re) + { + Console.Error.WriteLine("impossible: "+re); + } + bool success = !state.failed; + input.Rewind(start); + state.backtracking--; + state.failed = false; + return success; + } + + + protected DFA16 dfa16; + protected DFA55 dfa55; + private void InitializeCyclicDFAs() + { + this.dfa16 = new DFA16(this); + this.dfa55 = new DFA55(this); + + this.dfa55.specialStateTransitionHandler = new DFA.SpecialStateTransitionHandler(DFA55_SpecialStateTransition); + } + + const string DFA16_eotS = + "\x0b\uffff"; + const string DFA16_eofS = + "\x0b\uffff"; + const string DFA16_minS = + "\x01\x1e\x01\x1f\x01\x20\x02\uffff\x03\x1e\x01\x29\x01\x22\x01"+ + "\x1e"; + const string DFA16_maxS = + "\x02\x2a\x01\x20\x02\uffff\x01\x22\x05\x2a"; + const string DFA16_acceptS = + "\x03\uffff\x01\x01\x01\x02\x06\uffff"; + const string DFA16_specialS = + "\x0b\uffff}>"; + static readonly string[] DFA16_transitionS = { + "\x01\x01\x01\x02\x09\uffff\x01\x04\x01\x03", + "\x01\x02\x09\uffff\x01\x04\x01\x03", + "\x01\x05", + "", + "", + "\x01\x06\x01\uffff\x01\x05\x01\uffff\x01\x07", + "\x01\x08\x01\x02\x02\uffff\x01\x07\x06\uffff\x01\x04\x01\x03", + "\x01\x09\x01\x02\x02\uffff\x01\x0a\x06\uffff\x01\x04\x01\x03", + "\x01\x04\x01\x03", + "\x01\x0a\x06\uffff\x01\x04\x01\x03", + "\x01\x09\x01\x02\x02\uffff\x01\x0a\x06\uffff\x01\x04\x01\x03" + }; + + static readonly short[] DFA16_eot = DFA.UnpackEncodedString(DFA16_eotS); + static readonly short[] DFA16_eof = DFA.UnpackEncodedString(DFA16_eofS); + static readonly char[] DFA16_min = DFA.UnpackEncodedStringToUnsignedChars(DFA16_minS); + static readonly char[] DFA16_max = DFA.UnpackEncodedStringToUnsignedChars(DFA16_maxS); + static readonly short[] DFA16_accept = DFA.UnpackEncodedString(DFA16_acceptS); + static readonly short[] DFA16_special = DFA.UnpackEncodedString(DFA16_specialS); + static readonly short[][] DFA16_transition = DFA.UnpackEncodedStringArray(DFA16_transitionS); + + protected class DFA16 : DFA + { + public DFA16(BaseRecognizer recognizer) + { + this.recognizer = recognizer; + this.decisionNumber = 16; + this.eot = DFA16_eot; + this.eof = DFA16_eof; + this.min = DFA16_min; + this.max = DFA16_max; + this.accept = DFA16_accept; + this.special = DFA16_special; + this.transition = DFA16_transition; + + } + + override public string Description + { + get { return "83:1: scenarioKind : ( scenarioOutline | scenario );"; } + } + + } + + const string DFA55_eotS = + "\x5f\uffff"; + const string DFA55_eofS = + "\x01\x03\x5e\uffff"; + const string DFA55_minS = + "\x03\x1e\x02\uffff\x1c\x1e\x01\x00\x07\x1e\x01\x00\x04\x1e\x01"+ + "\x00\x02\x1e\x01\x00\x01\x1e\x02\x00\x04\x1e\x01\x00\x02\x1e\x01"+ + "\x00\x01\x1e\x02\x00\x02\x1e\x01\x00\x01\x1e\x02\x00\x01\x1e\x03"+ + "\x00\x02\x1e\x01\x00\x01\x1e\x02\x00\x01\x1e\x03\x00\x01\x1e\x0a"+ + "\x00"; + const string DFA55_maxS = + "\x02\x22\x01\x31\x02\uffff\x1c\x31\x01\x00\x07\x31\x01\x00\x04"+ + "\x31\x01\x00\x02\x31\x01\x00\x01\x31\x02\x00\x04\x31\x01\x00\x02"+ + "\x31\x01\x00\x01\x31\x02\x00\x02\x31\x01\x00\x01\x31\x02\x00\x01"+ + "\x31\x03\x00\x02\x31\x01\x00\x01\x31\x02\x00\x01\x31\x03\x00\x01"+ + "\x31\x0a\x00"; + const string DFA55_acceptS = + "\x03\uffff\x01\x02\x01\x01\x5a\uffff"; + const string DFA55_specialS = + "\x21\uffff\x01\x1d\x07\uffff\x01\x1e\x04\uffff\x01\x1f\x02\uffff"+ + "\x01\x1c\x01\uffff\x01\x1b\x01\x1a\x04\uffff\x01\x19\x02\uffff\x01"+ + "\x18\x01\uffff\x01\x17\x01\x16\x02\uffff\x01\x15\x01\uffff\x01\x14"+ + "\x01\x13\x01\uffff\x01\x12\x01\x11\x01\x10\x02\uffff\x01\x0f\x01"+ + "\uffff\x01\x0e\x01\x0d\x01\uffff\x01\x0c\x01\x0b\x01\x0a\x01\uffff"+ + "\x01\x09\x01\x08\x01\x07\x01\x06\x01\x00\x01\x05\x01\x04\x01\x03"+ + "\x01\x02\x01\x01}>"; + static readonly string[] DFA55_transitionS = { + "\x01\x01\x02\x04\x01\uffff\x01\x02", + "\x03\x04\x01\uffff\x01\x05", + "\x01\x06\x02\x04\x01\uffff\x01\x07\x0c\uffff\x03\x03", + "", + "", + "\x01\x08\x02\x04\x01\uffff\x01\x09\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x0a\x0c\uffff\x03\x03", + "\x01\x0b\x02\x04\x01\uffff\x01\x0c\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x0d\x0c\uffff\x03\x03", + "\x01\x0e\x02\x04\x01\uffff\x01\x0f\x0c\uffff\x03\x03", + "\x01\x10\x02\x04\x01\uffff\x01\x11\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x12\x0c\uffff\x03\x03", + "\x01\x13\x02\x04\x01\uffff\x01\x14\x0c\uffff\x03\x03", + "\x01\x15\x02\x04\x01\uffff\x01\x16\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x17\x0c\uffff\x03\x03", + "\x01\x18\x02\x04\x01\uffff\x01\x19\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x1a\x0c\uffff\x03\x03", + "\x01\x1b\x02\x04\x01\uffff\x01\x1c\x0c\uffff\x03\x03", + "\x01\x1d\x02\x04\x01\uffff\x01\x1e\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x1f\x0c\uffff\x03\x03", + "\x01\x20\x02\x04\x01\uffff\x01\x21\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x22\x0c\uffff\x03\x03", + "\x01\x23\x02\x04\x01\uffff\x01\x24\x0c\uffff\x03\x03", + "\x01\x25\x02\x04\x01\uffff\x01\x26\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x27\x0c\uffff\x03\x03", + "\x01\x28\x02\x04\x01\uffff\x01\x29\x0c\uffff\x03\x03", + "\x01\x2a\x02\x04\x01\uffff\x01\x2b\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x2c\x0c\uffff\x03\x03", + "\x01\x2d\x02\x04\x01\uffff\x01\x2e\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x2f\x0c\uffff\x03\x03", + "\x01\x30\x02\x04\x01\uffff\x01\x31\x0c\uffff\x03\x03", + "\x01\x32\x02\x04\x01\uffff\x01\x33\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x34\x0c\uffff\x03\x03", + "\x01\uffff", + "\x01\x35\x02\x04\x01\uffff\x01\x36\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x37\x0c\uffff\x03\x03", + "\x01\x38\x02\x04\x01\uffff\x01\x39\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x3a\x0c\uffff\x03\x03", + "\x01\x3b\x02\x04\x01\uffff\x01\x3c\x0c\uffff\x03\x03", + "\x01\x3d\x02\x04\x01\uffff\x01\x3e\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x3f\x0c\uffff\x03\x03", + "\x01\uffff", + "\x03\x04\x01\uffff\x01\x40\x0c\uffff\x03\x03", + "\x01\x41\x02\x04\x01\uffff\x01\x42\x0c\uffff\x03\x03", + "\x01\x43\x02\x04\x01\uffff\x01\x44\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x45\x0c\uffff\x03\x03", + "\x01\uffff", + "\x01\x46\x02\x04\x01\uffff\x01\x47\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x48\x0c\uffff\x03\x03", + "\x01\uffff", + "\x03\x04\x01\uffff\x01\x49\x0c\uffff\x03\x03", + "\x01\uffff", + "\x01\uffff", + "\x03\x04\x01\uffff\x01\x4a\x0c\uffff\x03\x03", + "\x01\x4b\x02\x04\x01\uffff\x01\x4c\x0c\uffff\x03\x03", + "\x01\x4d\x02\x04\x01\uffff\x01\x4e\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x4f\x0c\uffff\x03\x03", + "\x01\uffff", + "\x01\x50\x02\x04\x01\uffff\x01\x51\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x52\x0c\uffff\x03\x03", + "\x01\uffff", + "\x03\x04\x01\uffff\x01\x53\x0c\uffff\x03\x03", + "\x01\uffff", + "\x01\uffff", + "\x01\x54\x02\x04\x01\uffff\x01\x55\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x56\x0c\uffff\x03\x03", + "\x01\uffff", + "\x03\x04\x01\uffff\x01\x57\x0c\uffff\x03\x03", + "\x01\uffff", + "\x01\uffff", + "\x03\x04\x01\uffff\x01\x58\x0c\uffff\x03\x03", + "\x01\uffff", + "\x01\uffff", + "\x01\uffff", + "\x01\x59\x02\x04\x01\uffff\x01\x5a\x0c\uffff\x03\x03", + "\x03\x04\x01\uffff\x01\x5b\x0c\uffff\x03\x03", + "\x01\uffff", + "\x03\x04\x01\uffff\x01\x5c\x0c\uffff\x03\x03", + "\x01\uffff", + "\x01\uffff", + "\x03\x04\x01\uffff\x01\x5d\x0c\uffff\x03\x03", + "\x01\uffff", + "\x01\uffff", + "\x01\uffff", + "\x03\x04\x01\uffff\x01\x5e\x0c\uffff\x03\x03", + "\x01\uffff", + "\x01\uffff", + "\x01\uffff", + "\x01\uffff", + "\x01\uffff", + "\x01\uffff", + "\x01\uffff", + "\x01\uffff", + "\x01\uffff", + "\x01\uffff" + }; + + static readonly short[] DFA55_eot = DFA.UnpackEncodedString(DFA55_eotS); + static readonly short[] DFA55_eof = DFA.UnpackEncodedString(DFA55_eofS); + static readonly char[] DFA55_min = DFA.UnpackEncodedStringToUnsignedChars(DFA55_minS); + static readonly char[] DFA55_max = DFA.UnpackEncodedStringToUnsignedChars(DFA55_maxS); + static readonly short[] DFA55_accept = DFA.UnpackEncodedString(DFA55_acceptS); + static readonly short[] DFA55_special = DFA.UnpackEncodedString(DFA55_specialS); + static readonly short[][] DFA55_transition = DFA.UnpackEncodedStringArray(DFA55_transitionS); + + protected class DFA55 : DFA + { + public DFA55(BaseRecognizer recognizer) + { + this.recognizer = recognizer; + this.decisionNumber = 55; + this.eot = DFA55_eot; + this.eof = DFA55_eof; + this.min = DFA55_min; + this.max = DFA55_max; + this.accept = DFA55_accept; + this.special = DFA55_special; + this.transition = DFA55_transition; + + } + + override public string Description + { + get { return "()* loopback of 241:18: ( titleRest )*"; } + } + + } + + + protected internal int DFA55_SpecialStateTransition(DFA dfa, int s, IIntStream _input) //throws NoViableAltException + { + ITokenStream input = (ITokenStream)_input; + int _s = s; + switch ( s ) + { + case 0 : + int LA55_89 = input.LA(1); + + + int index55_89 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_89); + if ( s >= 0 ) return s; + break; + case 1 : + int LA55_94 = input.LA(1); + + + int index55_94 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_94); + if ( s >= 0 ) return s; + break; + case 2 : + int LA55_93 = input.LA(1); + + + int index55_93 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_93); + if ( s >= 0 ) return s; + break; + case 3 : + int LA55_92 = input.LA(1); + + + int index55_92 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_92); + if ( s >= 0 ) return s; + break; + case 4 : + int LA55_91 = input.LA(1); + + + int index55_91 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_91); + if ( s >= 0 ) return s; + break; + case 5 : + int LA55_90 = input.LA(1); + + + int index55_90 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_90); + if ( s >= 0 ) return s; + break; + case 6 : + int LA55_88 = input.LA(1); + + + int index55_88 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_88); + if ( s >= 0 ) return s; + break; + case 7 : + int LA55_87 = input.LA(1); + + + int index55_87 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_87); + if ( s >= 0 ) return s; + break; + case 8 : + int LA55_86 = input.LA(1); + + + int index55_86 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_86); + if ( s >= 0 ) return s; + break; + case 9 : + int LA55_85 = input.LA(1); + + + int index55_85 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_85); + if ( s >= 0 ) return s; + break; + case 10 : + int LA55_83 = input.LA(1); + + + int index55_83 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_83); + if ( s >= 0 ) return s; + break; + case 11 : + int LA55_82 = input.LA(1); + + + int index55_82 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_82); + if ( s >= 0 ) return s; + break; + case 12 : + int LA55_81 = input.LA(1); + + + int index55_81 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_81); + if ( s >= 0 ) return s; + break; + case 13 : + int LA55_79 = input.LA(1); + + + int index55_79 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_79); + if ( s >= 0 ) return s; + break; + case 14 : + int LA55_78 = input.LA(1); + + + int index55_78 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_78); + if ( s >= 0 ) return s; + break; + case 15 : + int LA55_76 = input.LA(1); + + + int index55_76 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_76); + if ( s >= 0 ) return s; + break; + case 16 : + int LA55_73 = input.LA(1); + + + int index55_73 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_73); + if ( s >= 0 ) return s; + break; + case 17 : + int LA55_72 = input.LA(1); + + + int index55_72 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_72); + if ( s >= 0 ) return s; + break; + case 18 : + int LA55_71 = input.LA(1); + + + int index55_71 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_71); + if ( s >= 0 ) return s; + break; + case 19 : + int LA55_69 = input.LA(1); + + + int index55_69 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_69); + if ( s >= 0 ) return s; + break; + case 20 : + int LA55_68 = input.LA(1); + + + int index55_68 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_68); + if ( s >= 0 ) return s; + break; + case 21 : + int LA55_66 = input.LA(1); + + + int index55_66 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_66); + if ( s >= 0 ) return s; + break; + case 22 : + int LA55_63 = input.LA(1); + + + int index55_63 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_63); + if ( s >= 0 ) return s; + break; + case 23 : + int LA55_62 = input.LA(1); + + + int index55_62 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_62); + if ( s >= 0 ) return s; + break; + case 24 : + int LA55_60 = input.LA(1); + + + int index55_60 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_60); + if ( s >= 0 ) return s; + break; + case 25 : + int LA55_57 = input.LA(1); + + + int index55_57 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_57); + if ( s >= 0 ) return s; + break; + case 26 : + int LA55_52 = input.LA(1); + + + int index55_52 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_52); + if ( s >= 0 ) return s; + break; + case 27 : + int LA55_51 = input.LA(1); + + + int index55_51 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_51); + if ( s >= 0 ) return s; + break; + case 28 : + int LA55_49 = input.LA(1); + + + int index55_49 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_49); + if ( s >= 0 ) return s; + break; + case 29 : + int LA55_33 = input.LA(1); + + + int index55_33 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_33); + if ( s >= 0 ) return s; + break; + case 30 : + int LA55_41 = input.LA(1); + + + int index55_41 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_41); + if ( s >= 0 ) return s; + break; + case 31 : + int LA55_46 = input.LA(1); + + + int index55_46 = input.Index(); + input.Rewind(); + s = -1; + if ( (synpred57_SpecFlowLang()) ) { s = 4; } + + else if ( (true) ) { s = 3; } + + + input.Seek(index55_46); + if ( s >= 0 ) return s; + break; + } + if (state.backtracking > 0) {state.failed = true; return -1;} + NoViableAltException nvae55 = + new NoViableAltException(dfa.Description, 55, _s, input); + dfa.Error(nvae55); + throw nvae55; + } + + + public static readonly BitSet FOLLOW_newlineWithSpaces_in_feature264 = new BitSet(new ulong[]{0x00000100C0000000UL}); + public static readonly BitSet FOLLOW_tags_in_feature275 = new BitSet(new ulong[]{0x0000010040000000UL}); + public static readonly BitSet FOLLOW_WS_in_feature286 = new BitSet(new ulong[]{0x0000010000000000UL}); + public static readonly BitSet FOLLOW_40_in_feature289 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_WS_in_feature291 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_text_in_feature294 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_newlineWithSpaces_in_feature296 = new BitSet(new ulong[]{0x00000603C0000000UL}); + public static readonly BitSet FOLLOW_descriptionLine_in_feature306 = new BitSet(new ulong[]{0x00000603C0000000UL}); + public static readonly BitSet FOLLOW_background_in_feature317 = new BitSet(new ulong[]{0x00000600C0000000UL}); + public static readonly BitSet FOLLOW_scenarioKind_in_feature328 = new BitSet(new ulong[]{0x00000600C0000000UL}); + public static readonly BitSet FOLLOW_WS_in_feature331 = new BitSet(new ulong[]{0x0000000000000000UL}); + public static readonly BitSet FOLLOW_EOF_in_feature334 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_tags411 = new BitSet(new ulong[]{0x00000000C0000000UL}); + public static readonly BitSet FOLLOW_tag_in_tags414 = new BitSet(new ulong[]{0x00000000C0000002UL}); + public static readonly BitSet FOLLOW_AT_in_tag451 = new BitSet(new ulong[]{0x0000000100000000UL}); + public static readonly BitSet FOLLOW_word_in_tag453 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_newlineWithSpaces_in_tag456 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_tag458 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WORDCHAR_in_word494 = new BitSet(new ulong[]{0x0000000100000002UL}); + public static readonly BitSet FOLLOW_WS_in_descriptionLine531 = new BitSet(new ulong[]{0x0000000140000000UL}); + public static readonly BitSet FOLLOW_descriptionLineText_in_descriptionLine534 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_newlineWithSpaces_in_descriptionLine536 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_background571 = new BitSet(new ulong[]{0x0000000200000000UL}); + public static readonly BitSet FOLLOW_T_BACKGROUND_in_background574 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_WS_in_background586 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_title_in_background588 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_newlineWithSpaces_in_background601 = new BitSet(new ulong[]{0x0000800040000000UL}); + public static readonly BitSet FOLLOW_givens_in_background603 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_scenarioOutline_in_scenarioKind641 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_scenario_in_scenarioKind652 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_tags_in_scenario671 = new BitSet(new ulong[]{0x0000020040000000UL}); + public static readonly BitSet FOLLOW_WS_in_scenario674 = new BitSet(new ulong[]{0x0000020000000000UL}); + public static readonly BitSet FOLLOW_41_in_scenario677 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_WS_in_scenario679 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_title_in_scenario691 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_newlineWithSpaces_in_scenario693 = new BitSet(new ulong[]{0x0003800040000000UL}); + public static readonly BitSet FOLLOW_steps_in_scenario704 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_tags_in_scenarioOutline750 = new BitSet(new ulong[]{0x0000040040000000UL}); + public static readonly BitSet FOLLOW_WS_in_scenarioOutline753 = new BitSet(new ulong[]{0x0000040000000000UL}); + public static readonly BitSet FOLLOW_42_in_scenarioOutline756 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_WS_in_scenarioOutline758 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_title_in_scenarioOutline769 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_newlineWithSpaces_in_scenarioOutline771 = new BitSet(new ulong[]{0x0003800040000000UL}); + public static readonly BitSet FOLLOW_steps_in_scenarioOutline781 = new BitSet(new ulong[]{0x0000180040000000UL}); + public static readonly BitSet FOLLOW_examples_in_scenarioOutline791 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_exampleSet_in_examples833 = new BitSet(new ulong[]{0x0000180040000002UL}); + public static readonly BitSet FOLLOW_WS_in_exampleSet870 = new BitSet(new ulong[]{0x0000180000000000UL}); + public static readonly BitSet FOLLOW_43_in_exampleSet874 = new BitSet(new ulong[]{0x00000005C0000000UL}); + public static readonly BitSet FOLLOW_44_in_exampleSet876 = new BitSet(new ulong[]{0x00000005C0000000UL}); + public static readonly BitSet FOLLOW_WS_in_exampleSet879 = new BitSet(new ulong[]{0x00000005C0000000UL}); + public static readonly BitSet FOLLOW_text_in_exampleSet890 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_newlineWithSpaces_in_exampleSet893 = new BitSet(new ulong[]{0x0008000040000000UL}); + public static readonly BitSet FOLLOW_table_in_exampleSet895 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_firstStep_in_steps933 = new BitSet(new ulong[]{0x0003E00040000002UL}); + public static readonly BitSet FOLLOW_nextStep_in_steps935 = new BitSet(new ulong[]{0x0003E00040000002UL}); + public static readonly BitSet FOLLOW_firstGiven_in_firstStep968 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_firstWhen_in_firstStep977 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_firstThen_in_firstStep986 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_firstStep_in_nextStep1008 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_firstAnd_in_nextStep1017 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_firstBut_in_nextStep1026 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_firstAnd1049 = new BitSet(new ulong[]{0x0000200000000000UL}); + public static readonly BitSet FOLLOW_45_in_firstAnd1052 = new BitSet(new ulong[]{0x0000000040000000UL}); + public static readonly BitSet FOLLOW_WS_in_firstAnd1054 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_sentenceEnd_in_firstAnd1056 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_firstBut1091 = new BitSet(new ulong[]{0x0000400000000000UL}); + public static readonly BitSet FOLLOW_46_in_firstBut1094 = new BitSet(new ulong[]{0x0000000040000000UL}); + public static readonly BitSet FOLLOW_WS_in_firstBut1096 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_sentenceEnd_in_firstBut1098 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_firstGiven_in_givens1133 = new BitSet(new ulong[]{0x0003E00040000002UL}); + public static readonly BitSet FOLLOW_nextStep_in_givens1135 = new BitSet(new ulong[]{0x0003E00040000002UL}); + public static readonly BitSet FOLLOW_WS_in_firstGiven1173 = new BitSet(new ulong[]{0x0000800000000000UL}); + public static readonly BitSet FOLLOW_47_in_firstGiven1176 = new BitSet(new ulong[]{0x0000000040000000UL}); + public static readonly BitSet FOLLOW_WS_in_firstGiven1178 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_sentenceEnd_in_firstGiven1180 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_firstWhen1216 = new BitSet(new ulong[]{0x0001000000000000UL}); + public static readonly BitSet FOLLOW_48_in_firstWhen1219 = new BitSet(new ulong[]{0x0000000040000000UL}); + public static readonly BitSet FOLLOW_WS_in_firstWhen1221 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_sentenceEnd_in_firstWhen1223 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_firstThen1259 = new BitSet(new ulong[]{0x0002000000000000UL}); + public static readonly BitSet FOLLOW_49_in_firstThen1262 = new BitSet(new ulong[]{0x0000000040000000UL}); + public static readonly BitSet FOLLOW_WS_in_firstThen1264 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_sentenceEnd_in_firstThen1266 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_text_in_sentenceEnd1303 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_newlineWithSpaces_in_sentenceEnd1305 = new BitSet(new ulong[]{0x000C000040000002UL}); + public static readonly BitSet FOLLOW_multilineText_in_sentenceEnd1307 = new BitSet(new ulong[]{0x0008000040000002UL}); + public static readonly BitSet FOLLOW_table_in_sentenceEnd1310 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_indent_in_multilineText1348 = new BitSet(new ulong[]{0x0004000000000000UL}); + public static readonly BitSet FOLLOW_50_in_multilineText1350 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_WS_in_multilineText1352 = new BitSet(new ulong[]{0x0000000400000000UL}); + public static readonly BitSet FOLLOW_NEWLINE_in_multilineText1355 = new BitSet(new ulong[]{0x00040005C0000000UL}); + public static readonly BitSet FOLLOW_multilineTextLine_in_multilineText1365 = new BitSet(new ulong[]{0x00040005C0000000UL}); + public static readonly BitSet FOLLOW_WS_in_multilineText1376 = new BitSet(new ulong[]{0x0004000000000000UL}); + public static readonly BitSet FOLLOW_50_in_multilineText1379 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_WS_in_multilineText1381 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_newlineWithSpaces_in_multilineText1384 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_indent1422 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_multilineTextLine1451 = new BitSet(new ulong[]{0x00000005C0000000UL}); + public static readonly BitSet FOLLOW_text_in_multilineTextLine1454 = new BitSet(new ulong[]{0x0000000400000000UL}); + public static readonly BitSet FOLLOW_NEWLINE_in_multilineTextLine1457 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_tableRow_in_table1498 = new BitSet(new ulong[]{0x0008000040000000UL}); + public static readonly BitSet FOLLOW_tableRow_in_table1500 = new BitSet(new ulong[]{0x0008000040000002UL}); + public static readonly BitSet FOLLOW_WS_in_tableRow1547 = new BitSet(new ulong[]{0x0008000000000000UL}); + public static readonly BitSet FOLLOW_51_in_tableRow1550 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_tableCell_in_tableRow1552 = new BitSet(new ulong[]{0x00000005C0000000UL}); + public static readonly BitSet FOLLOW_WS_in_tableRow1555 = new BitSet(new ulong[]{0x0000000440000000UL}); + public static readonly BitSet FOLLOW_newlineWithSpaces_in_tableRow1558 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_tableCell1594 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_text_in_tableCell1597 = new BitSet(new ulong[]{0x0008000040000000UL}); + public static readonly BitSet FOLLOW_WS_in_tableCell1599 = new BitSet(new ulong[]{0x0008000000000000UL}); + public static readonly BitSet FOLLOW_51_in_tableCell1602 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WORDCHAR_in_descriptionLineText1637 = new BitSet(new ulong[]{0x00000001C0000002UL}); + public static readonly BitSet FOLLOW_textRest_in_descriptionLineText1639 = new BitSet(new ulong[]{0x00000001C0000002UL}); + public static readonly BitSet FOLLOW_wordchar_in_text1678 = new BitSet(new ulong[]{0x00000001C0000002UL}); + public static readonly BitSet FOLLOW_textRest_in_text1680 = new BitSet(new ulong[]{0x00000001C0000002UL}); + public static readonly BitSet FOLLOW_WS_in_textRest1718 = new BitSet(new ulong[]{0x00000001C0000000UL}); + public static readonly BitSet FOLLOW_textRest_in_textRest1720 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_wordchar_in_textRest1730 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_wordchar_in_title1749 = new BitSet(new ulong[]{0x00000005C0000002UL}); + public static readonly BitSet FOLLOW_titleRest_in_title1751 = new BitSet(new ulong[]{0x00000005C0000002UL}); + public static readonly BitSet FOLLOW_WS_in_titleRest1790 = new BitSet(new ulong[]{0x00000005C0000000UL}); + public static readonly BitSet FOLLOW_titleRest_in_titleRest1792 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_NEWLINE_in_titleRest1802 = new BitSet(new ulong[]{0x00000005C0000000UL}); + public static readonly BitSet FOLLOW_titleRest_in_titleRest1804 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_wordchar_in_titleRest1814 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_NEWLINE_in_titleRestLine1833 = new BitSet(new ulong[]{0x0000000540000000UL}); + public static readonly BitSet FOLLOW_titleRestLine_in_titleRestLine1835 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_titleRestLine1845 = new BitSet(new ulong[]{0x0000000540000000UL}); + public static readonly BitSet FOLLOW_titleRestLine_in_titleRestLine1847 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WORDCHAR_in_titleRestLine1857 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_set_in_wordchar0 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_newlineWithSpaces1905 = new BitSet(new ulong[]{0x0000000400000000UL}); + public static readonly BitSet FOLLOW_NEWLINE_in_newlineWithSpaces1908 = new BitSet(new ulong[]{0x0000000440000002UL}); + public static readonly BitSet FOLLOW_WS_in_newlineWithSpaces1911 = new BitSet(new ulong[]{0x0000000400000000UL}); + public static readonly BitSet FOLLOW_NEWLINE_in_newlineWithSpaces1914 = new BitSet(new ulong[]{0x0000000440000002UL}); + public static readonly BitSet FOLLOW_WS_in_synpred26_SpecFlowLang879 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_synpred44_SpecFlowLang1381 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_WS_in_synpred51_SpecFlowLang1555 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_titleRest_in_synpred57_SpecFlowLang1751 = new BitSet(new ulong[]{0x0000000000000002UL}); + +} +} \ No newline at end of file diff --git a/Parser/Grammar/SpecFlowLangWalker.cs b/Parser/Grammar/SpecFlowLangWalker.cs new file mode 100644 index 000000000..a3cb64b08 --- /dev/null +++ b/Parser/Grammar/SpecFlowLangWalker.cs @@ -0,0 +1,2210 @@ +// $ANTLR 3.1.2 SpecFlowLangWalker.g 2009-10-16 10:52:13 + +// The variable 'variable' is assigned but its value is never used. +#pragma warning disable 168, 219 +// Unreachable code detected. +#pragma warning disable 162 +namespace TechTalk.SpecFlow.Parser.Grammar +{ + +using System.Collections.Generic; +using System.Text; +using TechTalk.SpecFlow.Parser.SyntaxElements; + + +using System; +using Antlr.Runtime; +using Antlr.Runtime.Tree;using IList = System.Collections.IList; +using ArrayList = System.Collections.ArrayList; +using Stack = Antlr.Runtime.Collections.StackList; + + +public partial class SpecFlowLangWalker : TreeParser +{ + public static readonly string[] tokenNames = new string[] + { + "", + "", + "", + "", + "FEATURE", + "DESCRIPTIONLINE", + "BACKGROUND", + "SCENARIOS", + "SCENARIO", + "SCENARIOOUTLINE", + "EXAMPLES", + "EXAMPLESET", + "STEPS", + "GIVEN", + "WHEN", + "THEN", + "TEXT", + "AND", + "BUT", + "TAGS", + "TAG", + "WORD", + "MULTILINETEXT", + "INDENT", + "LINE", + "TABLE", + "HEADER", + "BODY", + "ROW", + "CELL", + "WS", + "AT", + "WORDCHAR", + "T_BACKGROUND", + "NEWLINE", + "WSCHAR", + "NONWCHR", + "NEWLINECHR", + "NONNLCHR", + "COMMENT", + "'Feature:'", + "'Scenario:'", + "'Scenario Outline:'", + "'Examples:'", + "'Scenarios:'", + "'And'", + "'But'", + "'Given'", + "'When'", + "'Then'", + "'\"\"\"'", + "'|'" + }; + + public const int NEWLINECHR = 37; + public const int ROW = 28; + public const int T_BACKGROUND = 33; + public const int TABLE = 25; + public const int CELL = 29; + public const int DESCRIPTIONLINE = 5; + public const int AND = 17; + public const int EOF = -1; + public const int INDENT = 23; + public const int AT = 31; + public const int WORD = 21; + public const int T__51 = 51; + public const int BACKGROUND = 6; + public const int MULTILINETEXT = 22; + public const int THEN = 15; + public const int NONWCHR = 36; + public const int BODY = 27; + public const int GIVEN = 13; + public const int HEADER = 26; + public const int COMMENT = 39; + public const int SCENARIO = 8; + public const int T__50 = 50; + public const int T__42 = 42; + public const int T__43 = 43; + public const int T__40 = 40; + public const int T__41 = 41; + public const int T__46 = 46; + public const int T__47 = 47; + public const int T__44 = 44; + public const int T__45 = 45; + public const int EXAMPLESET = 11; + public const int T__48 = 48; + public const int T__49 = 49; + public const int BUT = 18; + public const int TAGS = 19; + public const int EXAMPLES = 10; + public const int WSCHAR = 35; + public const int TEXT = 16; + public const int NONNLCHR = 38; + public const int LINE = 24; + public const int FEATURE = 4; + public const int TAG = 20; + public const int SCENARIOS = 7; + public const int WORDCHAR = 32; + public const int WS = 30; + public const int NEWLINE = 34; + public const int SCENARIOOUTLINE = 9; + public const int WHEN = 14; + public const int STEPS = 12; + + // delegates + // delegators + + + + public SpecFlowLangWalker(ITreeNodeStream input) + : this(input, new RecognizerSharedState()) { + } + + public SpecFlowLangWalker(ITreeNodeStream input, RecognizerSharedState state) + : base(input, state) { + InitializeCyclicDFAs(); + + + } + + + override public string[] TokenNames { + get { return SpecFlowLangWalker.tokenNames; } + } + + override public string GrammarFileName { + get { return "SpecFlowLangWalker.g"; } + } + + + + // $ANTLR start "feature" + // SpecFlowLangWalker.g:17:1: feature returns [Feature feature] : ^( FEATURE (tags_= tags )? title_= text (descLine_= descriptionLine )* (background_= background )? ^( SCENARIOS (scenario_= scenarioKind )* ) ) ; + public Feature feature() // throws RecognitionException [1] + { + Feature feature = default(Feature); + + Tags tags_ = default(Tags); + + Text title_ = default(Text); + + DescriptionLine descLine_ = default(DescriptionLine); + + Background background_ = default(Background); + + Scenario scenario_ = default(Scenario); + + + + var scenarios = new List(); + var descLines = new List(); + + try + { + // SpecFlowLangWalker.g:25:5: ( ^( FEATURE (tags_= tags )? title_= text (descLine_= descriptionLine )* (background_= background )? ^( SCENARIOS (scenario_= scenarioKind )* ) ) ) + // SpecFlowLangWalker.g:25:9: ^( FEATURE (tags_= tags )? title_= text (descLine_= descriptionLine )* (background_= background )? ^( SCENARIOS (scenario_= scenarioKind )* ) ) + { + Match(input,FEATURE,FOLLOW_FEATURE_in_feature73); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:26:13: (tags_= tags )? + int alt1 = 2; + int LA1_0 = input.LA(1); + + if ( (LA1_0 == TAGS) ) + { + alt1 = 1; + } + switch (alt1) + { + case 1 : + // SpecFlowLangWalker.g:26:14: tags_= tags + { + PushFollow(FOLLOW_tags_in_feature90); + tags_ = tags(); + state.followingStackPointer--; + + + } + break; + + } + + PushFollow(FOLLOW_text_in_feature108); + title_ = text(); + state.followingStackPointer--; + + // SpecFlowLangWalker.g:28:13: (descLine_= descriptionLine )* + do + { + int alt2 = 2; + int LA2_0 = input.LA(1); + + if ( (LA2_0 == DESCRIPTIONLINE) ) + { + alt2 = 1; + } + + + switch (alt2) + { + case 1 : + // SpecFlowLangWalker.g:28:14: descLine_= descriptionLine + { + PushFollow(FOLLOW_descriptionLine_in_feature125); + descLine_ = descriptionLine(); + state.followingStackPointer--; + + descLines.Add(descLine_); + + } + break; + + default: + goto loop2; + } + } while (true); + + loop2: + ; // Stops C# compiler whining that label 'loop2' has no statements + + // SpecFlowLangWalker.g:29:13: (background_= background )? + int alt3 = 2; + int LA3_0 = input.LA(1); + + if ( (LA3_0 == BACKGROUND) ) + { + alt3 = 1; + } + switch (alt3) + { + case 1 : + // SpecFlowLangWalker.g:29:14: background_= background + { + PushFollow(FOLLOW_background_in_feature146); + background_ = background(); + state.followingStackPointer--; + + + } + break; + + } + + Match(input,SCENARIOS,FOLLOW_SCENARIOS_in_feature163); + + if ( input.LA(1) == Token.DOWN ) + { + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:31:17: (scenario_= scenarioKind )* + do + { + int alt4 = 2; + int LA4_0 = input.LA(1); + + if ( ((LA4_0 >= SCENARIO && LA4_0 <= SCENARIOOUTLINE)) ) + { + alt4 = 1; + } + + + switch (alt4) + { + case 1 : + // SpecFlowLangWalker.g:31:18: scenario_= scenarioKind + { + PushFollow(FOLLOW_scenarioKind_in_feature185); + scenario_ = scenarioKind(); + state.followingStackPointer--; + + scenarios.Add(scenario_); + + } + break; + + default: + goto loop4; + } + } while (true); + + loop4: + ; // Stops C# compiler whining that label 'loop4' has no statements + + + Match(input, Token.UP, null); + } + + Match(input, Token.UP, null); + + } + + + feature = new Feature(title_, tags_, descLines.ToArray(), background_, scenarios.ToArray()); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return feature; + } + // $ANTLR end "feature" + + + // $ANTLR start "tags" + // SpecFlowLangWalker.g:36:1: tags returns [Tags tags] : ^( TAGS (tag_= tag )+ ) ; + public Tags tags() // throws RecognitionException [1] + { + Tags tags = default(Tags); + + Tag tag_ = default(Tag); + + + + tags = new Tags(); + + try + { + // SpecFlowLangWalker.g:40:5: ( ^( TAGS (tag_= tag )+ ) ) + // SpecFlowLangWalker.g:40:9: ^( TAGS (tag_= tag )+ ) + { + Match(input,TAGS,FOLLOW_TAGS_in_tags243); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:41:13: (tag_= tag )+ + int cnt5 = 0; + do + { + int alt5 = 2; + int LA5_0 = input.LA(1); + + if ( (LA5_0 == TAG) ) + { + alt5 = 1; + } + + + switch (alt5) + { + case 1 : + // SpecFlowLangWalker.g:41:14: tag_= tag + { + PushFollow(FOLLOW_tag_in_tags260); + tag_ = tag(); + state.followingStackPointer--; + + tags.Add(tag_); + + } + break; + + default: + if ( cnt5 >= 1 ) goto loop5; + EarlyExitException eee5 = + new EarlyExitException(5, input); + throw eee5; + } + cnt5++; + } while (true); + + loop5: + ; // Stops C# compiler whinging that label 'loop5' has no statements + + + Match(input, Token.UP, null); + + } + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return tags; + } + // $ANTLR end "tags" + + + // $ANTLR start "tag" + // SpecFlowLangWalker.g:45:1: tag returns [Tag tag] : ^( TAG word_= word ) ; + public Tag tag() // throws RecognitionException [1] + { + Tag tag = default(Tag); + + Word word_ = default(Word); + + + try + { + // SpecFlowLangWalker.g:49:5: ( ^( TAG word_= word ) ) + // SpecFlowLangWalker.g:49:9: ^( TAG word_= word ) + { + Match(input,TAG,FOLLOW_TAG_in_tag302); + + Match(input, Token.DOWN, null); + PushFollow(FOLLOW_word_in_tag318); + word_ = word(); + state.followingStackPointer--; + + + Match(input, Token.UP, null); + + } + + + tag = new Tag(word_); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return tag; + } + // $ANTLR end "tag" + + + // $ANTLR start "word" + // SpecFlowLangWalker.g:54:1: word returns [Word word] : ^( WORD (char_= WORDCHAR )+ ) ; + public Word word() // throws RecognitionException [1] + { + Word word = default(Word); + + CommonTree char_ = null; + + + var wordBuffer = new StringBuilder(); + + try + { + // SpecFlowLangWalker.g:61:5: ( ^( WORD (char_= WORDCHAR )+ ) ) + // SpecFlowLangWalker.g:61:9: ^( WORD (char_= WORDCHAR )+ ) + { + Match(input,WORD,FOLLOW_WORD_in_word361); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:62:13: (char_= WORDCHAR )+ + int cnt6 = 0; + do + { + int alt6 = 2; + int LA6_0 = input.LA(1); + + if ( (LA6_0 == WORDCHAR) ) + { + alt6 = 1; + } + + + switch (alt6) + { + case 1 : + // SpecFlowLangWalker.g:62:14: char_= WORDCHAR + { + char_=(CommonTree)Match(input,WORDCHAR,FOLLOW_WORDCHAR_in_word378); + wordBuffer.Append(char_.Text); + + } + break; + + default: + if ( cnt6 >= 1 ) goto loop6; + EarlyExitException eee6 = + new EarlyExitException(6, input); + throw eee6; + } + cnt6++; + } while (true); + + loop6: + ; // Stops C# compiler whinging that label 'loop6' has no statements + + + Match(input, Token.UP, null); + + } + + + word = new Word(wordBuffer.ToString()); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return word; + } + // $ANTLR end "word" + + + // $ANTLR start "descriptionLine" + // SpecFlowLangWalker.g:66:1: descriptionLine returns [DescriptionLine descriptionLine] : ^( DESCRIPTIONLINE text_= text ) ; + public DescriptionLine descriptionLine() // throws RecognitionException [1] + { + DescriptionLine descriptionLine = default(DescriptionLine); + + Text text_ = default(Text); + + + try + { + // SpecFlowLangWalker.g:70:5: ( ^( DESCRIPTIONLINE text_= text ) ) + // SpecFlowLangWalker.g:70:9: ^( DESCRIPTIONLINE text_= text ) + { + Match(input,DESCRIPTIONLINE,FOLLOW_DESCRIPTIONLINE_in_descriptionLine420); + + Match(input, Token.DOWN, null); + PushFollow(FOLLOW_text_in_descriptionLine436); + text_ = text(); + state.followingStackPointer--; + + + Match(input, Token.UP, null); + + } + + + descriptionLine = new DescriptionLine(text_); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return descriptionLine; + } + // $ANTLR end "descriptionLine" + + + // $ANTLR start "background" + // SpecFlowLangWalker.g:75:1: background returns [Background background] : ^( BACKGROUND (title_= text )? steps_= steps ) ; + public Background background() // throws RecognitionException [1] + { + Background background = default(Background); + + Text title_ = default(Text); + + ScenarioSteps steps_ = default(ScenarioSteps); + + + try + { + // SpecFlowLangWalker.g:79:5: ( ^( BACKGROUND (title_= text )? steps_= steps ) ) + // SpecFlowLangWalker.g:79:9: ^( BACKGROUND (title_= text )? steps_= steps ) + { + Match(input,BACKGROUND,FOLLOW_BACKGROUND_in_background474); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:80:13: (title_= text )? + int alt7 = 2; + int LA7_0 = input.LA(1); + + if ( (LA7_0 == TEXT) ) + { + alt7 = 1; + } + switch (alt7) + { + case 1 : + // SpecFlowLangWalker.g:80:14: title_= text + { + PushFollow(FOLLOW_text_in_background491); + title_ = text(); + state.followingStackPointer--; + + + } + break; + + } + + PushFollow(FOLLOW_steps_in_background509); + steps_ = steps(); + state.followingStackPointer--; + + + Match(input, Token.UP, null); + + } + + + background = new Background(title_, steps_); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return background; + } + // $ANTLR end "background" + + + // $ANTLR start "scenarioKind" + // SpecFlowLangWalker.g:85:1: scenarioKind returns [Scenario scenarioKind] : (scenario_= scenario | outline_= scenarioOutline ); + public Scenario scenarioKind() // throws RecognitionException [1] + { + Scenario scenarioKind = default(Scenario); + + Scenario scenario_ = default(Scenario); + + ScenarioOutline outline_ = default(ScenarioOutline); + + + try + { + // SpecFlowLangWalker.g:86:5: (scenario_= scenario | outline_= scenarioOutline ) + int alt8 = 2; + int LA8_0 = input.LA(1); + + if ( (LA8_0 == SCENARIO) ) + { + alt8 = 1; + } + else if ( (LA8_0 == SCENARIOOUTLINE) ) + { + alt8 = 2; + } + else + { + NoViableAltException nvae_d8s0 = + new NoViableAltException("", 8, 0, input); + + throw nvae_d8s0; + } + switch (alt8) + { + case 1 : + // SpecFlowLangWalker.g:86:9: scenario_= scenario + { + PushFollow(FOLLOW_scenario_in_scenarioKind543); + scenario_ = scenario(); + state.followingStackPointer--; + + scenarioKind = scenario_; + + } + break; + case 2 : + // SpecFlowLangWalker.g:87:9: outline_= scenarioOutline + { + PushFollow(FOLLOW_scenarioOutline_in_scenarioKind557); + outline_ = scenarioOutline(); + state.followingStackPointer--; + + scenarioKind = outline_; + + } + break; + + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return scenarioKind; + } + // $ANTLR end "scenarioKind" + + + // $ANTLR start "scenarioOutline" + // SpecFlowLangWalker.g:90:1: scenarioOutline returns [ScenarioOutline outline] : ^( SCENARIOOUTLINE (tags_= tags )? title_= text steps_= steps examples_= examples ) ; + public ScenarioOutline scenarioOutline() // throws RecognitionException [1] + { + ScenarioOutline outline = default(ScenarioOutline); + + Tags tags_ = default(Tags); + + Text title_ = default(Text); + + ScenarioSteps steps_ = default(ScenarioSteps); + + Examples examples_ = default(Examples); + + + try + { + // SpecFlowLangWalker.g:94:5: ( ^( SCENARIOOUTLINE (tags_= tags )? title_= text steps_= steps examples_= examples ) ) + // SpecFlowLangWalker.g:94:9: ^( SCENARIOOUTLINE (tags_= tags )? title_= text steps_= steps examples_= examples ) + { + Match(input,SCENARIOOUTLINE,FOLLOW_SCENARIOOUTLINE_in_scenarioOutline587); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:95:18: (tags_= tags )? + int alt9 = 2; + int LA9_0 = input.LA(1); + + if ( (LA9_0 == TAGS) ) + { + alt9 = 1; + } + switch (alt9) + { + case 1 : + // SpecFlowLangWalker.g:95:18: tags_= tags + { + PushFollow(FOLLOW_tags_in_scenarioOutline603); + tags_ = tags(); + state.followingStackPointer--; + + + } + break; + + } + + PushFollow(FOLLOW_text_in_scenarioOutline620); + title_ = text(); + state.followingStackPointer--; + + PushFollow(FOLLOW_steps_in_scenarioOutline636); + steps_ = steps(); + state.followingStackPointer--; + + PushFollow(FOLLOW_examples_in_scenarioOutline652); + examples_ = examples(); + state.followingStackPointer--; + + + Match(input, Token.UP, null); + + } + + + outline = new ScenarioOutline(title_, tags_, steps_, examples_); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return outline; + } + // $ANTLR end "scenarioOutline" + + + // $ANTLR start "scenario" + // SpecFlowLangWalker.g:102:1: scenario returns [Scenario scenario] : ^( SCENARIO (tags_= tags )? title_= text steps_= steps ) ; + public Scenario scenario() // throws RecognitionException [1] + { + Scenario scenario = default(Scenario); + + Tags tags_ = default(Tags); + + Text title_ = default(Text); + + ScenarioSteps steps_ = default(ScenarioSteps); + + + try + { + // SpecFlowLangWalker.g:106:5: ( ^( SCENARIO (tags_= tags )? title_= text steps_= steps ) ) + // SpecFlowLangWalker.g:106:9: ^( SCENARIO (tags_= tags )? title_= text steps_= steps ) + { + Match(input,SCENARIO,FOLLOW_SCENARIO_in_scenario690); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:107:18: (tags_= tags )? + int alt10 = 2; + int LA10_0 = input.LA(1); + + if ( (LA10_0 == TAGS) ) + { + alt10 = 1; + } + switch (alt10) + { + case 1 : + // SpecFlowLangWalker.g:107:18: tags_= tags + { + PushFollow(FOLLOW_tags_in_scenario707); + tags_ = tags(); + state.followingStackPointer--; + + + } + break; + + } + + PushFollow(FOLLOW_text_in_scenario724); + title_ = text(); + state.followingStackPointer--; + + PushFollow(FOLLOW_steps_in_scenario740); + steps_ = steps(); + state.followingStackPointer--; + + + Match(input, Token.UP, null); + + } + + + scenario = new Scenario(title_, tags_, steps_); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return scenario; + } + // $ANTLR end "scenario" + + + // $ANTLR start "examples" + // SpecFlowLangWalker.g:113:1: examples returns [Examples examples] : ^( EXAMPLES (exampleSet_= exampleSet )+ ) ; + public Examples examples() // throws RecognitionException [1] + { + Examples examples = default(Examples); + + ExampleSet exampleSet_ = default(ExampleSet); + + + + var exampleSets = new List(); + + try + { + // SpecFlowLangWalker.g:120:5: ( ^( EXAMPLES (exampleSet_= exampleSet )+ ) ) + // SpecFlowLangWalker.g:120:9: ^( EXAMPLES (exampleSet_= exampleSet )+ ) + { + Match(input,EXAMPLES,FOLLOW_EXAMPLES_in_examples783); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:121:13: (exampleSet_= exampleSet )+ + int cnt11 = 0; + do + { + int alt11 = 2; + int LA11_0 = input.LA(1); + + if ( (LA11_0 == EXAMPLESET) ) + { + alt11 = 1; + } + + + switch (alt11) + { + case 1 : + // SpecFlowLangWalker.g:121:14: exampleSet_= exampleSet + { + PushFollow(FOLLOW_exampleSet_in_examples800); + exampleSet_ = exampleSet(); + state.followingStackPointer--; + + exampleSets.Add(exampleSet_); + + } + break; + + default: + if ( cnt11 >= 1 ) goto loop11; + EarlyExitException eee11 = + new EarlyExitException(11, input); + throw eee11; + } + cnt11++; + } while (true); + + loop11: + ; // Stops C# compiler whinging that label 'loop11' has no statements + + + Match(input, Token.UP, null); + + } + + + examples = new Examples(exampleSets.ToArray()); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return examples; + } + // $ANTLR end "examples" + + + // $ANTLR start "exampleSet" + // SpecFlowLangWalker.g:125:1: exampleSet returns [ExampleSet exampleSet] : ^( EXAMPLESET (title_= text )? table_= table ) ; + public ExampleSet exampleSet() // throws RecognitionException [1] + { + ExampleSet exampleSet = default(ExampleSet); + + Text title_ = default(Text); + + Table table_ = default(Table); + + + try + { + // SpecFlowLangWalker.g:129:5: ( ^( EXAMPLESET (title_= text )? table_= table ) ) + // SpecFlowLangWalker.g:129:9: ^( EXAMPLESET (title_= text )? table_= table ) + { + Match(input,EXAMPLESET,FOLLOW_EXAMPLESET_in_exampleSet842); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:130:19: (title_= text )? + int alt12 = 2; + int LA12_0 = input.LA(1); + + if ( (LA12_0 == TEXT) ) + { + alt12 = 1; + } + switch (alt12) + { + case 1 : + // SpecFlowLangWalker.g:130:19: title_= text + { + PushFollow(FOLLOW_text_in_exampleSet858); + title_ = text(); + state.followingStackPointer--; + + + } + break; + + } + + PushFollow(FOLLOW_table_in_exampleSet875); + table_ = table(); + state.followingStackPointer--; + + + Match(input, Token.UP, null); + + } + + + exampleSet = new ExampleSet(title_, table_); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return exampleSet; + } + // $ANTLR end "exampleSet" + + + // $ANTLR start "steps" + // SpecFlowLangWalker.g:135:1: steps returns [ScenarioSteps steps] : ^( STEPS (step_= step )+ ) ; + public ScenarioSteps steps() // throws RecognitionException [1] + { + ScenarioSteps steps = default(ScenarioSteps); + + ScenarioStep step_ = default(ScenarioStep); + + + + steps = new ScenarioSteps(); + + try + { + // SpecFlowLangWalker.g:139:5: ( ^( STEPS (step_= step )+ ) ) + // SpecFlowLangWalker.g:139:9: ^( STEPS (step_= step )+ ) + { + Match(input,STEPS,FOLLOW_STEPS_in_steps913); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:140:13: (step_= step )+ + int cnt13 = 0; + do + { + int alt13 = 2; + int LA13_0 = input.LA(1); + + if ( ((LA13_0 >= GIVEN && LA13_0 <= THEN) || (LA13_0 >= AND && LA13_0 <= BUT)) ) + { + alt13 = 1; + } + + + switch (alt13) + { + case 1 : + // SpecFlowLangWalker.g:140:14: step_= step + { + PushFollow(FOLLOW_step_in_steps930); + step_ = step(); + state.followingStackPointer--; + + steps.Add(step_); + + } + break; + + default: + if ( cnt13 >= 1 ) goto loop13; + EarlyExitException eee13 = + new EarlyExitException(13, input); + throw eee13; + } + cnt13++; + } while (true); + + loop13: + ; // Stops C# compiler whinging that label 'loop13' has no statements + + + Match(input, Token.UP, null); + + } + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return steps; + } + // $ANTLR end "steps" + + + // $ANTLR start "step" + // SpecFlowLangWalker.g:144:1: step returns [ScenarioStep step] : ( ^( GIVEN text_= text (mlt_= multilineText )? (table_= table )? ) | ^( WHEN text_= text (mlt_= multilineText )? (table_= table )? ) | ^( THEN text_= text (mlt_= multilineText )? (table_= table )? ) | ^( AND text_= text (mlt_= multilineText )? (table_= table )? ) | ^( BUT text_= text (mlt_= multilineText )? (table_= table )? ) ); + public ScenarioStep step() // throws RecognitionException [1] + { + ScenarioStep step = default(ScenarioStep); + + Text text_ = default(Text); + + MultilineText mlt_ = default(MultilineText); + + Table table_ = default(Table); + + + try + { + // SpecFlowLangWalker.g:145:5: ( ^( GIVEN text_= text (mlt_= multilineText )? (table_= table )? ) | ^( WHEN text_= text (mlt_= multilineText )? (table_= table )? ) | ^( THEN text_= text (mlt_= multilineText )? (table_= table )? ) | ^( AND text_= text (mlt_= multilineText )? (table_= table )? ) | ^( BUT text_= text (mlt_= multilineText )? (table_= table )? ) ) + int alt24 = 5; + switch ( input.LA(1) ) + { + case GIVEN: + { + alt24 = 1; + } + break; + case WHEN: + { + alt24 = 2; + } + break; + case THEN: + { + alt24 = 3; + } + break; + case AND: + { + alt24 = 4; + } + break; + case BUT: + { + alt24 = 5; + } + break; + default: + NoViableAltException nvae_d24s0 = + new NoViableAltException("", 24, 0, input); + + throw nvae_d24s0; + } + + switch (alt24) + { + case 1 : + // SpecFlowLangWalker.g:145:9: ^( GIVEN text_= text (mlt_= multilineText )? (table_= table )? ) + { + Match(input,GIVEN,FOLLOW_GIVEN_in_step967); + + Match(input, Token.DOWN, null); + PushFollow(FOLLOW_text_in_step983); + text_ = text(); + state.followingStackPointer--; + + // SpecFlowLangWalker.g:147:17: (mlt_= multilineText )? + int alt14 = 2; + int LA14_0 = input.LA(1); + + if ( (LA14_0 == MULTILINETEXT) ) + { + alt14 = 1; + } + switch (alt14) + { + case 1 : + // SpecFlowLangWalker.g:147:17: mlt_= multilineText + { + PushFollow(FOLLOW_multilineText_in_step999); + mlt_ = multilineText(); + state.followingStackPointer--; + + + } + break; + + } + + // SpecFlowLangWalker.g:148:19: (table_= table )? + int alt15 = 2; + int LA15_0 = input.LA(1); + + if ( (LA15_0 == TABLE) ) + { + alt15 = 1; + } + switch (alt15) + { + case 1 : + // SpecFlowLangWalker.g:148:19: table_= table + { + PushFollow(FOLLOW_table_in_step1016); + table_ = table(); + state.followingStackPointer--; + + + } + break; + + } + + + Match(input, Token.UP, null); + + step = new Given(text_, mlt_, table_); + + + } + break; + case 2 : + // SpecFlowLangWalker.g:153:9: ^( WHEN text_= text (mlt_= multilineText )? (table_= table )? ) + { + Match(input,WHEN,FOLLOW_WHEN_in_step1048); + + Match(input, Token.DOWN, null); + PushFollow(FOLLOW_text_in_step1064); + text_ = text(); + state.followingStackPointer--; + + // SpecFlowLangWalker.g:155:17: (mlt_= multilineText )? + int alt16 = 2; + int LA16_0 = input.LA(1); + + if ( (LA16_0 == MULTILINETEXT) ) + { + alt16 = 1; + } + switch (alt16) + { + case 1 : + // SpecFlowLangWalker.g:155:17: mlt_= multilineText + { + PushFollow(FOLLOW_multilineText_in_step1080); + mlt_ = multilineText(); + state.followingStackPointer--; + + + } + break; + + } + + // SpecFlowLangWalker.g:156:19: (table_= table )? + int alt17 = 2; + int LA17_0 = input.LA(1); + + if ( (LA17_0 == TABLE) ) + { + alt17 = 1; + } + switch (alt17) + { + case 1 : + // SpecFlowLangWalker.g:156:19: table_= table + { + PushFollow(FOLLOW_table_in_step1097); + table_ = table(); + state.followingStackPointer--; + + + } + break; + + } + + + Match(input, Token.UP, null); + + step = new When(text_, mlt_, table_); + + + } + break; + case 3 : + // SpecFlowLangWalker.g:161:9: ^( THEN text_= text (mlt_= multilineText )? (table_= table )? ) + { + Match(input,THEN,FOLLOW_THEN_in_step1129); + + Match(input, Token.DOWN, null); + PushFollow(FOLLOW_text_in_step1145); + text_ = text(); + state.followingStackPointer--; + + // SpecFlowLangWalker.g:163:17: (mlt_= multilineText )? + int alt18 = 2; + int LA18_0 = input.LA(1); + + if ( (LA18_0 == MULTILINETEXT) ) + { + alt18 = 1; + } + switch (alt18) + { + case 1 : + // SpecFlowLangWalker.g:163:17: mlt_= multilineText + { + PushFollow(FOLLOW_multilineText_in_step1161); + mlt_ = multilineText(); + state.followingStackPointer--; + + + } + break; + + } + + // SpecFlowLangWalker.g:164:19: (table_= table )? + int alt19 = 2; + int LA19_0 = input.LA(1); + + if ( (LA19_0 == TABLE) ) + { + alt19 = 1; + } + switch (alt19) + { + case 1 : + // SpecFlowLangWalker.g:164:19: table_= table + { + PushFollow(FOLLOW_table_in_step1178); + table_ = table(); + state.followingStackPointer--; + + + } + break; + + } + + + Match(input, Token.UP, null); + + step = new Then(text_, mlt_, table_); + + + } + break; + case 4 : + // SpecFlowLangWalker.g:169:9: ^( AND text_= text (mlt_= multilineText )? (table_= table )? ) + { + Match(input,AND,FOLLOW_AND_in_step1210); + + Match(input, Token.DOWN, null); + PushFollow(FOLLOW_text_in_step1226); + text_ = text(); + state.followingStackPointer--; + + // SpecFlowLangWalker.g:171:17: (mlt_= multilineText )? + int alt20 = 2; + int LA20_0 = input.LA(1); + + if ( (LA20_0 == MULTILINETEXT) ) + { + alt20 = 1; + } + switch (alt20) + { + case 1 : + // SpecFlowLangWalker.g:171:17: mlt_= multilineText + { + PushFollow(FOLLOW_multilineText_in_step1242); + mlt_ = multilineText(); + state.followingStackPointer--; + + + } + break; + + } + + // SpecFlowLangWalker.g:172:19: (table_= table )? + int alt21 = 2; + int LA21_0 = input.LA(1); + + if ( (LA21_0 == TABLE) ) + { + alt21 = 1; + } + switch (alt21) + { + case 1 : + // SpecFlowLangWalker.g:172:19: table_= table + { + PushFollow(FOLLOW_table_in_step1259); + table_ = table(); + state.followingStackPointer--; + + + } + break; + + } + + + Match(input, Token.UP, null); + + step = new And(text_, mlt_, table_); + + + } + break; + case 5 : + // SpecFlowLangWalker.g:177:9: ^( BUT text_= text (mlt_= multilineText )? (table_= table )? ) + { + Match(input,BUT,FOLLOW_BUT_in_step1291); + + Match(input, Token.DOWN, null); + PushFollow(FOLLOW_text_in_step1307); + text_ = text(); + state.followingStackPointer--; + + // SpecFlowLangWalker.g:179:17: (mlt_= multilineText )? + int alt22 = 2; + int LA22_0 = input.LA(1); + + if ( (LA22_0 == MULTILINETEXT) ) + { + alt22 = 1; + } + switch (alt22) + { + case 1 : + // SpecFlowLangWalker.g:179:17: mlt_= multilineText + { + PushFollow(FOLLOW_multilineText_in_step1323); + mlt_ = multilineText(); + state.followingStackPointer--; + + + } + break; + + } + + // SpecFlowLangWalker.g:180:19: (table_= table )? + int alt23 = 2; + int LA23_0 = input.LA(1); + + if ( (LA23_0 == TABLE) ) + { + alt23 = 1; + } + switch (alt23) + { + case 1 : + // SpecFlowLangWalker.g:180:19: table_= table + { + PushFollow(FOLLOW_table_in_step1340); + table_ = table(); + state.followingStackPointer--; + + + } + break; + + } + + + Match(input, Token.UP, null); + + step = new But(text_, mlt_, table_); + + + } + break; + + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return step; + } + // $ANTLR end "step" + + + // $ANTLR start "text" + // SpecFlowLangWalker.g:188:1: text returns [Text text] : ^( TEXT f= wordchar (ws= WS | wc= wordchar | nl= NEWLINE )* ) ; + public Text text() // throws RecognitionException [1] + { + Text text = default(Text); + + CommonTree ws = null; + CommonTree nl = null; + string f = default(string); + + string wc = default(string); + + + + var elements = new List(); + + try + { + // SpecFlowLangWalker.g:195:5: ( ^( TEXT f= wordchar (ws= WS | wc= wordchar | nl= NEWLINE )* ) ) + // SpecFlowLangWalker.g:195:9: ^( TEXT f= wordchar (ws= WS | wc= wordchar | nl= NEWLINE )* ) + { + Match(input,TEXT,FOLLOW_TEXT_in_text1395); + + Match(input, Token.DOWN, null); + PushFollow(FOLLOW_wordchar_in_text1412); + f = wordchar(); + state.followingStackPointer--; + + elements.Add(f); + // SpecFlowLangWalker.g:197:13: (ws= WS | wc= wordchar | nl= NEWLINE )* + do + { + int alt25 = 4; + switch ( input.LA(1) ) + { + case WS: + { + alt25 = 1; + } + break; + case AT: + case WORDCHAR: + { + alt25 = 2; + } + break; + case NEWLINE: + { + alt25 = 3; + } + break; + + } + + switch (alt25) + { + case 1 : + // SpecFlowLangWalker.g:197:17: ws= WS + { + ws=(CommonTree)Match(input,WS,FOLLOW_WS_in_text1443); + elements.Add(ws.Text); + + } + break; + case 2 : + // SpecFlowLangWalker.g:198:17: wc= wordchar + { + PushFollow(FOLLOW_wordchar_in_text1475); + wc = wordchar(); + state.followingStackPointer--; + + elements.Add(wc); + + } + break; + case 3 : + // SpecFlowLangWalker.g:199:17: nl= NEWLINE + { + nl=(CommonTree)Match(input,NEWLINE,FOLLOW_NEWLINE_in_text1501); + elements.Add(nl.Text); + + } + break; + + default: + goto loop25; + } + } while (true); + + loop25: + ; // Stops C# compiler whining that label 'loop25' has no statements + + + Match(input, Token.UP, null); + + } + + + text = new Text(elements.ToArray()); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return text; + } + // $ANTLR end "text" + + + // $ANTLR start "wordchar" + // SpecFlowLangWalker.g:204:1: wordchar returns [string text] : (wc= WORDCHAR | at= AT ); + public string wordchar() // throws RecognitionException [1] + { + string text = default(string); + + CommonTree wc = null; + CommonTree at = null; + + try + { + // SpecFlowLangWalker.g:205:5: (wc= WORDCHAR | at= AT ) + int alt26 = 2; + int LA26_0 = input.LA(1); + + if ( (LA26_0 == WORDCHAR) ) + { + alt26 = 1; + } + else if ( (LA26_0 == AT) ) + { + alt26 = 2; + } + else + { + NoViableAltException nvae_d26s0 = + new NoViableAltException("", 26, 0, input); + + throw nvae_d26s0; + } + switch (alt26) + { + case 1 : + // SpecFlowLangWalker.g:205:9: wc= WORDCHAR + { + wc=(CommonTree)Match(input,WORDCHAR,FOLLOW_WORDCHAR_in_wordchar1557); + text = wc.Text; + + } + break; + case 2 : + // SpecFlowLangWalker.g:206:9: at= AT + { + at=(CommonTree)Match(input,AT,FOLLOW_AT_in_wordchar1571); + @text = at.Text; + + } + break; + + } + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return text; + } + // $ANTLR end "wordchar" + + + // $ANTLR start "multilineText" + // SpecFlowLangWalker.g:209:1: multilineText returns [MultilineText multilineText] : ^( MULTILINETEXT (line_= line )* indent_= indent ) ; + public MultilineText multilineText() // throws RecognitionException [1] + { + MultilineText multilineText = default(MultilineText); + + string line_ = default(string); + + string indent_ = default(string); + + + + var lines = new StringBuilder(); + + try + { + // SpecFlowLangWalker.g:216:5: ( ^( MULTILINETEXT (line_= line )* indent_= indent ) ) + // SpecFlowLangWalker.g:216:9: ^( MULTILINETEXT (line_= line )* indent_= indent ) + { + Match(input,MULTILINETEXT,FOLLOW_MULTILINETEXT_in_multilineText1612); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:217:13: (line_= line )* + do + { + int alt27 = 2; + int LA27_0 = input.LA(1); + + if ( (LA27_0 == LINE) ) + { + alt27 = 1; + } + + + switch (alt27) + { + case 1 : + // SpecFlowLangWalker.g:217:14: line_= line + { + PushFollow(FOLLOW_line_in_multilineText1629); + line_ = line(); + state.followingStackPointer--; + + lines.Append(line_); + + } + break; + + default: + goto loop27; + } + } while (true); + + loop27: + ; // Stops C# compiler whining that label 'loop27' has no statements + + PushFollow(FOLLOW_indent_in_multilineText1649); + indent_ = indent(); + state.followingStackPointer--; + + + Match(input, Token.UP, null); + + } + + + multilineText = new MultilineText(lines.ToString(), indent_); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return multilineText; + } + // $ANTLR end "multilineText" + + + // $ANTLR start "line" + // SpecFlowLangWalker.g:222:1: line returns [string line] : ^( LINE (ws= WS )? (text_= text )? nl= NEWLINE ) ; + public string line() // throws RecognitionException [1] + { + string line = default(string); + + CommonTree ws = null; + CommonTree nl = null; + Text text_ = default(Text); + + + + var buffer = new StringBuilder(); + + try + { + // SpecFlowLangWalker.g:229:5: ( ^( LINE (ws= WS )? (text_= text )? nl= NEWLINE ) ) + // SpecFlowLangWalker.g:229:9: ^( LINE (ws= WS )? (text_= text )? nl= NEWLINE ) + { + Match(input,LINE,FOLLOW_LINE_in_line1695); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:230:13: (ws= WS )? + int alt28 = 2; + int LA28_0 = input.LA(1); + + if ( (LA28_0 == WS) ) + { + alt28 = 1; + } + switch (alt28) + { + case 1 : + // SpecFlowLangWalker.g:230:14: ws= WS + { + ws=(CommonTree)Match(input,WS,FOLLOW_WS_in_line1712); + buffer.Append(ws.Text); + + } + break; + + } + + // SpecFlowLangWalker.g:231:13: (text_= text )? + int alt29 = 2; + int LA29_0 = input.LA(1); + + if ( (LA29_0 == TEXT) ) + { + alt29 = 1; + } + switch (alt29) + { + case 1 : + // SpecFlowLangWalker.g:231:14: text_= text + { + PushFollow(FOLLOW_text_in_line1742); + text_ = text(); + state.followingStackPointer--; + + buffer.Append(text_.Value); + + } + break; + + } + + nl=(CommonTree)Match(input,NEWLINE,FOLLOW_NEWLINE_in_line1766); + buffer.Append(nl.Text); + + Match(input, Token.UP, null); + + } + + + line = buffer.ToString(); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return line; + } + // $ANTLR end "line" + + + // $ANTLR start "indent" + // SpecFlowLangWalker.g:236:1: indent returns [string indent] : ^( INDENT (ws= WS )? ) ; + public string indent() // throws RecognitionException [1] + { + string indent = default(string); + + CommonTree ws = null; + + + indent = ""; + + try + { + // SpecFlowLangWalker.g:240:5: ( ^( INDENT (ws= WS )? ) ) + // SpecFlowLangWalker.g:240:9: ^( INDENT (ws= WS )? ) + { + Match(input,INDENT,FOLLOW_INDENT_in_indent1811); + + if ( input.LA(1) == Token.DOWN ) + { + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:241:13: (ws= WS )? + int alt30 = 2; + int LA30_0 = input.LA(1); + + if ( (LA30_0 == WS) ) + { + alt30 = 1; + } + switch (alt30) + { + case 1 : + // SpecFlowLangWalker.g:241:14: ws= WS + { + ws=(CommonTree)Match(input,WS,FOLLOW_WS_in_indent1828); + indent = ws.Text; + + } + break; + + } + + + Match(input, Token.UP, null); + } + + } + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return indent; + } + // $ANTLR end "indent" + + + // $ANTLR start "table" + // SpecFlowLangWalker.g:245:1: table returns [Table table] : ^( TABLE ^( HEADER header_= tableRow ) ^( BODY (row_= tableRow )+ ) ) ; + public Table table() // throws RecognitionException [1] + { + Table table = default(Table); + + Row header_ = default(Row); + + Row row_ = default(Row); + + + + var bodyRows = new List(); + + try + { + // SpecFlowLangWalker.g:252:5: ( ^( TABLE ^( HEADER header_= tableRow ) ^( BODY (row_= tableRow )+ ) ) ) + // SpecFlowLangWalker.g:252:9: ^( TABLE ^( HEADER header_= tableRow ) ^( BODY (row_= tableRow )+ ) ) + { + Match(input,TABLE,FOLLOW_TABLE_in_table1876); + + Match(input, Token.DOWN, null); + Match(input,HEADER,FOLLOW_HEADER_in_table1891); + + Match(input, Token.DOWN, null); + PushFollow(FOLLOW_tableRow_in_table1895); + header_ = tableRow(); + state.followingStackPointer--; + + + Match(input, Token.UP, null); + Match(input,BODY,FOLLOW_BODY_in_table1911); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:254:20: (row_= tableRow )+ + int cnt31 = 0; + do + { + int alt31 = 2; + int LA31_0 = input.LA(1); + + if ( (LA31_0 == ROW) ) + { + alt31 = 1; + } + + + switch (alt31) + { + case 1 : + // SpecFlowLangWalker.g:254:21: row_= tableRow + { + PushFollow(FOLLOW_tableRow_in_table1916); + row_ = tableRow(); + state.followingStackPointer--; + + bodyRows.Add(row_); + + } + break; + + default: + if ( cnt31 >= 1 ) goto loop31; + EarlyExitException eee31 = + new EarlyExitException(31, input); + throw eee31; + } + cnt31++; + } while (true); + + loop31: + ; // Stops C# compiler whinging that label 'loop31' has no statements + + + Match(input, Token.UP, null); + + Match(input, Token.UP, null); + + } + + + table = new Table(header_, bodyRows.ToArray()); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return table; + } + // $ANTLR end "table" + + + // $ANTLR start "tableRow" + // SpecFlowLangWalker.g:258:1: tableRow returns [Row row] : ^( ROW (cell_= tableCell )+ ) ; + public Row tableRow() // throws RecognitionException [1] + { + Row row = default(Row); + + Cell cell_ = default(Cell); + + + + var cells = new List(); + + try + { + // SpecFlowLangWalker.g:265:5: ( ^( ROW (cell_= tableCell )+ ) ) + // SpecFlowLangWalker.g:265:9: ^( ROW (cell_= tableCell )+ ) + { + Match(input,ROW,FOLLOW_ROW_in_tableRow1964); + + Match(input, Token.DOWN, null); + // SpecFlowLangWalker.g:266:13: (cell_= tableCell )+ + int cnt32 = 0; + do + { + int alt32 = 2; + int LA32_0 = input.LA(1); + + if ( (LA32_0 == CELL) ) + { + alt32 = 1; + } + + + switch (alt32) + { + case 1 : + // SpecFlowLangWalker.g:266:14: cell_= tableCell + { + PushFollow(FOLLOW_tableCell_in_tableRow1981); + cell_ = tableCell(); + state.followingStackPointer--; + + cells.Add(cell_); + + } + break; + + default: + if ( cnt32 >= 1 ) goto loop32; + EarlyExitException eee32 = + new EarlyExitException(32, input); + throw eee32; + } + cnt32++; + } while (true); + + loop32: + ; // Stops C# compiler whinging that label 'loop32' has no statements + + + Match(input, Token.UP, null); + + } + + + row = new Row(cells.ToArray()); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return row; + } + // $ANTLR end "tableRow" + + + // $ANTLR start "tableCell" + // SpecFlowLangWalker.g:270:1: tableCell returns [Cell cell] : ^( CELL text_= text ) ; + public Cell tableCell() // throws RecognitionException [1] + { + Cell cell = default(Cell); + + Text text_ = default(Text); + + + try + { + // SpecFlowLangWalker.g:274:5: ( ^( CELL text_= text ) ) + // SpecFlowLangWalker.g:274:9: ^( CELL text_= text ) + { + Match(input,CELL,FOLLOW_CELL_in_tableCell2023); + + Match(input, Token.DOWN, null); + PushFollow(FOLLOW_text_in_tableCell2039); + text_ = text(); + state.followingStackPointer--; + + + Match(input, Token.UP, null); + + } + + + cell = new Cell(text_); + + } + catch (RecognitionException re) + { + ReportError(re); + Recover(input,re); + } + finally + { + } + return cell; + } + // $ANTLR end "tableCell" + + // Delegated rules + + + private void InitializeCyclicDFAs() + { + } + + + + public static readonly BitSet FOLLOW_FEATURE_in_feature73 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_tags_in_feature90 = new BitSet(new ulong[]{0x0000000000010000UL}); + public static readonly BitSet FOLLOW_text_in_feature108 = new BitSet(new ulong[]{0x00000000000000E0UL}); + public static readonly BitSet FOLLOW_descriptionLine_in_feature125 = new BitSet(new ulong[]{0x00000000000000E0UL}); + public static readonly BitSet FOLLOW_background_in_feature146 = new BitSet(new ulong[]{0x0000000000000080UL}); + public static readonly BitSet FOLLOW_SCENARIOS_in_feature163 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_scenarioKind_in_feature185 = new BitSet(new ulong[]{0x0000000000000308UL}); + public static readonly BitSet FOLLOW_TAGS_in_tags243 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_tag_in_tags260 = new BitSet(new ulong[]{0x0000000000100008UL}); + public static readonly BitSet FOLLOW_TAG_in_tag302 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_word_in_tag318 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_WORD_in_word361 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_WORDCHAR_in_word378 = new BitSet(new ulong[]{0x0000000100000008UL}); + public static readonly BitSet FOLLOW_DESCRIPTIONLINE_in_descriptionLine420 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_text_in_descriptionLine436 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_BACKGROUND_in_background474 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_text_in_background491 = new BitSet(new ulong[]{0x0000000000001000UL}); + public static readonly BitSet FOLLOW_steps_in_background509 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_scenario_in_scenarioKind543 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_scenarioOutline_in_scenarioKind557 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_SCENARIOOUTLINE_in_scenarioOutline587 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_tags_in_scenarioOutline603 = new BitSet(new ulong[]{0x0000000000010000UL}); + public static readonly BitSet FOLLOW_text_in_scenarioOutline620 = new BitSet(new ulong[]{0x0000000000001000UL}); + public static readonly BitSet FOLLOW_steps_in_scenarioOutline636 = new BitSet(new ulong[]{0x0000000000000400UL}); + public static readonly BitSet FOLLOW_examples_in_scenarioOutline652 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_SCENARIO_in_scenario690 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_tags_in_scenario707 = new BitSet(new ulong[]{0x0000000000010000UL}); + public static readonly BitSet FOLLOW_text_in_scenario724 = new BitSet(new ulong[]{0x0000000000001000UL}); + public static readonly BitSet FOLLOW_steps_in_scenario740 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_EXAMPLES_in_examples783 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_exampleSet_in_examples800 = new BitSet(new ulong[]{0x0000000000000808UL}); + public static readonly BitSet FOLLOW_EXAMPLESET_in_exampleSet842 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_text_in_exampleSet858 = new BitSet(new ulong[]{0x0000000002000000UL}); + public static readonly BitSet FOLLOW_table_in_exampleSet875 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_STEPS_in_steps913 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_step_in_steps930 = new BitSet(new ulong[]{0x000000000006E008UL}); + public static readonly BitSet FOLLOW_GIVEN_in_step967 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_text_in_step983 = new BitSet(new ulong[]{0x0000000002400008UL}); + public static readonly BitSet FOLLOW_multilineText_in_step999 = new BitSet(new ulong[]{0x0000000002000008UL}); + public static readonly BitSet FOLLOW_table_in_step1016 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_WHEN_in_step1048 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_text_in_step1064 = new BitSet(new ulong[]{0x0000000002400008UL}); + public static readonly BitSet FOLLOW_multilineText_in_step1080 = new BitSet(new ulong[]{0x0000000002000008UL}); + public static readonly BitSet FOLLOW_table_in_step1097 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_THEN_in_step1129 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_text_in_step1145 = new BitSet(new ulong[]{0x0000000002400008UL}); + public static readonly BitSet FOLLOW_multilineText_in_step1161 = new BitSet(new ulong[]{0x0000000002000008UL}); + public static readonly BitSet FOLLOW_table_in_step1178 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_AND_in_step1210 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_text_in_step1226 = new BitSet(new ulong[]{0x0000000002400008UL}); + public static readonly BitSet FOLLOW_multilineText_in_step1242 = new BitSet(new ulong[]{0x0000000002000008UL}); + public static readonly BitSet FOLLOW_table_in_step1259 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_BUT_in_step1291 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_text_in_step1307 = new BitSet(new ulong[]{0x0000000002400008UL}); + public static readonly BitSet FOLLOW_multilineText_in_step1323 = new BitSet(new ulong[]{0x0000000002000008UL}); + public static readonly BitSet FOLLOW_table_in_step1340 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_TEXT_in_text1395 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_wordchar_in_text1412 = new BitSet(new ulong[]{0x00000005C0000008UL}); + public static readonly BitSet FOLLOW_WS_in_text1443 = new BitSet(new ulong[]{0x00000005C0000008UL}); + public static readonly BitSet FOLLOW_wordchar_in_text1475 = new BitSet(new ulong[]{0x00000005C0000008UL}); + public static readonly BitSet FOLLOW_NEWLINE_in_text1501 = new BitSet(new ulong[]{0x00000005C0000008UL}); + public static readonly BitSet FOLLOW_WORDCHAR_in_wordchar1557 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_AT_in_wordchar1571 = new BitSet(new ulong[]{0x0000000000000002UL}); + public static readonly BitSet FOLLOW_MULTILINETEXT_in_multilineText1612 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_line_in_multilineText1629 = new BitSet(new ulong[]{0x0000000001800000UL}); + public static readonly BitSet FOLLOW_indent_in_multilineText1649 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_LINE_in_line1695 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_WS_in_line1712 = new BitSet(new ulong[]{0x0000000400010000UL}); + public static readonly BitSet FOLLOW_text_in_line1742 = new BitSet(new ulong[]{0x0000000400000000UL}); + public static readonly BitSet FOLLOW_NEWLINE_in_line1766 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_INDENT_in_indent1811 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_WS_in_indent1828 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_TABLE_in_table1876 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_HEADER_in_table1891 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_tableRow_in_table1895 = new BitSet(new ulong[]{0x0000000000000008UL}); + public static readonly BitSet FOLLOW_BODY_in_table1911 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_tableRow_in_table1916 = new BitSet(new ulong[]{0x0000000010000008UL}); + public static readonly BitSet FOLLOW_ROW_in_tableRow1964 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_tableCell_in_tableRow1981 = new BitSet(new ulong[]{0x0000000020000008UL}); + public static readonly BitSet FOLLOW_CELL_in_tableCell2023 = new BitSet(new ulong[]{0x0000000000000004UL}); + public static readonly BitSet FOLLOW_text_in_tableCell2039 = new BitSet(new ulong[]{0x0000000000000008UL}); + +} +} \ No newline at end of file diff --git a/Parser/Grammar/SpecFlowLangWalker.g b/Parser/Grammar/SpecFlowLangWalker.g new file mode 100644 index 000000000..44aa6b8d9 --- /dev/null +++ b/Parser/Grammar/SpecFlowLangWalker.g @@ -0,0 +1,277 @@ +tree grammar SpecFlowLangWalker; + +options { + language = CSharp2; + tokenVocab = SpecFlowLang; + ASTLabelType = CommonTree; +} + +@namespace { TechTalk.SpecFlow.Parser.Grammar } +@header +{ +using System.Collections.Generic; +using System.Text; +using TechTalk.SpecFlow.Parser.SyntaxElements; +} + +feature returns[Feature feature] +@init { + var scenarios = new List(); + var descLines = new List(); +} +@after { + $feature = new Feature(title_, tags_, descLines.ToArray(), background_, scenarios.ToArray()); +} + : ^(FEATURE + (tags_=tags)? + title_=text + (descLine_=descriptionLine { descLines.Add(descLine_); })* + (background_=background)? + ^(SCENARIOS + (scenario_=scenarioKind { scenarios.Add(scenario_); } )* + ) + ) + ; + +tags returns[Tags tags] +@init { + $tags = new Tags(); +} + : ^(TAGS + (tag_=tag { $tags.Add(tag_); })+ + ) + ; + +tag returns[Tag tag] +@after { + $tag = new Tag(word_); +} + : ^(TAG + word_=word + ) + ; + +word returns[Word word] +@init { + var wordBuffer = new StringBuilder(); +} +@after { + $word = new Word(wordBuffer.ToString()); +} + : ^(WORD + (char_=WORDCHAR { wordBuffer.Append(char_.Text); })+ + ) + ; + +descriptionLine returns[DescriptionLine descriptionLine] +@after { + $descriptionLine = new DescriptionLine(text_); +} + : ^(DESCRIPTIONLINE + text_=text + ) + ; + +background returns[Background background] +@after { + $background = new Background(title_, steps_); +} + : ^(BACKGROUND + (title_=text)? + steps_=steps + ) + ; + +scenarioKind returns[Scenario scenarioKind] + : scenario_=scenario { $scenarioKind = scenario_; } + | outline_=scenarioOutline { $scenarioKind = outline_; } + ; + +scenarioOutline returns[ScenarioOutline outline] +@after { + $outline = new ScenarioOutline(title_, tags_, steps_, examples_); +} + : ^(SCENARIOOUTLINE + tags_=tags? + title_=text + steps_=steps + examples_=examples + ) + ; + +scenario returns[Scenario scenario] +@after { + $scenario = new Scenario(title_, tags_, steps_); +} + : ^(SCENARIO + tags_=tags? + title_=text + steps_=steps + ) + ; + +examples returns[Examples examples] +@init { + var exampleSets = new List(); +} +@after { + $examples = new Examples(exampleSets.ToArray()); +} + : ^(EXAMPLES + (exampleSet_=exampleSet { exampleSets.Add(exampleSet_); })+ + ) + ; + +exampleSet returns[ExampleSet exampleSet] +@after { + $exampleSet = new ExampleSet(title_, table_); +} + : ^(EXAMPLESET + title_=text? + table_=table + ) + ; + +steps returns[ScenarioSteps steps] +@init { + $steps = new ScenarioSteps(); +} + : ^(STEPS + (step_=step { $steps.Add(step_); })+ + ) + ; + +step returns[ScenarioStep step] + : ^(GIVEN + text_=text + mlt_=multilineText? + table_=table? + ) + { + $step = new Given(text_, mlt_, table_); + } + | ^(WHEN + text_=text + mlt_=multilineText? + table_=table? + ) + { + $step = new When(text_, mlt_, table_); + } + | ^(THEN + text_=text + mlt_=multilineText? + table_=table? + ) + { + $step = new Then(text_, mlt_, table_); + } + | ^(AND + text_=text + mlt_=multilineText? + table_=table? + ) + { + $step = new And(text_, mlt_, table_); + } + | ^(BUT + text_=text + mlt_=multilineText? + table_=table? + ) + { + $step = new But(text_, mlt_, table_); + } + ; + + +text returns[Text text] +@init { + var elements = new List(); +} +@after { + text = new Text(elements.ToArray()); +} + : ^(TEXT + f=wordchar { elements.Add(f); } + ( ws=WS { elements.Add(ws.Text); } + | wc=wordchar { elements.Add(wc); } + | nl=NEWLINE { elements.Add(nl.Text); } + )* + ) + ; + +wordchar returns[string text] + : wc=WORDCHAR { $text = wc.Text; } + | at=AT { @text = at.Text; } + ; + +multilineText returns[MultilineText multilineText] +@init { + var lines = new StringBuilder(); +} +@after { + $multilineText = new MultilineText(lines.ToString(), indent_); +} + : ^(MULTILINETEXT + (line_=line { lines.Append(line_); })* + indent_=indent + ) + ; + +line returns[string line] +@init { + var buffer = new StringBuilder(); +} +@after { + $line = buffer.ToString(); +} + : ^(LINE + (ws=WS { buffer.Append(ws.Text); })? + (text_=text { buffer.Append(text_.Value); })? + nl=NEWLINE { buffer.Append(nl.Text); } + ) + ; + +indent returns[string indent] +@init { + $indent = ""; +} + : ^(INDENT + (ws=WS { $indent = ws.Text; } )? + ) + ; + +table returns[Table table] +@init { + var bodyRows = new List(); +} +@after { + $table = new Table(header_, bodyRows.ToArray()); +} + : ^(TABLE + ^(HEADER header_=tableRow) + ^(BODY (row_=tableRow { bodyRows.Add(row_); })+) + ) + ; + +tableRow returns[Row row] +@init { + var cells = new List(); +} +@after { + $row = new Row(cells.ToArray()); +} + : ^(ROW + (cell_=tableCell { cells.Add(cell_); })+ + ) + ; + +tableCell returns[Cell cell] +@after { + $cell = new Cell(text_); +} + : ^(CELL + text_=text + ) + ; diff --git a/Parser/Grammar/compile.cmd b/Parser/Grammar/compile.cmd new file mode 100644 index 000000000..3cb4e3273 --- /dev/null +++ b/Parser/Grammar/compile.cmd @@ -0,0 +1,6 @@ +pushd "%~dp0" + +java -cp ..\..\lib\antlr\antlr-3.1.2.jar org.antlr.Tool SpecFlowLang.g +java -cp ..\..\lib\antlr\antlr-3.1.2.jar org.antlr.Tool SpecFlowLangWalker.g + +popd diff --git a/Parser/IUnitTestConverter.cs b/Parser/IUnitTestConverter.cs new file mode 100644 index 000000000..67d9ec41a --- /dev/null +++ b/Parser/IUnitTestConverter.cs @@ -0,0 +1,20 @@ +using System; +using System.CodeDom; +using System.Collections.Generic; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser +{ + public interface IUnitTestConverter + { + void SetTestFixture(CodeTypeDeclaration typeDeclaration, string title, string description); + void SetTestFixtureCategories(CodeTypeDeclaration typeDeclaration, IEnumerable categories); + void SetTest(CodeMemberMethod memberMethod, string title); + void SetTestCategories(CodeMemberMethod memberMethod, IEnumerable categories); + void SetTestSetup(CodeMemberMethod memberMethod); + void SetTestFixtureSetup(CodeMemberMethod memberMethod); + void SetTestFixtureTearDown(CodeMemberMethod memberMethod); + void SetTestTearDown(CodeMemberMethod memberMethod); + void SetIgnore(CodeTypeMember codeTypeMember); + } +} \ No newline at end of file diff --git a/Parser/NUnitTestConverter.cs b/Parser/NUnitTestConverter.cs new file mode 100644 index 000000000..3b9df95f4 --- /dev/null +++ b/Parser/NUnitTestConverter.cs @@ -0,0 +1,104 @@ +using System; +using System.CodeDom; +using System.Collections.Generic; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser +{ + public class NUnitTestConverter : IUnitTestConverter + { + private const string TESTFIXTURE_ATTR = "NUnit.Framework.TestFixtureAttribute"; + private const string TEST_ATTR = "NUnit.Framework.TestAttribute"; + private const string CATEGORY_ATTR = "NUnit.Framework.CategoryAttribute"; + private const string TESTSETUP_ATTR = "NUnit.Framework.SetUpAttribute"; + private const string TESTFIXTURESETUP_ATTR = "NUnit.Framework.TestFixtureSetUpAttribute"; + private const string TESTFIXTURETEARDOWN_ATTR = "NUnit.Framework.TestFixtureTearDownAttribute"; + private const string TESTTEARDOWN_ATTR = "NUnit.Framework.TearDownAttribute"; + private const string IGNORE_ATTR = "NUnit.Framework.IgnoreAttribute"; + private const string DESCRIPTION_ATTR = "NUnit.Framework.DescriptionAttribute"; + + public void SetTestFixture(CodeTypeDeclaration typeDeclaration, string title, string description) + { + typeDeclaration.CustomAttributes.Add( + new CodeAttributeDeclaration( + new CodeTypeReference(TESTFIXTURE_ATTR))); + + SetDescription(typeDeclaration.CustomAttributes, title); + } + + private void SetDescription(CodeAttributeDeclarationCollection customAttributes, string description) + { + customAttributes.Add( + new CodeAttributeDeclaration( + new CodeTypeReference(DESCRIPTION_ATTR), + new CodeAttributeArgument( + new CodePrimitiveExpression(description)))); + } + + private void SetCategories(CodeAttributeDeclarationCollection customAttributes, IEnumerable categories) + { + foreach (var category in categories) + { + customAttributes.Add( + new CodeAttributeDeclaration( + new CodeTypeReference(CATEGORY_ATTR), + new CodeAttributeArgument( + new CodePrimitiveExpression(category)))); + } + } + + public void SetTestFixtureCategories(CodeTypeDeclaration typeDeclaration, IEnumerable categories) + { + SetCategories(typeDeclaration.CustomAttributes, categories); + } + + public void SetTest(CodeMemberMethod memberMethod, string title) + { + memberMethod.CustomAttributes.Add( + new CodeAttributeDeclaration( + new CodeTypeReference(TEST_ATTR))); + + SetDescription(memberMethod.CustomAttributes, title); + } + + public void SetTestCategories(CodeMemberMethod memberMethod, IEnumerable categories) + { + SetCategories(memberMethod.CustomAttributes, categories); + } + + public void SetTestSetup(CodeMemberMethod memberMethod) + { + memberMethod.CustomAttributes.Add( + new CodeAttributeDeclaration( + new CodeTypeReference(TESTSETUP_ATTR))); + } + + public void SetTestFixtureSetup(CodeMemberMethod memberMethod) + { + memberMethod.CustomAttributes.Add( + new CodeAttributeDeclaration( + new CodeTypeReference(TESTFIXTURESETUP_ATTR))); + } + + public void SetTestFixtureTearDown(CodeMemberMethod memberMethod) + { + memberMethod.CustomAttributes.Add( + new CodeAttributeDeclaration( + new CodeTypeReference(TESTFIXTURETEARDOWN_ATTR))); + } + + public void SetTestTearDown(CodeMemberMethod memberMethod) + { + memberMethod.CustomAttributes.Add( + new CodeAttributeDeclaration( + new CodeTypeReference(TESTTEARDOWN_ATTR))); + } + + public void SetIgnore(CodeTypeMember codeTypeMember) + { + codeTypeMember.CustomAttributes.Add( + new CodeAttributeDeclaration( + new CodeTypeReference(IGNORE_ATTR))); + } + } +} \ No newline at end of file diff --git a/Parser/Properties/AssemblyInfo.cs b/Parser/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..bba5c3e67 --- /dev/null +++ b/Parser/Properties/AssemblyInfo.cs @@ -0,0 +1,24 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 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("TechTalk.SpecFlow.Parser")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TechTalk.SpecFlow.Parser")] +[assembly: AssemblyCopyright("Copyright © 2009")] +[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)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9d1b09a6-4601-44a2-9849-08f512ab832b")] + diff --git a/Parser/SpecFlowLangParser.cs b/Parser/SpecFlowLangParser.cs new file mode 100644 index 000000000..7dc959814 --- /dev/null +++ b/Parser/SpecFlowLangParser.cs @@ -0,0 +1,41 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; +using Antlr.Runtime; +using Antlr.Runtime.Tree; +using TechTalk.SpecFlow.Parser.SyntaxElements; + +namespace TechTalk.SpecFlow.Parser +{ + public class SpecFlowLangParser + { + public Feature Parse(TextReader featureFileReader) + { + var fileContent = featureFileReader.ReadToEnd() + Environment.NewLine; + + var inputStream = new ANTLRReaderStream(new StringReader(fileContent)); + var lexer = new Grammar.SpecFlowLangLexer(inputStream); + var tokenStream = new CommonTokenStream(lexer); + var parser = new Grammar.SpecFlowLangParser(tokenStream); + + var featureTree = parser.feature().Tree as CommonTree; + + if (featureTree == null || parser.ParserErrors.Count > 0 || lexer.LexerErrors.Count > 0) + { + throw new SpecFlowParserException("Invalid Gherkin file!", lexer.LexerErrors.Concat(parser.ParserErrors).ToArray()); + } + + var walker = new Grammar.SpecFlowLangWalker(new CommonTreeNodeStream(featureTree)); + + Feature feature = walker.feature(); + + if (feature == null) + throw new SpecFlowParserException("Invalid Gherkin file!"); + + return feature; + } + } +} diff --git a/Parser/SpecFlowParserException.cs b/Parser/SpecFlowParserException.cs new file mode 100644 index 000000000..46bc3002c --- /dev/null +++ b/Parser/SpecFlowParserException.cs @@ -0,0 +1,48 @@ +using System; +using System.Linq; +using System.Runtime.Serialization; + +namespace TechTalk.SpecFlow.Parser +{ + [Serializable] + public class SpecFlowParserException : Exception + { + public string[] DetailedErrors { get; private set; } + + public override string Message + { + get + { + if (DetailedErrors != null) + return string.Format("{0}{1}{2}", + base.Message, + Environment.NewLine, + string.Join(Environment.NewLine, DetailedErrors)); + return base.Message; + } + } + + public SpecFlowParserException() + { + } + + public SpecFlowParserException(string message) : base(message) + { + } + + public SpecFlowParserException(string message, string[] detailedErrors) : base(message) + { + DetailedErrors = detailedErrors; + } + + public SpecFlowParserException(string message, Exception inner) : base(message, inner) + { + } + + protected SpecFlowParserException( + SerializationInfo info, + StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/Parser/SpecFlowUnitTestConverter.cs b/Parser/SpecFlowUnitTestConverter.cs new file mode 100644 index 000000000..26b5210ff --- /dev/null +++ b/Parser/SpecFlowUnitTestConverter.cs @@ -0,0 +1,469 @@ +using System; +using System.CodeDom; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using TechTalk.SpecFlow.Parser.SyntaxElements; + +namespace TechTalk.SpecFlow.Parser +{ + public class SpecFlowUnitTestConverter + { + private const string DEFAULT_NAMESPACE = "SpecFlowTests"; + const string FIXTURE_FORMAT = "{0}Feature"; + const string TEST_FORMAT = "{0}"; + private const string IGNORE_TAG = "Ignore"; + private const string SETUP_NAME = "ScenarioSetup"; + private const string TEARDOWN_NAME = "ScenarioTearDown"; + private const string FIXTURESETUP_NAME = "FeatureSetup"; + private const string FIXTURETEARDOWN_NAME = "FeatureTearDown"; + private const string BACKGROUND_NAME = "FeatureBackground"; + private const string TESTRUNNER_FIELD = "testRunner"; + private const string ITESTRUNNER_TYPE = "TechTalk.SpecFlow.ITestRunner"; + private const string TESTRUNNERMANAGER_TYPE = "TechTalk.SpecFlow.TestRunnerManager"; + private const string FEATUREINFO_TYPE = "TechTalk.SpecFlow.FeatureInfo"; + private const string SCENARIOINFO_TYPE = "TechTalk.SpecFlow.ScenarioInfo"; + private const string TABLE_TYPE = "TechTalk.SpecFlow.Table"; + private const string SPECFLOW_NAMESPACE = "TechTalk.SpecFlow"; + + private readonly IUnitTestConverter testConverter = new NUnitTestConverter(); + + public CodeCompileUnit GenerateUnitTestFixture(Feature feature, string testClassName, string targetNamespace) + { + targetNamespace = targetNamespace ?? DEFAULT_NAMESPACE; + testClassName = testClassName ?? string.Format(FIXTURE_FORMAT, feature.Title.ToIdentifier()); + + CodeCompileUnit codeCompileUnit = new CodeCompileUnit(); + CodeNamespace codeNamespace = new CodeNamespace(targetNamespace); + codeCompileUnit.Namespaces.Add(codeNamespace); + + codeNamespace.Imports.Add(new CodeNamespaceImport(SPECFLOW_NAMESPACE)); + + var testType = new CodeTypeDeclaration(testClassName); + testType.IsPartial = true; + testType.TypeAttributes |= TypeAttributes.Public; + codeNamespace.Types.Add(testType); + + testConverter.SetTestFixture(testType, feature.Title, feature.Description); + if (feature.Tags != null) + { + testConverter.SetTestFixtureCategories(testType, GetNonIgnoreTags(feature.Tags)); + if (feature.Tags.Any(t => t.Name.Equals(IGNORE_TAG, StringComparison.InvariantCultureIgnoreCase))) + testConverter.SetIgnore(testType); + } + + CodeMemberField testRunnerField = new CodeMemberField(ITESTRUNNER_TYPE, TESTRUNNER_FIELD); + testType.Members.Add(testRunnerField); + + GenerateTestFixtureSetup(testType, feature); + GenerateTestFixtureTearDown(testType); + var testSetup = GenerateTestSetup(testType); + GenerateTestTearDown(testType); + + if (feature.Background != null) + GenerateBackground(testType, testSetup, feature.Background); + + foreach (var scenario in feature.Scenarios) + { + if (scenario is ScenarioOutline) + GenerateScenarioOutlineTest(testType, testSetup, (ScenarioOutline)scenario, feature); + else + GenerateTest(testType, testSetup, scenario, feature); + } + + return codeCompileUnit; + } + + private IEnumerable GetNonIgnoreTags(IEnumerable tags) + { + return tags.Where(t => !t.Name.Equals(IGNORE_TAG, StringComparison.InvariantCultureIgnoreCase)).Select(t => t.Name); + } + + private CodeMemberMethod GenerateTestFixtureSetup(CodeTypeDeclaration testType, Feature feature) + { + CodeMemberMethod setupMethod = new CodeMemberMethod(); + testType.Members.Add(setupMethod); + + setupMethod.Attributes = MemberAttributes.Public; + setupMethod.Name = FIXTURESETUP_NAME; + + testConverter.SetTestFixtureSetup(setupMethod); + + //testRunner = TestRunner.EnsureTestRunner(); + var testRunnerField = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), TESTRUNNER_FIELD); + setupMethod.Statements.Add( + new CodeAssignStatement( + testRunnerField, + new CodeMethodInvokeExpression( + new CodeTypeReferenceExpression(TESTRUNNERMANAGER_TYPE), + "GetTestRunner"))); + + //FeatureInfo featureInfo = new FeatureInfo("xxxx"); + setupMethod.Statements.Add( + new CodeVariableDeclarationStatement(FEATUREINFO_TYPE, "featureInfo", + new CodeObjectCreateExpression(FEATUREINFO_TYPE, + new CodePrimitiveExpression(feature.Title), + new CodePrimitiveExpression(feature.Description), + GetStringArrayExpression(feature.Tags)))); + + //testRunner.OnFeatureStart(featureInfo); + setupMethod.Statements.Add( + new CodeMethodInvokeExpression( + testRunnerField, + "OnFeatureStart", + new CodeVariableReferenceExpression("featureInfo"))); + + return setupMethod; + } + + private CodeExpression GetStringArrayExpression(Tags tags) + { + if (tags == null || tags.Count == 0) + return new CodeCastExpression(typeof(string[]), new CodePrimitiveExpression(null)); + + List items = new List(); + foreach (var tag in tags) + { + items.Add(new CodePrimitiveExpression(tag.Name)); + } + + return new CodeArrayCreateExpression(typeof (string[]), items.ToArray()); + } + + private CodeExpression GetStringArrayExpression(IEnumerable items, ParameterSubstitution paramToIdentifier) + { + List expressions = new List(); + foreach (var item in items) + { + expressions.Add(GetSubstitutedString(item, paramToIdentifier)); + } + + return new CodeArrayCreateExpression(typeof (string[]), expressions.ToArray()); + } + + private CodeMemberMethod GenerateTestFixtureTearDown(CodeTypeDeclaration testType) + { + CodeMemberMethod tearDownMethod = new CodeMemberMethod(); + testType.Members.Add(tearDownMethod); + + tearDownMethod.Attributes = MemberAttributes.Public; + tearDownMethod.Name = FIXTURETEARDOWN_NAME; + + testConverter.SetTestFixtureTearDown(tearDownMethod); + + var testRunnerField = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), TESTRUNNER_FIELD); +// testRunner.OnFeatureEnd(); + tearDownMethod.Statements.Add( + new CodeMethodInvokeExpression( + testRunnerField, + "OnFeatureEnd")); +// testRunner = null; + tearDownMethod.Statements.Add( + new CodeAssignStatement( + testRunnerField, + new CodePrimitiveExpression(null))); + + return tearDownMethod; + } + + private CodeMemberMethod GenerateTestTearDown(CodeTypeDeclaration testType) + { + CodeMemberMethod tearDownMethod = new CodeMemberMethod(); + testType.Members.Add(tearDownMethod); + + tearDownMethod.Attributes = MemberAttributes.Public; + tearDownMethod.Name = TEARDOWN_NAME; + + testConverter.SetTestTearDown(tearDownMethod); + + var testRunnerField = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), TESTRUNNER_FIELD); + //testRunner.OnScenarioEnd(); + tearDownMethod.Statements.Add( + new CodeMethodInvokeExpression( + testRunnerField, + "OnScenarioEnd")); + + return tearDownMethod; + } + + private CodeMemberMethod GenerateTestSetup(CodeTypeDeclaration testType) + { + CodeMemberMethod setupMethod = new CodeMemberMethod(); + testType.Members.Add(setupMethod); + + setupMethod.Attributes = MemberAttributes.Public; + setupMethod.Name = SETUP_NAME; + setupMethod.Parameters.Add( + new CodeParameterDeclarationExpression(SCENARIOINFO_TYPE, "scenarioInfo")); + + //testConverter.SetTestSetup(setupMethod); + + //testRunner.OnScenarioStart(scenarioInfo); + var testRunnerField = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), TESTRUNNER_FIELD); + setupMethod.Statements.Add( + new CodeMethodInvokeExpression( + testRunnerField, + "OnScenarioStart", + new CodeVariableReferenceExpression("scenarioInfo"))); + + return setupMethod; + } + + private void GenerateBackground(CodeTypeDeclaration testType, CodeMemberMethod testSetup, Background background) + { + CodeMemberMethod backgroundMethod = new CodeMemberMethod(); + testType.Members.Add(backgroundMethod); + + backgroundMethod.Attributes = MemberAttributes.Public; + backgroundMethod.Name = BACKGROUND_NAME; + + foreach (var given in background.Steps) + GenerateStep(backgroundMethod, given, null); + + testSetup.Statements.Add( + new CodeMethodInvokeExpression( + new CodeThisReferenceExpression(), + backgroundMethod.Name)); + } + + private class ParameterSubstitution : List> + { + public void Add(string parameter, string identifier) + { + base.Add(new KeyValuePair(parameter.Trim(), identifier)); + } + + public bool TryGetIdentifier(string param, out string id) + { + param = param.Trim(); + foreach (var pair in this) + { + if (pair.Key.Equals(param)) + { + id = pair.Value; + return true; + } + } + id = null; + return false; + } + } + + private void GenerateScenarioOutlineTest(CodeTypeDeclaration testType, CodeMemberMethod testSetup, ScenarioOutline scenarioOutline, Feature feature) + { + string testMethodName = string.Format(TEST_FORMAT, scenarioOutline.Title.ToIdentifier()); + + ParameterSubstitution paramToIdentifier = new ParameterSubstitution(); + foreach (var param in scenarioOutline.Examples.ExampleSets[0].Table.Header.Cells) + paramToIdentifier.Add(param.Value, param.Value.ToIdentifierCamelCase()); + + if (scenarioOutline.Examples.ExampleSets.Length > 1) + { + //TODO: check params + } + + GenerateScenarioOutlineBody(scenarioOutline, paramToIdentifier, testType, testMethodName, testSetup); + + int exampleSetIndex = 0; + foreach (var exampleSet in scenarioOutline.Examples.ExampleSets) + { + string exampleSetTitle = exampleSet.Title == null ? string.Format("Scenarios{0}", exampleSetIndex + 1) : + exampleSet.Title.ToIdentifier(); + + for (int rowIndex = 0; rowIndex < exampleSet.Table.Body.Length; rowIndex++) + { + GenerateScenarioOutlineTestVariant(testType, scenarioOutline, testMethodName, paramToIdentifier, exampleSetTitle, exampleSet.Table.Body[rowIndex], rowIndex); + } + exampleSetIndex++; + } + } + + private void GenerateScenarioOutlineBody(ScenarioOutline scenarioOutline, ParameterSubstitution paramToIdentifier, CodeTypeDeclaration testType, string testMethodName, CodeMemberMethod testSetup) + { + CodeMemberMethod testMethod = new CodeMemberMethod(); + testType.Members.Add(testMethod); + + testMethod.Attributes = MemberAttributes.Public; + testMethod.Name = testMethodName; + + foreach (var pair in paramToIdentifier) + { + testMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof (string), pair.Value)); + } + + GenerateTestBody(scenarioOutline, testMethod, testSetup, paramToIdentifier); + } + + private void GenerateScenarioOutlineTestVariant(CodeTypeDeclaration testType, ScenarioOutline scenarioOutline, string testMethodName, List> paramToIdentifier, string exampleSetTitle, Row row, int rowIndex) + { + CodeMemberMethod testMethod = GetTestMethodDeclaration(testType, scenarioOutline); + testMethod.Name = string.Format("{0}_{1}_Variant{2}", testMethod.Name, exampleSetTitle, rowIndex); + + //call test implementation with the params + List argumentExpressions = new List(); + foreach (var paramCell in row.Cells) + { + argumentExpressions.Add(new CodePrimitiveExpression(paramCell.Value)); + } + testMethod.Statements.Add( + new CodeMethodInvokeExpression( + new CodeThisReferenceExpression(), + testMethodName, + argumentExpressions.ToArray())); + } + + private void GenerateTest(CodeTypeDeclaration testType, CodeMemberMethod testSetup, Scenario scenario, Feature feature) + { + CodeMemberMethod testMethod = GetTestMethodDeclaration(testType, scenario); + GenerateTestBody(scenario, testMethod, testSetup, null); + } + + private void GenerateTestBody(Scenario scenario, CodeMemberMethod testMethod, CodeMemberMethod testSetup, ParameterSubstitution paramToIdentifier) + { + //call test setup + //ScenarioInfo scenarioInfo = new ScenarioInfo("xxxx", tags...); + testMethod.Statements.Add( + new CodeVariableDeclarationStatement(SCENARIOINFO_TYPE, "scenarioInfo", + new CodeObjectCreateExpression(SCENARIOINFO_TYPE, + new CodePrimitiveExpression(scenario.Title), + GetStringArrayExpression(scenario.Tags)))); + + testMethod.Statements.Add( + new CodeMethodInvokeExpression( + new CodeThisReferenceExpression(), + testSetup.Name, + new CodeVariableReferenceExpression("scenarioInfo"))); + + foreach (var scenarioStep in scenario.Steps) + { + GenerateStep(testMethod, scenarioStep, paramToIdentifier); + } + + + // call collect errors + var testRunnerField = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), TESTRUNNER_FIELD); + //testRunner.CollectScenarioErrors(); + testMethod.Statements.Add( + new CodeMethodInvokeExpression( + testRunnerField, + "CollectScenarioErrors")); + + } + + private CodeMemberMethod GetTestMethodDeclaration(CodeTypeDeclaration testType, Scenario scenario) + { + CodeMemberMethod testMethod = new CodeMemberMethod(); + testType.Members.Add(testMethod); + + testMethod.Attributes = MemberAttributes.Public; + testMethod.Name = string.Format(TEST_FORMAT, scenario.Title.ToIdentifier()); + + testConverter.SetTest(testMethod, scenario.Title); + if (scenario.Tags != null) + { + testConverter.SetTestCategories(testMethod, GetNonIgnoreTags(scenario.Tags)); + if (scenario.Tags.Any(t => t.Name.Equals(IGNORE_TAG, StringComparison.InvariantCultureIgnoreCase))) + testConverter.SetIgnore(testMethod); + } + return testMethod; + } + + private CodeExpression GetSubstitutedString(string text, ParameterSubstitution paramToIdentifier) + { + if (text == null) + return new CodeCastExpression(typeof(string), new CodePrimitiveExpression(null)); + if (paramToIdentifier == null) + return new CodePrimitiveExpression(text); + + Regex paramRe = new Regex(@"\<(?[^\>]+)\>"); + string formatText = text.Replace("{", "{{").Replace("}", "}}"); + List arguments = new List(); + + formatText = paramRe.Replace(formatText, match => + { + string param = match.Groups["param"].Value; + string id; + if (!paramToIdentifier.TryGetIdentifier(param, out id)) + return match.Value; + int argIndex = arguments.IndexOf(id); + if (argIndex < 0) + { + argIndex = arguments.Count; + arguments.Add(id); + } + return "{" + argIndex + "}"; + }); + + if (arguments.Count == 0) + return new CodePrimitiveExpression(text); + + List formatArguments = new List(); + formatArguments.Add(new CodePrimitiveExpression(formatText)); + foreach (var id in arguments) + formatArguments.Add(new CodeVariableReferenceExpression(id)); + + return new CodeMethodInvokeExpression( + new CodeTypeReferenceExpression(typeof (string)), + "Format", + formatArguments.ToArray()); + } + + private void GenerateStep(CodeMemberMethod testMethod, ScenarioStep scenarioStep, ParameterSubstitution paramToIdentifier) + { + var testRunnerField = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), TESTRUNNER_FIELD); + + //testRunner.Given("something"); + List arguments = new List(); + arguments.Add( + GetSubstitutedString(scenarioStep.Text, paramToIdentifier)); + if (scenarioStep.MultiLineTextArgument != null || scenarioStep.TableArg != null) + { + arguments.Add( + GetMultilineTextArgExpression(scenarioStep.MultiLineTextArgument, paramToIdentifier)); + arguments.Add( + GetTableArgExpression(scenarioStep.TableArg, testMethod.Statements, paramToIdentifier)); + } + + testMethod.Statements.Add( + new CodeMethodInvokeExpression( + testRunnerField, + scenarioStep.GetType().Name, + arguments.ToArray())); + } + + private int tableCounter = 0; + private CodeExpression GetTableArgExpression(Table tableArg, CodeStatementCollection statements, ParameterSubstitution paramToIdentifier) + { + if (tableArg == null) + return new CodeCastExpression(TABLE_TYPE, new CodePrimitiveExpression(null)); + + tableCounter++; + + //Table table0 = new Table(header...); + var tableVar = new CodeVariableReferenceExpression("table" + tableCounter); + statements.Add( + new CodeVariableDeclarationStatement(TABLE_TYPE, tableVar.VariableName, + new CodeObjectCreateExpression( + TABLE_TYPE, + GetStringArrayExpression(tableArg.Header.Cells.Select(c => c.Value), paramToIdentifier)))); + + foreach (var row in tableArg.Body) + { + //table0.AddRow(cells...); + statements.Add( + new CodeMethodInvokeExpression( + tableVar, + "AddRow", + GetStringArrayExpression(row.Cells.Select(c => c.Value), paramToIdentifier))); + } + return tableVar; + } + + private CodeExpression GetMultilineTextArgExpression(string multiLineTextArgument, ParameterSubstitution paramToIdentifier) + { + return GetSubstitutedString(multiLineTextArgument, paramToIdentifier); + } + } +} diff --git a/Parser/SyntaxElements/And.cs b/Parser/SyntaxElements/And.cs new file mode 100644 index 000000000..fe7ac44cc --- /dev/null +++ b/Parser/SyntaxElements/And.cs @@ -0,0 +1,16 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + public class And : ScenarioStep + { + public And() + { + } + + public And(Text stepText, MultilineText multilineTextArgument, Table tableArg) : base(stepText, multilineTextArgument, tableArg) + { + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/Background.cs b/Parser/SyntaxElements/Background.cs new file mode 100644 index 000000000..a7e3d50ea --- /dev/null +++ b/Parser/SyntaxElements/Background.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + public class Background + { + public string Title { get; set; } + public ScenarioSteps Steps { get; set; } + + public Background() + { + } + + public Background(Text title, ScenarioSteps scenarioSteps) + { + Title = title == null ? "" : title.Value; + Steps = scenarioSteps ?? new ScenarioSteps(); + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/But.cs b/Parser/SyntaxElements/But.cs new file mode 100644 index 000000000..9cb4659d0 --- /dev/null +++ b/Parser/SyntaxElements/But.cs @@ -0,0 +1,16 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + public class But : ScenarioStep + { + public But() + { + } + + public But(Text stepText, MultilineText multilineTextArgument, Table tableArg) : base(stepText, multilineTextArgument, tableArg) + { + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/Examples.cs b/Parser/SyntaxElements/Examples.cs new file mode 100644 index 000000000..ffa1bc01f --- /dev/null +++ b/Parser/SyntaxElements/Examples.cs @@ -0,0 +1,35 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + public class Examples + { + public ExampleSet[] ExampleSets { get; set; } + + public Examples() + { + } + + public Examples(params ExampleSet[] exampleSets) + { + ExampleSets = exampleSets; + } + } + + public class ExampleSet + { + public string Title { get; set; } + public Table Table { get; set; } + + public ExampleSet() + { + } + + public ExampleSet(Text title, Table table) + { + Title = title == null ? string.Empty : title.Value; + Table = table; + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/Feature.cs b/Parser/SyntaxElements/Feature.cs new file mode 100644 index 000000000..c63b3de45 --- /dev/null +++ b/Parser/SyntaxElements/Feature.cs @@ -0,0 +1,40 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + /// + /// not required in the final AST + /// + public class DescriptionLine + { + public string LineText { get; set; } + + public DescriptionLine(Text lineText) + { + LineText = lineText.Value; + } + } + + public class Feature + { + public Tags Tags { get; set; } + public Background Background { get; set; } + public Scenario[] Scenarios { get; set; } + public string Title { get; set; } + public string Description { get; set; } + + public Feature() + { + } + + public Feature(Text title, Tags tags, DescriptionLine[] description, Background background, params Scenario[] scenarios) + { + Tags = tags; + Description = description == null ? string.Empty : string.Join(Environment.NewLine, description.Select(d => d.LineText.Trim()).ToArray()); + Background = background; + Scenarios = scenarios; + Title = title.Value; + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/Given.cs b/Parser/SyntaxElements/Given.cs new file mode 100644 index 000000000..432cff510 --- /dev/null +++ b/Parser/SyntaxElements/Given.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + public class Given : ScenarioStep + { + public Given() + { + } + + public Given(Text givenText, MultilineText multilineTextArgument, Table tableArg) : base(givenText, multilineTextArgument, tableArg) + { + } + } + + public class Givens : List + { + public Givens() + { + } + + public Givens(params Given[] givens) + { + AddRange(givens); + } + } +} + \ No newline at end of file diff --git a/Parser/SyntaxElements/MultilineText.cs b/Parser/SyntaxElements/MultilineText.cs new file mode 100644 index 000000000..943e89a0a --- /dev/null +++ b/Parser/SyntaxElements/MultilineText.cs @@ -0,0 +1,18 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + /// + /// not required in the final AST + /// + public class MultilineText + { + public string Value; + + public MultilineText(string text, string indent) + { + Value = (Environment.NewLine + text).Replace(Environment.NewLine + indent, Environment.NewLine).Remove(0, Environment.NewLine.Length); + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/Scenario.cs b/Parser/SyntaxElements/Scenario.cs new file mode 100644 index 000000000..ff1563993 --- /dev/null +++ b/Parser/SyntaxElements/Scenario.cs @@ -0,0 +1,26 @@ +using System; +using System.Linq; +using System.Xml.Serialization; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + [XmlInclude(typeof(ScenarioOutline))] + public class Scenario + { + public Tags Tags { get; set; } + public string Title { get; set; } + + public ScenarioSteps Steps { get; set; } + + public Scenario() + { + } + + public Scenario(Text title, Tags tags, ScenarioSteps scenarioSteps) + { + Title = title.Value; + Tags = tags; + Steps = scenarioSteps ?? new ScenarioSteps(); + } + } +} diff --git a/Parser/SyntaxElements/ScenarioOutline.cs b/Parser/SyntaxElements/ScenarioOutline.cs new file mode 100644 index 000000000..3a2752885 --- /dev/null +++ b/Parser/SyntaxElements/ScenarioOutline.cs @@ -0,0 +1,19 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + public class ScenarioOutline : Scenario + { + public Examples Examples { get; set; } + + public ScenarioOutline() + { + } + + public ScenarioOutline(Text title, Tags tags, ScenarioSteps scenarioSteps, Examples examples) : base(title, tags, scenarioSteps) + { + Examples = examples; + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/ScenarioStep.cs b/Parser/SyntaxElements/ScenarioStep.cs new file mode 100644 index 000000000..ff3ff380a --- /dev/null +++ b/Parser/SyntaxElements/ScenarioStep.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Serialization; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + [XmlInclude(typeof(Given))] + [XmlInclude(typeof(When))] + [XmlInclude(typeof(Then))] + [XmlInclude(typeof(And))] + [XmlInclude(typeof(But))] + public class ScenarioStep + { + public string Text { get; set; } + public string MultiLineTextArgument { get; set; } + public Table TableArg { get; set; } + + public ScenarioStep() + { + } + + public ScenarioStep(Text stepText, MultilineText multilineTextArgument, Table tableArg) + { + this.Text = stepText.Value; + MultiLineTextArgument = multilineTextArgument == null ? null : multilineTextArgument.Value; + this.TableArg = tableArg; + } + } + + public class ScenarioSteps : List + { + public ScenarioSteps() + { + } + + public ScenarioSteps(params ScenarioStep[] thens) + { + AddRange(thens); + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/Table.cs b/Parser/SyntaxElements/Table.cs new file mode 100644 index 000000000..46196b260 --- /dev/null +++ b/Parser/SyntaxElements/Table.cs @@ -0,0 +1,49 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + public class Cell + { + public string Value { get; set; } + + public Cell() + { + } + + public Cell(Text value) + { + Value = value.Value; + } + } + + public class Row + { + public Cell[] Cells { get; set; } + + public Row() + { + } + + public Row(params Cell[] cells) + { + Cells = cells; + } + } + + public class Table + { + public Row Header { get; set; } + public Row[] Body { get; set; } + + public Table() + { + } + + public Table(Row header, params Row[] body) + { + Header = header; + Body = body; + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/Tag.cs b/Parser/SyntaxElements/Tag.cs new file mode 100644 index 000000000..c097857a9 --- /dev/null +++ b/Parser/SyntaxElements/Tag.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + public class Tag + { + public string Name { get; set; } + + public Tag() + { + } + + public Tag(Word name) + { + Name = name.Value; + } + } + + public class Tags : List + { + public Tags() + { + } + + public Tags(params Tag[] tags) + { + AddRange(tags); + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/Text.cs b/Parser/SyntaxElements/Text.cs new file mode 100644 index 000000000..fdc3b6756 --- /dev/null +++ b/Parser/SyntaxElements/Text.cs @@ -0,0 +1,26 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + /// + /// not required in the final AST + /// + public class Text + { + public string Value { get; set; } + + public Text(params string[] textElements) + { + if (textElements != null && textElements.Length > 0) + Value = string.Concat(textElements); + else + Value = String.Empty; + } + + public override string ToString() + { + return Value; + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/Then.cs b/Parser/SyntaxElements/Then.cs new file mode 100644 index 000000000..1eb38d229 --- /dev/null +++ b/Parser/SyntaxElements/Then.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + public class Then : ScenarioStep + { + public Then() + { + } + + public Then(Text givenText, MultilineText multilineTextArgument, Table tableArg) : base(givenText, multilineTextArgument, tableArg) + { + } + } + + public class Thens : List + { + public Thens() + { + } + + public Thens(params Then[] thens) + { + AddRange(thens); + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/When.cs b/Parser/SyntaxElements/When.cs new file mode 100644 index 000000000..e1eda4d47 --- /dev/null +++ b/Parser/SyntaxElements/When.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + public class When : ScenarioStep + { + public When() + { + } + + public When(Text givenText, MultilineText multilineTextArgument, Table tableArg) : base(givenText, multilineTextArgument, tableArg) + { + } + } + + public class Whens : List + { + public Whens() + { + } + + public Whens(params When[] whens) + { + AddRange(whens); + } + } +} \ No newline at end of file diff --git a/Parser/SyntaxElements/Word.cs b/Parser/SyntaxElements/Word.cs new file mode 100644 index 000000000..98e98e718 --- /dev/null +++ b/Parser/SyntaxElements/Word.cs @@ -0,0 +1,23 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow.Parser.SyntaxElements +{ + /// + /// not required in the final AST + /// + public class Word + { + public string Value { get; set; } + + public Word(string value) + { + this.Value = value; + } + + public override string ToString() + { + return Value; + } + } +} \ No newline at end of file diff --git a/Parser/TechTalk.SpecFlow.Parser.csproj b/Parser/TechTalk.SpecFlow.Parser.csproj new file mode 100644 index 000000000..7fe327cc2 --- /dev/null +++ b/Parser/TechTalk.SpecFlow.Parser.csproj @@ -0,0 +1,108 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {7CCEF6D6-FC17-422E-9BED-EDD752B6496F} + Library + Properties + TechTalk.SpecFlow.Parser + TechTalk.SpecFlow.Parser + v3.5 + 512 + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\lib\antlr\Antlr3.Runtime.dll + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + StringExtensions.cs + + + VersionInfo.cs + + + + Code + + + Code + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Parser/TechTalk.SpecFlow.Parser.csproj.vspscc b/Parser/TechTalk.SpecFlow.Parser.csproj.vspscc new file mode 100644 index 000000000..b6d32892f --- /dev/null +++ b/Parser/TechTalk.SpecFlow.Parser.csproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/Parser/bin/Debug/Antlr3.Runtime.dll b/Parser/bin/Debug/Antlr3.Runtime.dll new file mode 100644 index 000000000..e39f7cf5c Binary files /dev/null and b/Parser/bin/Debug/Antlr3.Runtime.dll differ diff --git a/Parser/bin/Debug/TechTalk.SpecFlow.Parser.dll b/Parser/bin/Debug/TechTalk.SpecFlow.Parser.dll new file mode 100644 index 000000000..c29af2009 Binary files /dev/null and b/Parser/bin/Debug/TechTalk.SpecFlow.Parser.dll differ diff --git a/Parser/bin/Debug/TechTalk.SpecFlow.Parser.pdb b/Parser/bin/Debug/TechTalk.SpecFlow.Parser.pdb new file mode 100644 index 000000000..546fbb9a7 Binary files /dev/null and b/Parser/bin/Debug/TechTalk.SpecFlow.Parser.pdb differ diff --git a/Parser/obj/Debug/TechTalk.SpecFlow.Parser.csproj.FileListAbsolute.txt b/Parser/obj/Debug/TechTalk.SpecFlow.Parser.csproj.FileListAbsolute.txt new file mode 100644 index 000000000..f9ac8e310 --- /dev/null +++ b/Parser/obj/Debug/TechTalk.SpecFlow.Parser.csproj.FileListAbsolute.txt @@ -0,0 +1,6 @@ +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Parser\bin\Debug\TechTalk.SpecFlow.Parser.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Parser\bin\Debug\TechTalk.SpecFlow.Parser.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Parser\bin\Debug\Antlr3.Runtime.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Parser\obj\Debug\ResolveAssemblyReference.cache +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Parser\obj\Debug\TechTalk.SpecFlow.Parser.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Parser\obj\Debug\TechTalk.SpecFlow.Parser.pdb diff --git a/Parser/obj/Debug/TechTalk.SpecFlow.Parser.dll b/Parser/obj/Debug/TechTalk.SpecFlow.Parser.dll new file mode 100644 index 000000000..c29af2009 Binary files /dev/null and b/Parser/obj/Debug/TechTalk.SpecFlow.Parser.dll differ diff --git a/Parser/obj/Debug/TechTalk.SpecFlow.Parser.pdb b/Parser/obj/Debug/TechTalk.SpecFlow.Parser.pdb new file mode 100644 index 000000000..546fbb9a7 Binary files /dev/null and b/Parser/obj/Debug/TechTalk.SpecFlow.Parser.pdb differ diff --git a/Reporting/AssemblyServices.cs b/Reporting/AssemblyServices.cs new file mode 100644 index 000000000..4ee759154 --- /dev/null +++ b/Reporting/AssemblyServices.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections; +using System.IO; +using System.Reflection; +using System.Diagnostics; + +namespace TechTalk.SpecFlow.Reporting +{ + public sealed class AssemblyServices + { + static private Assembly LoadAssemblyFrom(string name, string probingFolder) + { + string[] nameParts = name.Split(new char[] {','}, 2); + string assemblyName = nameParts[0]; + + try + { + return Assembly.LoadFrom(Path.Combine(probingFolder, assemblyName) + ".dll"); + } + catch (Exception) + { + try + { + return Assembly.LoadFrom(Path.Combine(probingFolder, assemblyName) + ".exe"); + } + catch (Exception) + { + return null; + } + } + } + + static private Assembly LoadAssemblyFrom(string name, string[] probingPath) + { + foreach (string probingFolder in probingPath) + { + Assembly result = LoadAssemblyFrom(name, probingFolder); + if (result != null) + return result; + } + return null; + } + + static public void SubscribeAssemblyResolve(params string[] probingPath) + { + SubscribeAssemblyResolve(AppDomain.CurrentDomain, probingPath); + } + + static public void SubscribeAssemblyResolve(AppDomain appDomain, params string[] probingPath) + { + AssemblyResolver resolver = new AssemblyResolver(probingPath); + appDomain.AssemblyResolve += new ResolveEventHandler(resolver.AppDomain_AssemblyResolve); + } + + [Serializable] + private class AssemblyResolver + { + private string[] probingPath; + + public AssemblyResolver(string[] probingPath) + { + this.probingPath = probingPath; + } + + public Assembly AppDomain_AssemblyResolve(object sender, ResolveEventArgs args) + { + string nameToResolve = args.Name; + + Assembly result = LoadAssemblyFrom(nameToResolve, probingPath); + Debug.WriteLine(String.Format("Resolving assembly \"{0}\", result: \"{1}\"", + nameToResolve, + result == null ? "Failed" : new Uri(result.CodeBase).AbsolutePath)); + + return result; + } + } + } +} \ No newline at end of file diff --git a/Reporting/BindingCollector.cs b/Reporting/BindingCollector.cs new file mode 100644 index 000000000..523f389cc --- /dev/null +++ b/Reporting/BindingCollector.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text.RegularExpressions; + +namespace TechTalk.SpecFlow.Reporting +{ + [Serializable] + public class FilePosition + { + public string FilePath { get; set; } + public int Line { get; set; } + public int Column { get; set; } + } + + [Serializable] + public class BindingInfo + { + public string MethodReference { get; set; } + public FilePosition FilePosition { get; set; } + + public string BindingType { get; set; } + public Regex Regex { get; set; } + public string[] ParameterNames { get; set; } + public bool HasMultilineTextArg { get; set; } + public bool HasTableArg { get; set; } + } + + public class BindingCollector : MarshalByRefObject + { + private readonly Type bindingAttributeType; + private readonly Type scenarioStepAttributeType; + + public BindingCollector() + { + Assembly specFlowRuntime = Assembly.Load("TechTalk.SpecFlow"); + this.bindingAttributeType = specFlowRuntime.GetType("TechTalk.SpecFlow.BindingAttribute", true); + this.scenarioStepAttributeType = specFlowRuntime.GetType("TechTalk.SpecFlow.ScenarioStepAttribute", true); + } + + public void BuildBindingsFromAssembly(Assembly assembly, List bindings) + { + foreach (Type type in assembly.GetTypes()) + { + Attribute bindingAttr = Attribute.GetCustomAttribute(type, bindingAttributeType); + if (bindingAttr == null) + continue; + + BuildBindingsFromType(type, bindings); + } + } + + private void BuildBindingsFromType(Type type, List bindings) + { + foreach (MethodInfo method in type.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) + { + var scenarioStepAttrs = Attribute.GetCustomAttributes(method, scenarioStepAttributeType); + if (scenarioStepAttrs != null) + foreach (var scenarioStepAttr in scenarioStepAttrs) + { + BuildStepBindingFromMethod(method, scenarioStepAttr, bindings); + } + +// var bindingEventAttrs = Attribute.GetCustomAttributes(method, typeof(BindingEventAttribute)); +// if (bindingEventAttrs != null) +// foreach (BindingEventAttribute bindingEventAttr in bindingEventAttrs) +// { +// BuildEventBindingFromMethod(method, bindingEventAttr); +// } + } + } + + private void BuildStepBindingFromMethod(MethodInfo method, Attribute scenarioStepAttr, List bindings) + { + Regex regex = new Regex("^" + scenarioStepAttr.GetProperty("Regex") + "$", RegexOptions.Compiled | RegexOptions.CultureInvariant); + var parameters = method.GetParameters(); + + var hasTableArg = parameters.Length == 0 + ? false + : parameters[parameters.Length - 1].ParameterType.Name == "Table"; + + BindingInfo bindingInfo = new BindingInfo + { + BindingType = GetBindingType(scenarioStepAttr), + Regex = regex, + MethodReference = String.Format("{0}.{1}({2})", + method.DeclaringType.FullName, method.Name, String.Join(", ", parameters.Select(pi => pi.ParameterType.Name).ToArray())), + ParameterNames = parameters.Select(pi => pi.Name).ToArray(), + HasMultilineTextArg = false, //TODO + HasTableArg = hasTableArg + }; + + bindings.Add(bindingInfo); + } + + private string GetBindingType(Attribute scenarioStepAttr) + { + var attrName = scenarioStepAttr.GetType().Name; + return attrName.Remove(attrName.Length - "Attribute".Length); + } + + public List CollectBindings(string assemblyName) + { + Assembly assembly = Assembly.Load(assemblyName); + var bindings = new List(); + + BuildBindingsFromAssembly(assembly, bindings); + + return bindings; + } + + internal static List CollectBindings(SpecFlowProject specFlowProject, string basePath) + { + List bindings = new List(); + var reportingFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + + AppDomainSetup appDomainSetup = new AppDomainSetup(); + appDomainSetup.ApplicationBase = reportingFolder; + AppDomain appDomain = AppDomain.CreateDomain("CollectBindings", null, appDomainSetup); + + AssemblyServices.SubscribeAssemblyResolve(appDomain, basePath); + + BindingCollector bindingCollector = + (BindingCollector)appDomain.CreateInstanceAndUnwrap( + Assembly.GetExecutingAssembly().GetName().FullName, + typeof(BindingCollector).FullName); + + bindings.AddRange(bindingCollector.CollectBindings(specFlowProject.AssemblyName)); + + AppDomain.Unload(appDomain); + return bindings; + } + } +} \ No newline at end of file diff --git a/Reporting/Common/Common.xslt b/Reporting/Common/Common.xslt new file mode 100644 index 000000000..d2a027ad2 --- /dev/null +++ b/Reporting/Common/Common.xslt @@ -0,0 +1,225 @@ + + + + + + + + + + Generated by SpecFlow (see http://www.specflow.org/) + + <xsl:value-of select="$title"/> + + + + + + + + + + + + +

+ +

+ + Generated by SpecFlow at (see http://www.specflow.org/). + +
+
diff --git a/Reporting/Common/GherkinElements.xslt b/Reporting/Common/GherkinElements.xslt new file mode 100644 index 000000000..5aea4ba82 --- /dev/null +++ b/Reporting/Common/GherkinElements.xslt @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + [copy] + + + + + + + + + + + + + + + + + + + + + + + +
+ + + left top + top + + + +
+ + + left + + + + +
+
+ + +
+      
+    
+
+
diff --git a/Reporting/MsBuildProjectReader.cs b/Reporting/MsBuildProjectReader.cs new file mode 100644 index 000000000..56cc69d54 --- /dev/null +++ b/Reporting/MsBuildProjectReader.cs @@ -0,0 +1,46 @@ +using System; +using System.IO; +using System.Linq; +using Microsoft.Build.BuildEngine; + +namespace TechTalk.SpecFlow.Reporting +{ + static class MsBuildProjectReader + { + public static SpecFlowProject LoadSpecFlowProjectFromMsBuild(string projectFile) + { + projectFile = Path.GetFullPath(projectFile); + Project project = new Project(); + project.Load(projectFile, ProjectLoadSettings.IgnoreMissingImports); + + string projectFolder = Path.GetDirectoryName(projectFile); + + SpecFlowProject specFlowProject = new SpecFlowProject(); + specFlowProject.ProjectFolder = projectFolder; + specFlowProject.ProjectName = Path.GetFileNameWithoutExtension(projectFile); + specFlowProject.AssemblyName = project.GetEvaluatedProperty("AssemblyName"); + specFlowProject.DefaultNamespace = project.GetEvaluatedProperty("RootNamespace"); + + var items = project.GetEvaluatedItemsByName("None").Cast() + .Concat(project.GetEvaluatedItemsByName("Content").Cast()); + foreach (BuildItem item in items) + { + var extension = Path.GetExtension(item.FinalItemSpec); + if (extension.Equals(".feature", StringComparison.InvariantCultureIgnoreCase)) + { + var featureFile = new SpecFlowFeatureFile(item.FinalItemSpec); + var ns = item.GetEvaluatedMetadata("CustomToolNamespace"); + if (!String.IsNullOrEmpty(ns)) + featureFile.CustomNamespace = ns; + specFlowProject.FeatureFiles.Add(featureFile); + } + + if (Path.GetFileName(item.FinalItemSpec).Equals("app.config", StringComparison.InvariantCultureIgnoreCase)) + { + ParserConfigReader.UpdateConfigFromFile(specFlowProject.ParserConfiguration, Path.Combine(projectFolder, item.FinalItemSpec)); + } + } + return specFlowProject; + } + } +} diff --git a/Reporting/NConsoler/NConsoler.cs b/Reporting/NConsoler/NConsoler.cs new file mode 100644 index 000000000..4ab7db121 --- /dev/null +++ b/Reporting/NConsoler/NConsoler.cs @@ -0,0 +1,924 @@ +// +// NConsoler 0.9.3 +// http://nconsoler.csharpus.com +// + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Diagnostics; + +namespace NConsoler +{ + /// + /// Entry point for NConsoler applications + /// + public sealed class Consolery + { + /// + /// Runs an appropriate Action method. + /// Uses the class this call lives in as target type and command line arguments from Environment + /// + public static void Run() + { + Type declaringType = new StackTrace().GetFrame(1).GetMethod().DeclaringType; + string[] args = new string[Environment.GetCommandLineArgs().Length - 1]; + new List(Environment.GetCommandLineArgs()).CopyTo(1, args, 0, Environment.GetCommandLineArgs().Length - 1); + Run(declaringType, args); + } + + /// + /// Runs an appropriate Action method + /// + /// Type where to search for Action methods + /// Arguments that will be converted to Action method arguments + public static void Run(Type targetType, string[] args) + { + Run(targetType, args, new ConsoleMessenger()); + } + + /// + /// Runs an appropriate Action method + /// + /// Type where to search for Action methods + /// Arguments that will be converted to Action method arguments + /// Uses for writing messages instead of Console class methods + public static void Run(Type targetType, string[] args, IMessenger messenger) + { + try + { + new Consolery(targetType, args, messenger).RunAction(); + } + catch (NConsolerException e) + { + messenger.Write(e.Message); + } + } + + /// + /// Validates specified type and throws NConsolerException if an error + /// + /// Type where to search for Action methods + public static void Validate(Type targetType) + { + new Consolery(targetType, new string[] {}, new ConsoleMessenger()).ValidateMetadata(); + } + + private readonly Type _targetType; + private readonly string[] _args; + private readonly List _actionMethods = new List(); + private readonly IMessenger _messenger; + + private Consolery(Type targetType, string[] args, IMessenger messenger) + { + #region Parameter Validation + if (targetType == null) + { + throw new ArgumentNullException("targetType"); + } + if (args == null) + { + throw new ArgumentNullException("args"); + } + if (messenger == null) + { + throw new ArgumentNullException("messenger"); + } + #endregion + _targetType = targetType; + _args = args; + _messenger = messenger; + MethodInfo[] methods = _targetType.GetMethods(BindingFlags.Public | BindingFlags.Static); + foreach (MethodInfo method in methods) + { + object[] attributes = method.GetCustomAttributes(false); + foreach (object attribute in attributes) + { + if (attribute is ActionAttribute) + { + _actionMethods.Add(method); + break; + } + } + } + } + + static object ConvertValue(string value, Type argumentType) + { + if (argumentType == typeof(int)) + { + try + { + return Convert.ToInt32(value); + } + catch (FormatException) + { + throw new NConsolerException("Could not convert \"{0}\" to integer", value); + } + catch (OverflowException) + { + throw new NConsolerException("Value \"{0}\" is too big or too small", value); + } + } + if (argumentType == typeof(string)) + { + return value; + } + if (argumentType == typeof(bool)) + { + try + { + return Convert.ToBoolean(value); + } + catch (FormatException) + { + throw new NConsolerException("Could not convert \"{0}\" to boolean", value); + } + } + if (argumentType == typeof(string[])) + { + return value.Split('+'); + } + if (argumentType == typeof(int[])) + { + string[] values = value.Split('+'); + int[] valuesArray = new int[values.Length]; + for (int i = 0; i < values.Length; i++) + { + valuesArray[i] = (int)ConvertValue(values[i], typeof(int)); + } + return valuesArray; + } + if (argumentType == typeof(DateTime)) + { + return ConvertToDateTime(value); + } + throw new NConsolerException("Unknown type is used in your method {0}", argumentType.FullName); + } + + private static DateTime ConvertToDateTime(string parameter) + { + string[] parts = parameter.Split('-'); + if (parts.Length != 3) + { + throw new NConsolerException("Could not convert {0} to Date", parameter); + } + int day = (int)ConvertValue(parts[0], typeof(int)); + int month = (int)ConvertValue(parts[1], typeof(int)); + int year = (int)ConvertValue(parts[2], typeof(int)); + try + { + return new DateTime(year, month, day); + } + catch (ArgumentException) + { + throw new NConsolerException("Could not convert {0} to Date", parameter); + } + } + + private static bool CanBeConvertedToDate(string parameter) + { + try + { + ConvertToDateTime(parameter); + return true; + } + catch(NConsolerException) + { + return false; + } + } + + private bool SingleActionWithOnlyOptionalParametersSpecified() { + if (IsMulticommand) return false; + MethodInfo method = _actionMethods[0]; + return OnlyOptionalParametersSpecified(method); + } + + private static bool OnlyOptionalParametersSpecified(MethodBase method) + { + foreach (ParameterInfo parameter in method.GetParameters()) + { + if (IsRequired(parameter)) + { + return false; + } + } + return true; + } + + + private void RunAction() + { + ValidateMetadata(); + if (IsHelpRequested()) + { + PrintUsage(); + return; + } + + MethodInfo currentMethod = GetCurrentMethod(); + if (currentMethod == null) + { + PrintUsage(); + throw new NConsolerException("Unknown subcommand \"{0}\"", _args[0]); + } + ValidateInput(currentMethod); + InvokeMethod(currentMethod); + } + + private struct ParameterData + { + public readonly int position; + public readonly Type type; + + public ParameterData(int position, Type type) + { + this.position = position; + this.type = type; + } + } + + private static bool IsRequired(ICustomAttributeProvider info) + { + object[] attributes = info.GetCustomAttributes(typeof(ParameterAttribute), false); + return attributes.Length == 0 || attributes[0].GetType() == typeof(RequiredAttribute); + } + + private static bool IsOptional(ICustomAttributeProvider info) + { + return !IsRequired(info); + } + + private static OptionalAttribute GetOptional(ICustomAttributeProvider info) + { + object[] attributes = info.GetCustomAttributes(typeof(OptionalAttribute), false); + return (OptionalAttribute)attributes[0]; + } + + private bool IsMulticommand + { + get + { + return _actionMethods.Count > 1; + } + } + + private bool IsHelpRequested() + { + return (_args.Length == 0 && !SingleActionWithOnlyOptionalParametersSpecified()) + || (_args.Length > 0 && (_args[0] == "/?" + || _args[0] == "/help" + || _args[0] == "/h" + || _args[0] == "help")); + } + + private void InvokeMethod(MethodInfo method) + { + try + { + method.Invoke(null, BuildParameterArray(method)); + } + catch (TargetInvocationException e) + { + if (e.InnerException != null) + { + throw new NConsolerException(e.InnerException.Message, e); + } + throw; + } + } + + private object[] BuildParameterArray(MethodInfo method) + { + int argumentIndex = IsMulticommand ? 1 : 0; + List parameterValues = new List(); + Dictionary aliases = new Dictionary(); + foreach (ParameterInfo info in method.GetParameters()) + { + if (IsRequired(info)) + { + parameterValues.Add(ConvertValue(_args[argumentIndex], info.ParameterType)); + } + else + { + OptionalAttribute optional = GetOptional(info); + + foreach (string altName in optional.AltNames) + { + aliases.Add(altName.ToLower(), + new ParameterData(parameterValues.Count, info.ParameterType)); + } + aliases.Add(info.Name.ToLower(), + new ParameterData(parameterValues.Count, info.ParameterType)); + parameterValues.Add(optional.Default); + } + argumentIndex++; + } + foreach (string optionalParameter in OptionalParameters(method)) + { + string name = ParameterName(optionalParameter); + string value = ParameterValue(optionalParameter); + parameterValues[aliases[name].position] = ConvertValue(value, aliases[name].type); + } + return parameterValues.ToArray(); + } + + private IEnumerable OptionalParameters(MethodInfo method) + { + int firstOptionalParameterIndex = RequiredParameterCount(method); + if (IsMulticommand) + { + firstOptionalParameterIndex++; + } + for (int i = firstOptionalParameterIndex; i < _args.Length; i++) + { + yield return _args[i]; + } + } + + private static int RequiredParameterCount(MethodInfo method) + { + int requiredParameterCount = 0; + foreach (ParameterInfo parameter in method.GetParameters()) + { + if (IsRequired(parameter)) + { + requiredParameterCount++; + } + } + return requiredParameterCount; + } + + private MethodInfo GetCurrentMethod() + { + if (!IsMulticommand) + { + return _actionMethods[0]; + } + return GetMethodByName(_args[0].ToLower()); + } + + private MethodInfo GetMethodByName(string name) + { + foreach (MethodInfo method in _actionMethods) + { + if (method.Name.ToLower() == name) + { + return method; + } + } + return null; + } + + private void PrintUsage(MethodInfo method) + { + PrintMethodDescription(method); + Dictionary parameters = GetParametersDescriptions(method); + PrintUsageExample(method, parameters); + PrintParametersDescriptions(parameters); + } + + private void PrintUsageExample(MethodInfo method, IDictionary parameterList) + { + string subcommand = IsMulticommand ? method.Name.ToLower() + " " : String.Empty; + string parameters = String.Join(" ", new List(parameterList.Keys).ToArray()); + _messenger.Write("usage: " + ProgramName() + " " + subcommand + parameters); + } + + private void PrintMethodDescription(MethodInfo method) + { + string description = GetMethodDescription(method); + if (description == String.Empty) return; + _messenger.Write(description); + } + + private static string GetMethodDescription(MethodInfo method) + { + object[] attributes = method.GetCustomAttributes(true); + foreach (object attribute in attributes) + { + if (attribute is ActionAttribute) + { + return ((ActionAttribute)attribute).Description; + } + } + throw new NConsolerException("Method is not marked with an Action attribute"); + } + + private static Dictionary GetParametersDescriptions(MethodInfo method) + { + Dictionary parameters = new Dictionary(); + foreach (ParameterInfo parameter in method.GetParameters()) + { + object[] parameterAttributes = + parameter.GetCustomAttributes(typeof(ParameterAttribute), false); + if (parameterAttributes.Length > 0) + { + string name = GetDisplayName(parameter); + ParameterAttribute attribute = (ParameterAttribute)parameterAttributes[0]; + parameters.Add(name, attribute.Description); + } + else + { + parameters.Add(parameter.Name, String.Empty); + } + } + return parameters; + } + + private void PrintParametersDescriptions(IEnumerable> parameters) + { + int maxParameterNameLength = MaxKeyLength(parameters); + foreach (KeyValuePair pair in parameters) + { + if (pair.Value != String.Empty) + { + int difference = maxParameterNameLength - pair.Key.Length + 2; + _messenger.Write(" " + pair.Key + new String(' ', difference) + pair.Value); + } + } + } + + private static int MaxKeyLength(IEnumerable> parameters) + { + int maxLength = 0; + foreach (KeyValuePair pair in parameters) + { + if (pair.Key.Length > maxLength) + { + maxLength = pair.Key.Length; + } + } + return maxLength; + } + + private string ProgramName() + { + Assembly entryAssembly = Assembly.GetEntryAssembly(); + if (entryAssembly == null) + { + return _targetType.Name.ToLower(); + } + return new AssemblyName(entryAssembly.FullName).Name; + } + + private void PrintUsage() + { + if (IsMulticommand && !IsSubcommandHelpRequested()) + { + PrintGeneralMulticommandUsage(); + } + else if (IsMulticommand && IsSubcommandHelpRequested()) + { + PrintSubcommandUsage(); + } + else + { + PrintUsage(_actionMethods[0]); + } + } + + private void PrintSubcommandUsage() + { + MethodInfo method = GetMethodByName(_args[1].ToLower()); + if (method == null) + { + PrintGeneralMulticommandUsage(); + throw new NConsolerException("Unknown subcommand \"{0}\"", _args[0].ToLower()); + } + PrintUsage(method); + } + + private bool IsSubcommandHelpRequested() + { + return _args.Length > 0 + && _args[0].ToLower() == "help" + && _args.Length == 2; + } + + private void PrintGeneralMulticommandUsage() + { + _messenger.Write( + String.Format("usage: {0} [args]", ProgramName())); + _messenger.Write( + String.Format("Type '{0} help ' for help on a specific subcommand.", ProgramName())); + _messenger.Write(String.Empty); + _messenger.Write("Available subcommands:"); + foreach (MethodInfo method in _actionMethods) + { + _messenger.Write(method.Name.ToLower() + " " + GetMethodDescription(method)); + } + } + + private static string GetDisplayName(ParameterInfo parameter) + { + if (IsRequired(parameter)) + { + return parameter.Name; + } + OptionalAttribute optional = GetOptional(parameter); + string parameterName = + (optional.AltNames.Length > 0) ? optional.AltNames[0] : parameter.Name; + if (parameter.ParameterType != typeof(bool)) + { + parameterName += ":" + ValueDescription(parameter.ParameterType); + } + return "[/" + parameterName + "]"; + } + + private static string ValueDescription(Type type) + { + if (type == typeof(int)) + { + return "number"; + } + if (type == typeof(string)) + { + return "value"; + } + if (type == typeof(int[])) + { + return "number[+number]"; + } + if (type == typeof(string[])) + { + return "value[+value]"; + } + if (type == typeof(DateTime)) + { + return "dd-mm-yyyy"; + } + throw new ArgumentOutOfRangeException(String.Format("Type {0} is unknown", type.Name)); + } + + #region Validation + + private void ValidateInput(MethodInfo method) + { + CheckAllRequiredParametersAreSet(method); + CheckOptionalParametersAreNotDuplicated(method); + CheckUnknownParametersAreNotPassed(method); + } + + private void CheckAllRequiredParametersAreSet(MethodInfo method) + { + int minimumArgsLengh = RequiredParameterCount(method); + if (IsMulticommand) + { + minimumArgsLengh++; + } + if (_args.Length < minimumArgsLengh) + { + throw new NConsolerException("Not all required parameters are set"); + } + } + + private static string ParameterName(string parameter) + { + if (parameter.StartsWith("/-")) + { + return parameter.Substring(2).ToLower(); + } + if (parameter.Contains(":")) + { + return parameter.Substring(1, parameter.IndexOf(":") - 1).ToLower(); + } + return parameter.Substring(1).ToLower(); + } + + private static string ParameterValue(string parameter) + { + if (parameter.StartsWith("/-")) + { + return "false"; + } + if (parameter.Contains(":")) + { + return parameter.Substring(parameter.IndexOf(":") + 1); + } + return "true"; + } + + private void CheckOptionalParametersAreNotDuplicated(MethodInfo method) + { + List passedParameters = new List(); + foreach (string optionalParameter in OptionalParameters(method)) + { + if (!optionalParameter.StartsWith("/")) + { + throw new NConsolerException("Unknown parameter {0}", optionalParameter); + } + string name = ParameterName(optionalParameter); + if (passedParameters.Contains(name)) + { + throw new NConsolerException("Parameter with name {0} passed two times", name); + } + passedParameters.Add(name); + } + } + + private void CheckUnknownParametersAreNotPassed(MethodInfo method) + { + List parameterNames = new List(); + foreach (ParameterInfo parameter in method.GetParameters()) + { + if (IsRequired(parameter)) + { + continue; + } + parameterNames.Add(parameter.Name.ToLower()); + OptionalAttribute optional = GetOptional(parameter); + foreach (string altName in optional.AltNames) + { + parameterNames.Add(altName.ToLower()); + } + } + foreach (string optionalParameter in OptionalParameters(method)) + { + string name = ParameterName(optionalParameter); + if (!parameterNames.Contains(name.ToLower())) + { + throw new NConsolerException("Unknown parameter name {0}", optionalParameter); + } + } + } + + private void ValidateMetadata() + { + CheckAnyActionMethodExists(); + IfActionMethodIsSingleCheckMethodHasParameters(); + foreach (MethodInfo method in _actionMethods) + { + CheckActionMethodNamesAreNotReserved(); + CheckRequiredAndOptionalAreNotAppliedAtTheSameTime(method); + CheckOptionalParametersAreAfterRequiredOnes(method); + CheckOptionalParametersDefaultValuesAreAssignableToRealParameterTypes(method); + CheckOptionalParametersAltNamesAreNotDuplicated(method); + } + } + + private void CheckActionMethodNamesAreNotReserved() + { + foreach (MethodInfo method in _actionMethods) + { + if (method.Name.ToLower() == "help") + { + throw new NConsolerException("Method name \"{0}\" is reserved. Please, choose another name", method.Name); + } + } + } + + private void CheckAnyActionMethodExists() + { + if (_actionMethods.Count == 0) + { + throw new NConsolerException("Can not find any public static method marked with [Action] attribute in type \"{0}\"", _targetType.Name); + } + } + + private void IfActionMethodIsSingleCheckMethodHasParameters() + { + if (_actionMethods.Count == 1 && _actionMethods[0].GetParameters().Length == 0) + { + throw new NConsolerException("[Action] attribute applied once to the method \"{0}\" without parameters. In this case NConsoler should not be used", _actionMethods[0].Name); + } + } + + private static void CheckRequiredAndOptionalAreNotAppliedAtTheSameTime(MethodBase method) + { + foreach (ParameterInfo parameter in method.GetParameters()) + { + object[] attributes = parameter.GetCustomAttributes(typeof(ParameterAttribute), false); + if (attributes.Length > 1) + { + throw new NConsolerException("More than one attribute is applied to the parameter \"{0}\" in the method \"{1}\"", parameter.Name, method.Name); + } + } + } + + private static bool CanBeNull(Type type) + { + return type == typeof(string) + || type == typeof(string[]) + || type == typeof(int[]); + } + + private static void CheckOptionalParametersDefaultValuesAreAssignableToRealParameterTypes(MethodBase method) + { + foreach (ParameterInfo parameter in method.GetParameters()) + { + if (IsRequired(parameter)) + { + continue; + } + OptionalAttribute optional = GetOptional(parameter); + if (optional.Default != null && optional.Default.GetType() == typeof(string) && CanBeConvertedToDate(optional.Default.ToString())) + { + return; + } + if ((optional.Default == null && !CanBeNull(parameter.ParameterType)) + || (optional.Default != null && !optional.Default.GetType().IsAssignableFrom(parameter.ParameterType))) + { + throw new NConsolerException("Default value for an optional parameter \"{0}\" in method \"{1}\" can not be assigned to the parameter", parameter.Name, method.Name); + } + } + } + + private static void CheckOptionalParametersAreAfterRequiredOnes(MethodBase method) + { + bool optionalFound = false; + foreach (ParameterInfo parameter in method.GetParameters()) + { + if (IsOptional(parameter)) + { + optionalFound = true; + } + else if (optionalFound) + { + throw new NConsolerException("It is not allowed to write a parameter with a Required attribute after a parameter with an Optional one. See method \"{0}\" parameter \"{1}\"", method.Name, parameter.Name); + } + } + } + + private static void CheckOptionalParametersAltNamesAreNotDuplicated(MethodBase method) + { + List parameterNames = new List(); + foreach (ParameterInfo parameter in method.GetParameters()) + { + if (IsRequired(parameter)) + { + parameterNames.Add(parameter.Name.ToLower()); + } + else + { + if (parameterNames.Contains(parameter.Name.ToLower())) + { + throw new NConsolerException("Found duplicated parameter name \"{0}\" in method \"{1}\". Please check alt names for optional parameters", parameter.Name, method.Name); + } + parameterNames.Add(parameter.Name.ToLower()); + OptionalAttribute optional = GetOptional(parameter); + foreach (string altName in optional.AltNames) + { + if (parameterNames.Contains(altName.ToLower())) + { + throw new NConsolerException("Found duplicated parameter name \"{0}\" in method \"{1}\". Please check alt names for optional parameters", altName, method.Name); + } + parameterNames.Add(altName.ToLower()); + } + } + } + } + + #endregion + } + + /// + /// Used for getting messages from NConsoler + /// + public interface IMessenger + { + void Write(string message); + } + + /// + /// Uses Console class for message output + /// + public class ConsoleMessenger : IMessenger + { + public void Write(string message) + { + Console.WriteLine(message); + } + } + + /// + /// Every action method should be marked with this attribute + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + public sealed class ActionAttribute : Attribute + { + public ActionAttribute() + { + } + + public ActionAttribute(string description) + { + _description = description; + } + + private string _description = String.Empty; + + /// + /// Description is used for help messages + /// + public string Description + { + get + { + return _description; + } + + set + { + _description = value; + } + } + } + + /// + /// Should not be used directly + /// + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + public class ParameterAttribute : Attribute + { + private string _description = String.Empty; + + /// + /// Description is used in help message + /// + public string Description + { + get + { + return _description; + } + + set + { + _description = value; + } + } + + protected ParameterAttribute() + { + } + } + + /// + /// Marks an Action method parameter as optional + /// + public sealed class OptionalAttribute : ParameterAttribute + { + private string[] _altNames; + + public string[] AltNames + { + get + { + return _altNames; + } + + set + { + _altNames = value; + } + } + + private readonly object _defaultValue; + + public object Default + { + get + { + return _defaultValue; + } + } + + /// Default value if client doesn't pass this value + /// Aliases for parameter + public OptionalAttribute(object defaultValue, params string[] altNames) + { + _defaultValue = defaultValue; + _altNames = altNames; + } + } + + /// + /// Marks an Action method parameter as required + /// + public sealed class RequiredAttribute : ParameterAttribute + { + + } + + /// + /// Can be used for safe exception throwing - NConsoler will catch the exception + /// + public sealed class NConsolerException : Exception + { + public NConsolerException() + { + } + + public NConsolerException(string message, Exception innerException) + : base(message, innerException) + { + } + + public NConsolerException(string message, params string[] arguments) + : base(String.Format(message, arguments)) + { + } + } +} diff --git a/Reporting/NUnitExecutionReport/NUnitExecutionReportGenerator.cs b/Reporting/NUnitExecutionReport/NUnitExecutionReportGenerator.cs new file mode 100644 index 000000000..cf80540a8 --- /dev/null +++ b/Reporting/NUnitExecutionReport/NUnitExecutionReportGenerator.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace TechTalk.SpecFlow.Reporting.NUnitExecutionReport +{ + internal class NUnitExecutionReportGenerator + { + public void GenerateReport() + { + throw new NotImplementedException(); + } + + public void TransformReport(string outputFilePath) + { + throw new NotImplementedException(); + } + } +} diff --git a/Reporting/ParserConfigReader.cs b/Reporting/ParserConfigReader.cs new file mode 100644 index 000000000..f99e25697 --- /dev/null +++ b/Reporting/ParserConfigReader.cs @@ -0,0 +1,10 @@ +namespace TechTalk.SpecFlow.Reporting +{ + static class ParserConfigReader + { + public static void UpdateConfigFromFile(ParserConfiguration parserConfiguration, string configFile) + { + //TODO + } + } +} \ No newline at end of file diff --git a/Reporting/ParserHelper.cs b/Reporting/ParserHelper.cs new file mode 100644 index 000000000..90fb7a9bf --- /dev/null +++ b/Reporting/ParserHelper.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using TechTalk.SpecFlow.Parser; +using TechTalk.SpecFlow.Parser.SyntaxElements; + +namespace TechTalk.SpecFlow.Reporting +{ + static class ParserHelper + { + public static List GetParsedFeatures(SpecFlowProject specFlowProject) + { + List parsedFeatures = new List(); + foreach (var featureFile in specFlowProject.FeatureFiles) + { + SpecFlowLangParser parser = new SpecFlowLangParser(); + using (var reader = new StreamReader(featureFile.GetFullPath(specFlowProject))) + { + Feature feature = parser.Parse(reader); + parsedFeatures.Add(feature); + } + } + return parsedFeatures; + } + } +} diff --git a/Reporting/Program.cs b/Reporting/Program.cs new file mode 100644 index 000000000..e06006c00 --- /dev/null +++ b/Reporting/Program.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.IO; +using NConsoler; +using TechTalk.SpecFlow.Parser.SyntaxElements; +using TechTalk.SpecFlow.Reporting.NUnitExecutionReport; +using TechTalk.SpecFlow.Reporting.StepDefinitionReport; + +namespace TechTalk.SpecFlow.Reporting +{ + class Program + { + static void Main(string[] args) + { + Consolery.Run(typeof(Program), args); + return; + } + + [Action("Step Definition Report")] + public static void StepDefinitionReport( + [Required] string projectFile, + [Optional("bin\\Debug")] string binFolder, + [Optional("StepDefinitionReport.html", "out")] string outputFile) + { + SpecFlowProject specFlowProject = MsBuildProjectReader.LoadSpecFlowProjectFromMsBuild(projectFile); + + List parsedFeatures = ParserHelper.GetParsedFeatures(specFlowProject); + + var basePath = Path.Combine(specFlowProject.ProjectFolder, binFolder); + List bindings = BindingCollector.CollectBindings(specFlowProject, basePath); + + StepDefinitionReportGenerator generator = new StepDefinitionReportGenerator(specFlowProject, bindings, parsedFeatures); + generator.GenerateReport(); + + string outputFilePath = Path.Combine(basePath, outputFile); + generator.TransformReport(outputFilePath); + } + + [Action] + public static void NUnitExecutionReport( + [Optional("TestResult.xml")] string xmlTestResult, + [Optional("TestResult.txt", "testOutput")] string labeledTestOutput, + [Optional("TestResult.html", "out")] string outputFile + ) + { + NUnitExecutionReportGenerator generator = new NUnitExecutionReportGenerator(); + generator.GenerateReport(); + + string outputFilePath = Path.GetFullPath(outputFile); + generator.TransformReport(outputFilePath); + } + } +} \ No newline at end of file diff --git a/Reporting/Properties/AssemblyInfo.cs b/Reporting/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f7da8a51d --- /dev/null +++ b/Reporting/Properties/AssemblyInfo.cs @@ -0,0 +1,23 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 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("Reporting")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Reporting")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2009")] +[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)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("08de25e1-aa29-4d61-9441-23ed05ab1dce")] diff --git a/Reporting/ReflectionHelper.cs b/Reporting/ReflectionHelper.cs new file mode 100644 index 000000000..02dcc3cd9 --- /dev/null +++ b/Reporting/ReflectionHelper.cs @@ -0,0 +1,10 @@ +namespace TechTalk.SpecFlow.Reporting +{ + static class ReflectionHelper + { + public static T GetProperty(this object source, string propertyName) + { + return (T)source.GetType().GetProperty(propertyName).GetValue(source, null); + } + } +} \ No newline at end of file diff --git a/Reporting/ResourceXmlReader.cs b/Reporting/ResourceXmlReader.cs new file mode 100644 index 000000000..1222a09e4 --- /dev/null +++ b/Reporting/ResourceXmlReader.cs @@ -0,0 +1,42 @@ +using System; +using System.IO; +using System.Reflection; +using System.Xml; + +namespace TechTalk.SpecFlow.Reporting +{ + internal class ResourceXmlReader : XmlTextReader + { + private readonly string baseUri; + + public ResourceXmlReader(Type type, string resourceName) + : this(type.Assembly, type.Namespace + Type.Delimiter + resourceName) + { + + } + + public ResourceXmlReader(Assembly assembly, string resourceName) : base(GetResourceStream(assembly, resourceName)) + { + var resourcePath = + Path.GetFileNameWithoutExtension(resourceName).Replace(Type.Delimiter, Path.AltDirectorySeparatorChar) + + Path.GetExtension(resourceName); + baseUri = String.Format("resource://{0}/{1}", assembly.GetName().Name, resourcePath); + } + + private static Stream GetResourceStream(Assembly assembly, string resourceName) + { + var result = assembly.GetManifestResourceStream(resourceName); + if (result == null) + throw new InvalidOperationException(String.Format("Resource '{0}' not found.", resourceName)); + return result; + } + + public override string BaseURI + { + get + { + return baseUri; + } + } + } +} \ No newline at end of file diff --git a/Reporting/SpecFlowProject.cs b/Reporting/SpecFlowProject.cs new file mode 100644 index 000000000..49e32934c --- /dev/null +++ b/Reporting/SpecFlowProject.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.IO; + +namespace TechTalk.SpecFlow.Reporting +{ + internal class ParserConfiguration + { + + } + + internal class SpecFlowFeatureFile + { + public string ProjectRelativePath { get; private set; } + public string CustomNamespace { get; set; } + public string GetFullPath(SpecFlowProject project) + { + return Path.Combine(project.ProjectFolder, ProjectRelativePath); + } + + public SpecFlowFeatureFile(string path) + { + ProjectRelativePath = path; + } + } + + internal class SpecFlowProject + { + public string ProjectName { get; set; } + public string AssemblyName { get; set; } + public string ProjectFolder { get; set; } + public string DefaultNamespace { get; set; } + public List FeatureFiles { get; private set; } + public ParserConfiguration ParserConfiguration { get; set; } + + public SpecFlowProject() + { + FeatureFiles = new List(); + ParserConfiguration = new ParserConfiguration(); // load defaults + } + } +} \ No newline at end of file diff --git a/Reporting/StepDefinitionReport/ReportElements/StepDefinitionReport.cs b/Reporting/StepDefinitionReport/ReportElements/StepDefinitionReport.cs new file mode 100644 index 000000000..2ecc99946 --- /dev/null +++ b/Reporting/StepDefinitionReport/ReportElements/StepDefinitionReport.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Xml.Serialization; +using TechTalk.SpecFlow.Parser.SyntaxElements; + +namespace TechTalk.SpecFlow.Reporting.StepDefinitionReport.ReportElements +{ + [XmlType("StepDefinitionReport", Namespace = XmlNamespace)] + public class StepDefinitionReport + { + public const string XmlNamespace = "urn:TechTalk:SpecFlow.Report"; + + [XmlAttribute("projectName")] + public string ProjectName; + [XmlAttribute("generatedAt")] + public string GeneratedAt; + + [XmlElement("StepDefinition")] + public List StepDefinitions = new List(); + } + + [XmlType(Namespace = StepDefinitionReport.XmlNamespace)] + public class StepDefinition + { + [XmlAttribute("type")] + public string Type; + + public Binding Binding; + public ScenarioStep ScenarioStep; + public List Instances = new List(); + } + + [XmlType(Namespace = StepDefinitionReport.XmlNamespace)] + public class Binding + { + public string MethodReference; + } + + [XmlType(Namespace = StepDefinitionReport.XmlNamespace)] + public class Instance + { + [XmlAttribute("fromScenarioOutline")] + public bool FromScenarioOutline; + public FeatureRef FeatureRef; + public ScenarioRef ScenarioRef; + public List Parameters; + public ScenarioStep ScenarioStep; + } + + [XmlType(Namespace = StepDefinitionReport.XmlNamespace)] + public class FeatureRef + { + [XmlAttribute("name")] + public string Name; + + [XmlAttribute("file")] + public string FilePath; + + } + + [XmlType(Namespace = StepDefinitionReport.XmlNamespace)] + public class ScenarioRef + { + [XmlAttribute("name")] + public string Name; + } + + [XmlType(Namespace = StepDefinitionReport.XmlNamespace)] + public class Parameter + { + [XmlAttribute("name")] + public string Name; + + [XmlText] + public string Value; + } +} \ No newline at end of file diff --git a/Reporting/StepDefinitionReport/StepDefinitionReport.xml b/Reporting/StepDefinitionReport/StepDefinitionReport.xml new file mode 100644 index 000000000..9d49e483a --- /dev/null +++ b/Reporting/StepDefinitionReport/StepDefinitionReport.xml @@ -0,0 +1,332 @@ + + + + + + + the Application Support User e-mail address is '' + + + + + + + + gr-app-support@grtest.at + + + the Application Support User e-mail address is 'gr-app-support@grtest.at' + + + + + + + some-other@grtest.at + + + the Application Support User e-mail address is 'some-other@grtest.at' + + + + + + + + there is some precondition + + + + + + + there is some precondition + + + + + + + there is some precondition + + + + + + + + there is an exchange rate in the database with: + +
+ + + code + + + rate + + + date + + + error code + + +
+ + + + + USD + + + 1.2 + + + 2009/09/15 + + + OK + + + + +
+ +
+ + + + + + there is an exchange rate in the database with: + +
+ + + code + + + rate + + + date + + + error code + + +
+ + + + + USD + + + 1.2 + + + 2009/09/15 + + + OK + + + + +
+
+
+ + + + + there is an exchange rate in the database with: + +
+ + + code + + + rate + + + date + + + error code + + +
+ + + + + USD + + + 1.2 + + + 2009/09/14 + + + OK + + + + + + + EUR + + + 1.2 + + + 2009/09/14 + + + OK + + + + +
+
+
+ + + + + there is an exchange rate in the database with: + +
+ + + code + + + rate + + + date + + + error code + + +
+ + + + + USD + + + 1.2 + + + 2009/09/14 + + + OK + + + + + + + EUR + + + 1.2 + + + 2009/09/14 + + + OK + + + + +
+
+
+
+
+ + + + + the XX Support User e-mail address is '' + + + + + + gr-app-support@grtest.at + + + + + the XX Support User e-mail address is 'gr-app-support@grtest.at' + + + + + + + something-else@grtest.at + + + the XX Support User e-mail address is 'gr-app-support@grtest.at' + + + + + + + + something where there is no binding yet + + + + + + + + something where there is no binding yet + + + + + + + something where there is no binding yet + + + + + + + + + something where there is no instances yet, just binding + + + +
\ No newline at end of file diff --git a/Reporting/StepDefinitionReport/StepDefinitionReport.xslt b/Reporting/StepDefinitionReport/StepDefinitionReport.xslt new file mode 100644 index 000000000..defe2336e --- /dev/null +++ b/Reporting/StepDefinitionReport/StepDefinitionReport.xslt @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + Step Definition Report + + + + + + + + + + + + + +

Givens

+ + + +

Whens

+ + + +

Thens

+ + + + + +
+ + + + + + + + + + + + + + + + noBinding + noInstances + + + + + + + + + + + + +
Step DefinitionInstances
+ + + + + + [show] + +
+
+ + + + + + / + + + (scenario outline example) + + + + + + + + + + + + + + + { + + } + + + + + + Used values for parameter '': + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Reporting/StepDefinitionReport/StepDefinitionReportGenerator.cs b/Reporting/StepDefinitionReport/StepDefinitionReportGenerator.cs new file mode 100644 index 000000000..9ad57fc5c --- /dev/null +++ b/Reporting/StepDefinitionReport/StepDefinitionReportGenerator.cs @@ -0,0 +1,343 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Xml; +using System.Xml.Serialization; +using System.Xml.Xsl; +using TechTalk.SpecFlow.Parser.SyntaxElements; +using TechTalk.SpecFlow.Reporting.StepDefinitionReport.ReportElements; + +namespace TechTalk.SpecFlow.Reporting.StepDefinitionReport +{ + internal class StepDefinitionReportGenerator + { + private readonly SpecFlowProject specFlowProject; + private readonly List bindings; + private readonly List parsedFeatures; + + private ReportElements.StepDefinitionReport report; + private Dictionary stepDefByBinding; + private Dictionary bindingByStepDef; + private readonly List stepDefsWithNoBinding = new List(); + + public StepDefinitionReportGenerator(SpecFlowProject specFlowProject, List bindings, List parsedFeatures) + { + this.specFlowProject = specFlowProject; + this.bindings = bindings; + this.parsedFeatures = parsedFeatures; + } + + public ReportElements.StepDefinitionReport GenerateReport() + { + report = new ReportElements.StepDefinitionReport(); + report.ProjectName = specFlowProject.ProjectName; + report.GeneratedAt = DateTime.Now.ToString("g", CultureInfo.InvariantCulture); + + stepDefByBinding = new Dictionary(); + bindingByStepDef = new Dictionary(); + + foreach (var bindingInfo in bindings) + { + var stepDefinition = new StepDefinition(); + stepDefinition.Binding = new Binding { MethodReference = bindingInfo.MethodReference }; + stepDefinition.Type = bindingInfo.BindingType; + + stepDefByBinding.Add(bindingInfo, stepDefinition); + bindingByStepDef.Add(stepDefinition, bindingInfo); + report.StepDefinitions.Add(stepDefinition); + } + + foreach (var feature in parsedFeatures) + { + var featureRef = new FeatureRef { FilePath = "some.feature", Name = feature.Title }; + if (feature.Background != null) + { + var scenarioRef = new ScenarioRef { Name = "Background" }; + AddStepInstances(featureRef, scenarioRef, feature.Background.Steps, false); + } + + foreach (var scenario in feature.Scenarios) + { + var scenarioRef = new ScenarioRef { Name = scenario.Title }; + if (scenario is ScenarioOutline) + { + ScenarioSteps firstExampleSteps = CreateFirstExampleScenarioSteps((ScenarioOutline) scenario); + AddStepInstances(featureRef, scenarioRef, firstExampleSteps, true); + } + else + { + AddStepInstances(featureRef, scenarioRef, scenario.Steps, false); + } + } + } + + foreach (var stepDefinition in report.StepDefinitions) + { + if (stepDefinition.ScenarioStep == null) + { + CreateSampleStep(stepDefinition); + } + + if (stepDefinition.Instances.Count == 0) + { + stepDefinition.Instances = null; + } + } + + return report; + } + + private ScenarioSteps CreateFirstExampleScenarioSteps(ScenarioOutline scenarioOutline) + { + foreach (var exampleSet in scenarioOutline.Examples.ExampleSets) + { + foreach (var example in exampleSet.Table.Body) + { + Dictionary paramSubst = new Dictionary(); + for (int i = 0; i < exampleSet.Table.Header.Cells.Length; i++) + { + paramSubst.Add(exampleSet.Table.Header.Cells[i].Value, example.Cells[i].Value); + } + + return CreateScenarioSteps(scenarioOutline, paramSubst); + } + } + return new ScenarioSteps(); + } + + private ScenarioSteps CreateScenarioSteps(ScenarioOutline scenarioOutline, Dictionary paramSubst) + { + ScenarioSteps result = new ScenarioSteps(); + foreach (var scenarioStep in scenarioOutline.Steps) + { + var newStep = Clone(scenarioStep); + newStep.Text = GetReplacedText(newStep.Text, paramSubst); + newStep.MultiLineTextArgument = GetReplacedText(newStep.MultiLineTextArgument, paramSubst); + + if (newStep.TableArg != null) + { + foreach (var row in newStep.TableArg.Body) + { + foreach (var cell in row.Cells) + { + cell.Value = GetReplacedText(cell.Value, paramSubst); + } + } + } + + result.Add(newStep); + } + return result; + } + + private string GetReplacedText(string text, Dictionary paramSubst) + { + if (text == null || paramSubst == null) + return text; + + foreach (var subst in paramSubst) + { + text = text.Replace("<" + subst.Key + ">", subst.Value); + } + + return text; + } + + private void CreateSampleStep(StepDefinition stepDefinition) + { + BindingInfo bindingInfo = bindingByStepDef[stepDefinition]; + Debug.Assert(bindingInfo != null); + switch (stepDefinition.Type) + { + case "Given": + stepDefinition.ScenarioStep = new Given(); + break; + case "When": + stepDefinition.ScenarioStep = new When(); + break; + case "Then": + stepDefinition.ScenarioStep = new Then(); + break; + default: + throw new InvalidOperationException(); + } + + stepDefinition.ScenarioStep.Text = GetSampleText(bindingInfo); + } + + private string GetSampleText(BindingInfo bindingInfo, string text, Match match) + { + StringBuilder sampleText = new StringBuilder(text); + for (int groupIndex = match.Groups.Count - 1; groupIndex >= 1; groupIndex--) + { + int paramIndex = groupIndex - 1; + var paramText = paramIndex >= bindingInfo.ParameterNames.Length ? "{?param?}" : + "{" + bindingInfo.ParameterNames[paramIndex] + "}"; + + var gr = match.Groups[groupIndex]; + sampleText.Remove(gr.Index, gr.Length); + sampleText.Insert(gr.Index, paramText); + } + return sampleText.ToString(); + } + + private string GetSampleText(BindingInfo bindingInfo) + { + var sampleText = bindingInfo.Regex.ToString().Trim('$', '^'); + Regex re = new Regex(@"\([^\)]+\)"); + int paramIndex = 0; + sampleText = re.Replace(sampleText, delegate + { + return paramIndex >= bindingInfo.ParameterNames.Length ? "{?param?}" : + "{" + bindingInfo.ParameterNames[paramIndex++] + "}"; + }); + return sampleText; + } + + public void TransformReport(string outputFilePath) + { + XmlSerializer serializer = new XmlSerializer(typeof(ReportElements.StepDefinitionReport), ReportElements.StepDefinitionReport.XmlNamespace); + + if (XsltHelper.IsXmlOutput(outputFilePath)) + { + XsltHelper.TransformXml(serializer, report, outputFilePath); + } + else + { + XsltHelper.TransformHtml(serializer, report, typeof(StepDefinitionReportGenerator), outputFilePath); + } + } + + private void AddStepInstances(FeatureRef featureRef, ScenarioRef scenarioRef, IEnumerable scenarioSteps, bool fromScenarioOutline) + { + string currentBlock = ""; + + foreach (var scenarioStep in scenarioSteps) + { + if (scenarioStep is Given || scenarioStep is When || scenarioStep is Then) + currentBlock = scenarioStep.GetType().Name; + + bool found = false; + + foreach (var bindingInfo in bindings) + { + if (bindingInfo.BindingType != currentBlock) + continue; + + var match = bindingInfo.Regex.Match(scenarioStep.Text); + if (!match.Success) + continue; + + Instance instance = new Instance + { + FromScenarioOutline = fromScenarioOutline, + ScenarioStep = scenarioStep, + FeatureRef = featureRef, + ScenarioRef = scenarioRef + }; + var regexArgs = match.Groups.Cast().Skip(1).Select(g => g.Value).ToArray(); + if (regexArgs.Length > 0) + { + instance.Parameters = new List(); + for (int i = 0; i < Math.Min(regexArgs.Length, bindingInfo.ParameterNames.Length); i++) + instance.Parameters.Add(new Parameter { Name = bindingInfo.ParameterNames[i], Value = regexArgs[i] }); + } + + var stepDefinition = stepDefByBinding[bindingInfo]; + stepDefinition.Instances.Add(instance); + + if (stepDefinition.ScenarioStep == null) + { + stepDefinition.ScenarioStep = CloneTo(scenarioStep, currentBlock); + stepDefinition.ScenarioStep.Text = GetSampleText(bindingInfo, stepDefinition.ScenarioStep.Text, match); + } + + found = true; + break; + } + + if (!found) + { + var stepDefinition = + stepDefsWithNoBinding.FirstOrDefault(sd => sd.ScenarioStep.Text.Equals(scenarioStep.Text)); + + if (stepDefinition == null) + { + stepDefinition = new StepDefinition(); + stepDefinition.Type = currentBlock; + stepDefinition.ScenarioStep = CloneTo(scenarioStep, currentBlock); + stepDefsWithNoBinding.Add(stepDefinition); + report.StepDefinitions.Add(stepDefinition); + } + + Instance instance = new Instance + { + FromScenarioOutline = fromScenarioOutline, + ScenarioStep = scenarioStep, + FeatureRef = featureRef, + ScenarioRef = scenarioRef + }; + stepDefinition.Instances.Add(instance); + } + } + } + + private ScenarioStep Clone(ScenarioStep step) + { + ScenarioStep newStep = null; + if (step is Given) + newStep = new Given(); + else if (step is When) + newStep = new When(); + else if (step is Then) + newStep = new Then(); + else if (step is And) + newStep = new And(); + else if (step is But) + newStep = new But(); + + Debug.Assert(newStep != null); + + newStep.Text = step.Text; + newStep.MultiLineTextArgument = step.MultiLineTextArgument; + newStep.TableArg = Clone(step.TableArg); + return newStep; + } + + private Table Clone(Table table) + { + if (table == null) + return null; + + return new Table(Clone(table.Header), table.Body.Select(r => Clone(r)).ToArray()); + } + + private Row Clone(Row row) + { + return new Row(row.Cells.Select(c => new Cell(){Value = c.Value}).ToArray()); + } + + private ScenarioStep CloneTo(ScenarioStep step, string currentBlock) + { + ScenarioStep newStep = null; + if (currentBlock == "Given") + newStep = new Given(); + else if (currentBlock == "When") + newStep = new When(); + else if (currentBlock == "Then") + newStep = new Then(); + + Debug.Assert(newStep != null); + + newStep.Text = step.Text; + newStep.MultiLineTextArgument = step.MultiLineTextArgument; + newStep.TableArg = Clone(step.TableArg); + return newStep; + } + } +} \ No newline at end of file diff --git a/Reporting/TechTalk.SpecFlow.Reporting.csproj b/Reporting/TechTalk.SpecFlow.Reporting.csproj new file mode 100644 index 000000000..921143103 --- /dev/null +++ b/Reporting/TechTalk.SpecFlow.Reporting.csproj @@ -0,0 +1,93 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {FC43509F-E7D3-40C4-B4C3-1E6C9D5530A4} + Exe + Properties + TechTalk.SpecFlow.Reporting + TechTalk.SpecFlow.Reporting + v3.5 + 512 + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + VersionInfo.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + {7CCEF6D6-FC17-422E-9BED-EDD752B6496F} + TechTalk.SpecFlow.Parser + + + + + \ No newline at end of file diff --git a/Reporting/TechTalk.SpecFlow.Reporting.csproj.vspscc b/Reporting/TechTalk.SpecFlow.Reporting.csproj.vspscc new file mode 100644 index 000000000..b6d32892f --- /dev/null +++ b/Reporting/TechTalk.SpecFlow.Reporting.csproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/Reporting/XmlResourceResolver.cs b/Reporting/XmlResourceResolver.cs new file mode 100644 index 000000000..df8cf2e3a --- /dev/null +++ b/Reporting/XmlResourceResolver.cs @@ -0,0 +1,27 @@ +using System; +using System.IO; +using System.Net; +using System.Reflection; +using System.Xml; + +namespace TechTalk.SpecFlow.Reporting +{ + public class XmlResourceResolver : XmlResolver + { + private ICredentials credentials; + + public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) + { + string resourceName = absoluteUri.AbsolutePath.TrimStart(Path.AltDirectorySeparatorChar).Replace(Path.AltDirectorySeparatorChar, Type.Delimiter); + string assemblyName = absoluteUri.Host; + + Assembly assembly = Assembly.Load(assemblyName); + return new ResourceXmlReader(assembly, resourceName); + } + + public override ICredentials Credentials + { + set { credentials = value; } + } + } +} \ No newline at end of file diff --git a/Reporting/XsltHelper.cs b/Reporting/XsltHelper.cs new file mode 100644 index 000000000..4bf8a792a --- /dev/null +++ b/Reporting/XsltHelper.cs @@ -0,0 +1,49 @@ +using System; +using System.IO; +using System.Linq; +using System.Text; +using System.Xml; +using System.Xml.Serialization; +using System.Xml.Xsl; + +namespace TechTalk.SpecFlow.Reporting +{ + internal static class XsltHelper + { + public static bool IsXmlOutput(string outputFilePath) + { + return Path.GetExtension(outputFilePath).Equals(".xml", StringComparison.InvariantCultureIgnoreCase); + } + + public static void TransformXml(XmlSerializer serializer, object report, string outputFilePath) + { + string xmlOutputPath = Path.ChangeExtension(outputFilePath, ".xml"); + + using (var writer = new StreamWriter(xmlOutputPath, false, Encoding.UTF8)) + { + serializer.Serialize(writer, report); + } + } + + public static void TransformHtml(XmlSerializer serializer, object report, Type reportType, string outputFilePath) + { + var xmlOutputWriter = new StringWriter(); + serializer.Serialize(xmlOutputWriter, report); + + XslCompiledTransform xslt = new XslCompiledTransform(); + var reportName = reportType.Name.Replace("Generator", ""); + using (var xsltReader = new ResourceXmlReader(reportType, reportName + ".xslt")) + { + xslt.Load(xsltReader, null, new XmlResourceResolver()); + } + + var xmlOutputReader = new XmlTextReader(new StringReader(xmlOutputWriter.ToString())); + + XsltArgumentList argumentList = new XsltArgumentList(); + using (var outFileStream = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write)) + { + xslt.Transform(xmlOutputReader, argumentList, outFileStream); + } + } + } +} diff --git a/Reporting/bin/Debug/Antlr3.Runtime.dll b/Reporting/bin/Debug/Antlr3.Runtime.dll new file mode 100644 index 000000000..e39f7cf5c Binary files /dev/null and b/Reporting/bin/Debug/Antlr3.Runtime.dll differ diff --git a/Reporting/bin/Debug/TechTalk.SpecFlow.Parser.dll b/Reporting/bin/Debug/TechTalk.SpecFlow.Parser.dll new file mode 100644 index 000000000..c29af2009 Binary files /dev/null and b/Reporting/bin/Debug/TechTalk.SpecFlow.Parser.dll differ diff --git a/Reporting/bin/Debug/TechTalk.SpecFlow.Parser.pdb b/Reporting/bin/Debug/TechTalk.SpecFlow.Parser.pdb new file mode 100644 index 000000000..546fbb9a7 Binary files /dev/null and b/Reporting/bin/Debug/TechTalk.SpecFlow.Parser.pdb differ diff --git a/Reporting/bin/Debug/TechTalk.SpecFlow.Reporting.exe b/Reporting/bin/Debug/TechTalk.SpecFlow.Reporting.exe new file mode 100644 index 000000000..3f46e1e0e Binary files /dev/null and b/Reporting/bin/Debug/TechTalk.SpecFlow.Reporting.exe differ diff --git a/Reporting/bin/Debug/TechTalk.SpecFlow.Reporting.pdb b/Reporting/bin/Debug/TechTalk.SpecFlow.Reporting.pdb new file mode 100644 index 000000000..712abaefd Binary files /dev/null and b/Reporting/bin/Debug/TechTalk.SpecFlow.Reporting.pdb differ diff --git a/Reporting/obj/Debug/TechTalk.SpecFlow.Reporting.csproj.FileListAbsolute.txt b/Reporting/obj/Debug/TechTalk.SpecFlow.Reporting.csproj.FileListAbsolute.txt new file mode 100644 index 000000000..71ad0051e --- /dev/null +++ b/Reporting/obj/Debug/TechTalk.SpecFlow.Reporting.csproj.FileListAbsolute.txt @@ -0,0 +1,8 @@ +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Reporting\bin\Debug\TechTalk.SpecFlow.Reporting.exe +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Reporting\bin\Debug\TechTalk.SpecFlow.Reporting.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Reporting\bin\Debug\TechTalk.SpecFlow.Parser.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Reporting\bin\Debug\Antlr3.Runtime.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Reporting\bin\Debug\TechTalk.SpecFlow.Parser.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Reporting\obj\Debug\ResolveAssemblyReference.cache +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Reporting\obj\Debug\TechTalk.SpecFlow.Reporting.exe +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Reporting\obj\Debug\TechTalk.SpecFlow.Reporting.pdb diff --git a/Reporting/obj/Debug/TechTalk.SpecFlow.Reporting.exe b/Reporting/obj/Debug/TechTalk.SpecFlow.Reporting.exe new file mode 100644 index 000000000..3f46e1e0e Binary files /dev/null and b/Reporting/obj/Debug/TechTalk.SpecFlow.Reporting.exe differ diff --git a/Reporting/obj/Debug/TechTalk.SpecFlow.Reporting.pdb b/Reporting/obj/Debug/TechTalk.SpecFlow.Reporting.pdb new file mode 100644 index 000000000..712abaefd Binary files /dev/null and b/Reporting/obj/Debug/TechTalk.SpecFlow.Reporting.pdb differ diff --git a/Runtime/Attributes.cs b/Runtime/Attributes.cs new file mode 100644 index 000000000..578e4e6f3 --- /dev/null +++ b/Runtime/Attributes.cs @@ -0,0 +1,111 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] + public class BindingAttribute : Attribute + { + + } + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + public abstract class ScenarioStepAttribute : Attribute + { + internal BindingType Type { get; private set; } + public string Regex { get; set; } + + internal ScenarioStepAttribute(BindingType type, string regex) + { + Type = type; + Regex = regex; + } + } + + public class GivenAttribute : ScenarioStepAttribute + { + public GivenAttribute(string regex) + : base(BindingType.Given, regex) + { + } + } + + public class WhenAttribute : ScenarioStepAttribute + { + public WhenAttribute(string regex) + : base(BindingType.When, regex) + { + } + } + + public class ThenAttribute : ScenarioStepAttribute + { + public ThenAttribute(string regex) + : base(BindingType.Then, regex) + { + } + } + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + public abstract class BindingEventAttribute : Attribute + { + internal BindingEvent Event { get; private set; } + public string[] Tags { get; private set; } + + internal BindingEventAttribute(BindingEvent bindingEvent, string[] tags) + { + Event = bindingEvent; + Tags = tags; + } + } + + public class BeforeTestRun : BindingEventAttribute + { + public BeforeTestRun() : base(BindingEvent.TestRunStart, null) {} + } + + public class AfterTestRun : BindingEventAttribute + { + public AfterTestRun() : base(BindingEvent.TestRunEnd, null) { } + } + + public class BeforeFeature : BindingEventAttribute + { + public BeforeFeature(params string[] tags) : base(BindingEvent.FeatureStart, tags) { } + } + + public class AfterFeature : BindingEventAttribute + { + public AfterFeature(params string[] tags) : base(BindingEvent.FeatureEnd, tags) { } + } + + public class BeforeScenario : BindingEventAttribute + { + public BeforeScenario(params string[] tags) : base(BindingEvent.ScenarioStart, tags) { } + } + + public class AfterScenario : BindingEventAttribute + { + public AfterScenario(params string[] tags) : base(BindingEvent.ScenarioEnd, tags) { } + } + + public class BeforeScenarioBlock : BindingEventAttribute + { + public BeforeScenarioBlock(params string[] tags) : base(BindingEvent.BlockStart, tags) { } + } + + public class AfterScenarioBlock : BindingEventAttribute + { + public AfterScenarioBlock(params string[] tags) : base(BindingEvent.BlockEnd, tags) { } + } + + public class BeforeStep : BindingEventAttribute + { + public BeforeStep(params string[] tags) : base(BindingEvent.StepStart, tags) { } + } + + public class AfterStep : BindingEventAttribute + { + public AfterStep(params string[] tags) : base(BindingEvent.StepEnd, tags) { } + } +} \ No newline at end of file diff --git a/Runtime/BindingException.cs b/Runtime/BindingException.cs new file mode 100644 index 000000000..b933f4e8e --- /dev/null +++ b/Runtime/BindingException.cs @@ -0,0 +1,65 @@ +using System; +using System.Linq; +using System.Runtime.Serialization; + +namespace TechTalk.SpecFlow +{ + [Serializable] + public class BindingException : Exception + { + // + // For guidelines regarding the creation of new exception types, see + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp + // and + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp + // + + public BindingException() + { + } + + public BindingException(string message) : base(message) + { + } + + public BindingException(string message, Exception inner) : base(message, inner) + { + } + + protected BindingException( + SerializationInfo info, + StreamingContext context) : base(info, context) + { + } + } + + [Serializable] + public class MissingStepDefinitionException : Exception + { + public MissingStepDefinitionException() + : base("No matching step definition found for one or more steps.") + { + } + + protected MissingStepDefinitionException( + SerializationInfo info, + StreamingContext context) : base(info, context) + { + } + } + + [Serializable] + public class PendingStepException : Exception + { + public PendingStepException() + : base("One or more step definitions are not implemented yet.") + { + } + + protected PendingStepException( + SerializationInfo info, + StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/Runtime/BindingMatch.cs b/Runtime/BindingMatch.cs new file mode 100644 index 000000000..e1cc8b08a --- /dev/null +++ b/Runtime/BindingMatch.cs @@ -0,0 +1,22 @@ +using System; +using System.Linq; +using System.Text.RegularExpressions; + +namespace TechTalk.SpecFlow +{ + internal class BindingMatch + { + public StepBinding StepBinding { get; private set; } + public Match Match { get; private set; } + public object[] ExtraArguments { get; private set; } + public StepArgs StepArgs { get; private set; } + + public BindingMatch(StepBinding stepBinding, Match match, object[] extraArguments, StepArgs stepArgs) + { + StepBinding = stepBinding; + Match = match; + ExtraArguments = extraArguments; + StepArgs = stepArgs; + } + } +} \ No newline at end of file diff --git a/Runtime/BindingRegistry.cs b/Runtime/BindingRegistry.cs new file mode 100644 index 000000000..ed5b82a8f --- /dev/null +++ b/Runtime/BindingRegistry.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text.RegularExpressions; + +namespace TechTalk.SpecFlow +{ + internal enum BindingEvent + { + TestRunStart, + TestRunEnd, + FeatureStart, + FeatureEnd, + ScenarioStart, + ScenarioEnd, + BlockStart, + BlockEnd, + StepStart, + StepEnd + } + + internal class BindingRegistry : IEnumerable + { + private readonly List stepBindings = new List(); + private readonly Dictionary> eventBindings = new Dictionary>(); + + public void BuildBindingsFromAssembly(Assembly assembly) + { + foreach (Type type in assembly.GetTypes()) + { + BindingAttribute bindingAttr = (BindingAttribute)Attribute.GetCustomAttribute(type, typeof (BindingAttribute)); + if (bindingAttr == null) + continue; + + BuildBindingsFromType(type); + } + } + + private void BuildBindingsFromType(Type type) + { + foreach (MethodInfo method in type.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) + { + var scenarioStepAttrs = Attribute.GetCustomAttributes(method, typeof(ScenarioStepAttribute)); + if (scenarioStepAttrs != null) + foreach (ScenarioStepAttribute scenarioStepAttr in scenarioStepAttrs) + { + BuildStepBindingFromMethod(method, scenarioStepAttr); + } + + var bindingEventAttrs = Attribute.GetCustomAttributes(method, typeof(BindingEventAttribute)); + if (bindingEventAttrs != null) + foreach (BindingEventAttribute bindingEventAttr in bindingEventAttrs) + { + BuildEventBindingFromMethod(method, bindingEventAttr); + } + } + } + + public List GetEvents(BindingEvent bindingEvent) + { + List list; + if (!eventBindings.TryGetValue(bindingEvent, out list)) + { + list = new List(); + eventBindings.Add(bindingEvent, list); + } + + return list; + } + + private void BuildEventBindingFromMethod(MethodInfo method, BindingEventAttribute bindingEventAttr) + { + CheckEventBindingMethod(method); + + Delegate bindingAction = CreateBindingAction(method); + var eventBinding = new EventBinding(bindingAction, bindingEventAttr.Tags, method); + + GetEvents(bindingEventAttr.Event).Add(eventBinding); + } + + private void CheckEventBindingMethod(MethodInfo method) + { + if (!method.IsStatic) + throw new Exception("The event binding method must be static! " + method.ToString()); + + //TODO: check parameters, etc. + } + + private void BuildStepBindingFromMethod(MethodInfo method, ScenarioStepAttribute scenarioStepAttr) + { + CheckStepBindingMethod(method); + + Regex regex = new Regex("^" + scenarioStepAttr.Regex + "$", RegexOptions.Compiled | RegexOptions.CultureInvariant); + Delegate bindingAction = CreateBindingAction(method); + var parameterTypes = method.GetParameters().Select(pi => pi.ParameterType).ToArray(); + StepBinding stepBinding = new StepBinding(scenarioStepAttr.Type, regex, bindingAction, parameterTypes, method); + + stepBindings.Add(stepBinding); + } + + private void CheckStepBindingMethod(MethodInfo method) + { +// if (!method.IsStatic) +// throw new Exception("The binding method must be static! " + method.ToString()); + + //TODO: check parameters, etc. + } + + private Delegate CreateBindingAction(MethodInfo method) + { + List parameters = new List(); + foreach (ParameterInfo parameterInfo in method.GetParameters()) + { + parameters.Add(Expression.Parameter(parameterInfo.ParameterType, parameterInfo.Name)); + } + + LambdaExpression lambda; + + if (method.IsStatic) + { + lambda = Expression.Lambda( + Expression.Call(method, parameters.Cast().ToArray()), + parameters.ToArray()); + } + else + { + Type bindingType = method.DeclaringType; + Expression> getInstanceExpression = + () => ScenarioContext.Current.GetBindingInstance(bindingType); + + lambda = Expression.Lambda( + Expression.Call( + Expression.Convert(getInstanceExpression.Body, bindingType), + method, + parameters.Cast().ToArray()), + parameters.ToArray()); + } + + + return lambda.Compile(); + } + + public IEnumerator GetEnumerator() + { + return stepBindings.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} \ No newline at end of file diff --git a/Runtime/BindingType.cs b/Runtime/BindingType.cs new file mode 100644 index 000000000..b76e10a95 --- /dev/null +++ b/Runtime/BindingType.cs @@ -0,0 +1,35 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow +{ + internal enum BindingType + { + Given = ScenarioBlock.Given, + When = ScenarioBlock.When, + Then = ScenarioBlock.Then + } + + internal static class BindingTypeHelper + { + public static BindingType ToBindingType(this ScenarioBlock block) + { + if (block != ScenarioBlock.Given && + block != ScenarioBlock.When && + block != ScenarioBlock.Then) + throw new ArgumentException("Unable to convert block to binding type", "block"); + + return (BindingType)((int)block); + } + + public static ScenarioBlock ToScenarioBlock(this BindingType bindingType) + { + return (ScenarioBlock)((int)bindingType); + } + + public static bool Equals(this ScenarioBlock block, BindingType bindingType) + { + return (int)block == (int)bindingType; + } + } +} \ No newline at end of file diff --git a/Runtime/Configuration.cs b/Runtime/Configuration.cs new file mode 100644 index 000000000..8e451eeee --- /dev/null +++ b/Runtime/Configuration.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; + +namespace TechTalk.SpecFlow +{ + internal class Configuration + { + static public Configuration Current + { + get { return ObjectContainer.Configuration; } + } + + private const bool StopAtFirstErrorDefault = false; + private const bool UseIgnoreForMissingOrPendingStepsDefault = false; + private const bool TraceTimingsDefault = false; + private const bool TraceSuccessfulStepsDefault = true; + private const bool DetectAmbiguousMatchesDefault = true; + private const double MinTracedDurationDefault = 0.1; + + public bool StopAtFirstError { get; set; } + public bool DetectAmbiguousMatches { get; set; } + public bool TraceSuccessfulSteps { get; set; } + public bool TraceTimings { get; set; } + public bool UseIgnoreForMissingOrPendingSteps { get; set; } + public TimeSpan MinTracedDuration { get; set; } + + public Configuration() + { + MinTracedDuration = TimeSpan.FromSeconds(MinTracedDurationDefault); + DetectAmbiguousMatches = DetectAmbiguousMatchesDefault; + TraceSuccessfulSteps = TraceSuccessfulStepsDefault; + TraceTimings = TraceTimingsDefault; + UseIgnoreForMissingOrPendingSteps = UseIgnoreForMissingOrPendingStepsDefault; + StopAtFirstError = StopAtFirstErrorDefault; + } + + private static bool GetBoolConfig(string name, bool defaultValue) + { + string value = ConfigurationManager.AppSettings["SpecFlow." + name]; + if (value == null) + return defaultValue; + return bool.Parse(value); + } + + private static double GetDoubleConfig(string name, double defaultValue) + { + string value = ConfigurationManager.AppSettings["SpecFlow." + name]; + if (value == null) + return defaultValue; + return double.Parse(value); + } + + public static Configuration LoadFromConfigFile() + { + var config = new Configuration(); + config.MinTracedDuration = TimeSpan.FromSeconds(GetDoubleConfig("MinTracedDuration", MinTracedDurationDefault)); + config.DetectAmbiguousMatches = GetBoolConfig("DetectAmbiguousMatches", DetectAmbiguousMatchesDefault); + config.TraceSuccessfulSteps = GetBoolConfig("TraceSuccessfulSteps", TraceSuccessfulStepsDefault); + config.TraceTimings = GetBoolConfig("TraceTimings", TraceTimingsDefault); + config.UseIgnoreForMissingOrPendingSteps = GetBoolConfig("UseIgnoreForMissingOrPendingSteps", UseIgnoreForMissingOrPendingStepsDefault); + config.StopAtFirstError = GetBoolConfig("StopAtFirstError", StopAtFirstErrorDefault); + return config; + } + } +} diff --git a/Runtime/EventBinding.cs b/Runtime/EventBinding.cs new file mode 100644 index 000000000..2850c1e6c --- /dev/null +++ b/Runtime/EventBinding.cs @@ -0,0 +1,20 @@ +using System; +using System.Linq; +using System.Reflection; + +namespace TechTalk.SpecFlow +{ + internal class EventBinding + { + public Delegate BindingAction { get; private set; } + public string[] Tags { get; private set; } + public MethodInfo MethodInfo { get; private set; } + + public EventBinding(Delegate bindingAction, string[] tags, MethodInfo methodInfo) + { + BindingAction = bindingAction; + Tags = tags; + MethodInfo = methodInfo; + } + } +} \ No newline at end of file diff --git a/Runtime/FeatureContext.cs b/Runtime/FeatureContext.cs new file mode 100644 index 000000000..341de5e5b --- /dev/null +++ b/Runtime/FeatureContext.cs @@ -0,0 +1,25 @@ +using System; +using System.Diagnostics; +using System.Linq; + +namespace TechTalk.SpecFlow +{ + public class FeatureContext : SpecFlowContext + { + static public FeatureContext Current + { + get { return ObjectContainer.FeatureContext; } + } + + public FeatureInfo FeatureInfo { get; private set; } + internal Stopwatch Stopwatch { get; private set; } + + public FeatureContext(FeatureInfo featureInfo) + { + Stopwatch = new Stopwatch(); + Stopwatch.Start(); + + FeatureInfo = featureInfo; + } + } +} \ No newline at end of file diff --git a/Runtime/FeatureInfo.cs b/Runtime/FeatureInfo.cs new file mode 100644 index 000000000..a8d6aa51f --- /dev/null +++ b/Runtime/FeatureInfo.cs @@ -0,0 +1,19 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow +{ + public class FeatureInfo + { + public string[] Tags { get; private set; } + public string Title { get; private set; } + public string Description { get; private set; } + + public FeatureInfo(string title, string description, params string[] tags) + { + Title = title; + Description = description; + Tags = tags; + } + } +} \ No newline at end of file diff --git a/Runtime/ITestRunner.cs b/Runtime/ITestRunner.cs new file mode 100644 index 000000000..0c780d6d6 --- /dev/null +++ b/Runtime/ITestRunner.cs @@ -0,0 +1,84 @@ +using System.Reflection; + +namespace TechTalk.SpecFlow +{ + public interface ITestRunner + { + void InitializeTestRunner(Assembly[] bindingAssemblies); + + void OnFeatureStart(FeatureInfo featureInfo); + void OnFeatureEnd(); + void OnScenarioStart(ScenarioInfo scenarioInfo); + void CollectScenarioErrors(); + void OnScenarioEnd(); + + void Given(string text, string multilineTextArg, Table tableArg); + void When(string text, string multilineTextArg, Table tableArg); + void Then(string text, string multilineTextArg, Table tableArg); + void And(string text, string multilineTextArg, Table tableArg); + void But(string text, string multilineTextArg, Table tableArg); + + void Pending(); + } + + public static class TestRunnerDefaultArguments + { + public static void Given(this ITestRunner testRunner, string text) + { + testRunner.Given(text, null, null); + } + + public static void Given(this ITestRunner testRunner, string text, string multilineTextArg) + { + testRunner.Given(text, multilineTextArg, null); + } + + public static void When(this ITestRunner testRunner, string text) + { + testRunner.When(text, null, null); + } + + public static void When(this ITestRunner testRunner, string text, string multilineTextArg) + { + testRunner.When(text, multilineTextArg, null); + } + + public static void Then(this ITestRunner testRunner, string text) + { + testRunner.Then(text, null, null); + } + + public static void Then(this ITestRunner testRunner, string text, string multilineTextArg) + { + testRunner.Then(text, multilineTextArg, null); + } + + public static void And(this ITestRunner testRunner, string text) + { + testRunner.And(text, null, null); + } + + public static void And(this ITestRunner testRunner, string text, string multilineTextArg) + { + testRunner.And(text, multilineTextArg, null); + } + + public static void But(this ITestRunner testRunner, string text) + { + testRunner.But(text, null, null); + } + + public static void But(this ITestRunner testRunner, string text, string multilineTextArg) + { + testRunner.But(text, multilineTextArg, null); + } + } + + public static class TestRunnerManager + { + public static ITestRunner GetTestRunner() + { + return ObjectContainer.EnsureTestRunner(Assembly.GetCallingAssembly()); + } + } +} \ No newline at end of file diff --git a/Runtime/ObjectContainer.cs b/Runtime/ObjectContainer.cs new file mode 100644 index 000000000..3a369b821 --- /dev/null +++ b/Runtime/ObjectContainer.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using TechTalk.SpecFlow.TestFrameworkIntegration; + +namespace TechTalk.SpecFlow +{ + internal class ObjectContainer + { + #region Configuration + private static Configuration configuration = null; + + public static Configuration Configuration + { + get + { + if (configuration == null) + { + configuration = Configuration.LoadFromConfigFile(); + } + return configuration; + } + } + #endregion + + #region TestRunner + private static ITestRunner testRunner = null; + + private static ITestRunner CreateTestRunner() + { + return new TestRunner(); //TODO: factory from config? + } + + public static ITestRunner TestRunner + { + get + { + return EnsureTestRunner(Assembly.GetCallingAssembly()); + } + internal set + { + testRunner = value; + } + } + + internal static ITestRunner EnsureTestRunner(Assembly callingAssembly) + { + if (testRunner == null) + { + testRunner = CreateTestRunner(); + + List bindingAssemblies = new List(); + bindingAssemblies.Add(callingAssembly); //TODO: add more assemblies from config + testRunner.InitializeTestRunner(bindingAssemblies.ToArray()); + } + return testRunner; + } + + #endregion + + #region FeautreContext + + private static FeatureContext featureContext = null; + + static public FeatureContext FeatureContext + { + get + { + if (featureContext == null) + return null; + return featureContext; + } + internal set + { + if (featureContext != null) + { + if (value != null) + TestTracer.Warning("The previous feature context was not disposed."); + DisposeFeatureContext(); + } + + featureContext = value; + } + } + + private static void DisposeFeatureContext() + { + ((IDisposable)featureContext).Dispose(); + featureContext = null; + } + + #endregion + + #region ScenarioContext + + private static ScenarioContext scenarioContext = null; + + static public ScenarioContext ScenarioContext + { + get + { + if (scenarioContext == null) + return null; + return scenarioContext; + } + internal set + { + if (scenarioContext != null) + { + if (value != null) + TestTracer.Warning("The previous scenario context was not disposed."); + DisposeScenarioContext(); + } + + scenarioContext = value; + } + } + + private static void DisposeScenarioContext() + { + ((IDisposable)scenarioContext).Dispose(); + scenarioContext = null; + } + + #endregion + + #region TestTracer + private static TestTracer testTracer = null; + + public static TestTracer TestTracer + { + get + { + if (testTracer == null) + { + testTracer = new ConsoleTestTracer(); + } + return testTracer; + } + } + #endregion + + #region TestFrameworkIntegration + private static ITestFrameworkIntegration testFrameworkIntegration = null; + + public static ITestFrameworkIntegration TestFrameworkIntegration + { + get + { + if (testFrameworkIntegration == null) + { + testFrameworkIntegration = new NUnitIntegration(); + } + return testFrameworkIntegration; + } + } + #endregion + } +} \ No newline at end of file diff --git a/Runtime/Properties/AssemblyInfo.cs b/Runtime/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..72a77457c --- /dev/null +++ b/Runtime/Properties/AssemblyInfo.cs @@ -0,0 +1,25 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 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("TechTalk.SpecFlow")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TechTalk.SpecFlow")] +[assembly: AssemblyCopyright("Copyright © 2009")] +[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)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("cba254bb-2476-4e96-9a9f-6db1a1b5eb62")] + +[assembly: InternalsVisibleTo("TechTalk.SpecFlow.RuntimeTests")] diff --git a/Runtime/ScenarioBlock.cs b/Runtime/ScenarioBlock.cs new file mode 100644 index 000000000..e1e1644de --- /dev/null +++ b/Runtime/ScenarioBlock.cs @@ -0,0 +1,22 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow +{ + public enum ScenarioBlock + { + None, + Given, + When, + Then, + } + + internal enum StepDefinitionKeyword + { + Given, + When, + Then, + And, + But + } +} \ No newline at end of file diff --git a/Runtime/ScenarioContext.cs b/Runtime/ScenarioContext.cs new file mode 100644 index 000000000..c4cb6a2f0 --- /dev/null +++ b/Runtime/ScenarioContext.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace TechTalk.SpecFlow +{ + internal enum TestStatus + { + OK, + StepDefinitionPending, + MissingStepDefinition, + BindingError, + TestError + } + + public class ScenarioContext : SpecFlowContext + { + static public ScenarioContext Current + { + get { return ObjectContainer.ScenarioContext; } + } + + public ScenarioInfo ScenarioInfo { get; private set; } + + public ScenarioBlock CurrentScenarioBlock { get; internal set; } + + internal TestStatus TestStatus { get; set; } + internal Exception TestError { get; set; } + internal List PendingSteps { get; private set; } + internal List MissingSteps { get; private set; } + internal Stopwatch Stopwatch { get; private set; } + + public ScenarioContext(ScenarioInfo scenarioInfo) + { + Stopwatch = new Stopwatch(); + Stopwatch.Start(); + + CurrentScenarioBlock = ScenarioBlock.None; + ScenarioInfo = scenarioInfo; + TestStatus = TestStatus.OK; + PendingSteps = new List(); + MissingSteps = new List(); + } + + public void Pending() + { + ObjectContainer.TestRunner.Pending(); + } + + private Dictionary bindingInstances = new Dictionary(); + + public object GetBindingInstance(Type bindingType) + { + object value; + if (!bindingInstances.TryGetValue(bindingType, out value)) + { + value = Activator.CreateInstance(bindingType); + bindingInstances.Add(bindingType, value); + } + + return value; + } + } +} \ No newline at end of file diff --git a/Runtime/ScenarioInfo.cs b/Runtime/ScenarioInfo.cs new file mode 100644 index 000000000..3470a80e1 --- /dev/null +++ b/Runtime/ScenarioInfo.cs @@ -0,0 +1,17 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow +{ + public class ScenarioInfo + { + public string[] Tags { get; private set; } + public string Title { get; private set; } + + public ScenarioInfo(string title, params string[] tags) + { + Title = title; + Tags = tags; + } + } +} \ No newline at end of file diff --git a/Runtime/SpecFlowContext.cs b/Runtime/SpecFlowContext.cs new file mode 100644 index 000000000..e96e5fb89 --- /dev/null +++ b/Runtime/SpecFlowContext.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace TechTalk.SpecFlow +{ + public abstract class SpecFlowContext : Dictionary, IDisposable + { + protected virtual void Dispose() + { + } + + void IDisposable.Dispose() + { + Dispose(); + } + + public bool TryGetValue(string key, out TValue value) + { + object result; + if (base.TryGetValue(key, out result)) + { + value = (TValue)result; + return true; + } + + value = default(TValue); + return false; + } + } +} \ No newline at end of file diff --git a/Runtime/StepArgs.cs b/Runtime/StepArgs.cs new file mode 100644 index 000000000..88b085011 --- /dev/null +++ b/Runtime/StepArgs.cs @@ -0,0 +1,23 @@ +using System; +using System.Linq; + +namespace TechTalk.SpecFlow +{ + internal class StepArgs + { + public StepDefinitionKeyword StepDefinitionKeyword { get; private set; } + public BindingType Type { get; private set; } + public string Text { get; private set; } + public string MultilineTextArgument { get; private set; } + public Table TableArgument { get; private set; } + + public StepArgs(BindingType type, StepDefinitionKeyword stepDefinitionKeyword, string text, string multilineTextArgument, Table tableArgument) + { + Type = type; + StepDefinitionKeyword = stepDefinitionKeyword; + Text = text; + MultilineTextArgument = multilineTextArgument; + TableArgument = tableArgument; + } + } +} \ No newline at end of file diff --git a/Runtime/StepBinding.cs b/Runtime/StepBinding.cs new file mode 100644 index 000000000..afc536959 --- /dev/null +++ b/Runtime/StepBinding.cs @@ -0,0 +1,26 @@ +using System; +using System.Linq; +using System.Reflection; +using System.Text.RegularExpressions; + +namespace TechTalk.SpecFlow +{ + internal class StepBinding + { + public BindingType Type { get; private set; } + public Regex Regex { get; private set; } + public Delegate BindingAction { get; private set; } + public Type[] ParameterTypes { get; private set; } + public MethodInfo MethodInfo { get; private set; } + + + public StepBinding(BindingType type, Regex regex, Delegate bindingAction, Type[] parameterTypes, MethodInfo methodInfo) + { + Type = type; + Regex = regex; + BindingAction = bindingAction; + ParameterTypes = parameterTypes; + MethodInfo = methodInfo; + } + } +} \ No newline at end of file diff --git a/Runtime/StringExtensions.cs b/Runtime/StringExtensions.cs new file mode 100644 index 000000000..c58446dd8 --- /dev/null +++ b/Runtime/StringExtensions.cs @@ -0,0 +1,59 @@ +using System; +using System.Linq; +using System.Text.RegularExpressions; + +namespace TechTalk.SpecFlow +{ + internal static class StringExtensions + { + public static string Indent(this string text, string indent) + { + if (text.EndsWith(Environment.NewLine)) + { + return text.Remove(text.Length - Environment.NewLine.Length).Indent(indent) + Environment.NewLine; + } + + return indent + text.Replace(Environment.NewLine, Environment.NewLine + indent); + } + + public static string ToIdentifier(this string text) + { + Regex firstWordCharRe = new Regex(@"(?
[^a-zA-Z]+)(?[a-zA-Z])");
+            text = firstWordCharRe.Replace(text, match => match.Groups["pre"].Value + match.Groups["fc"].Value.ToUpper());
+
+            Regex punctCharRe = new Regex(@"[\n\.-]+");
+            text = punctCharRe.Replace(text, "_");
+
+            Regex nonWordCharRe = new Regex(@"[^a-zA-Z0-9_]+");
+            text = nonWordCharRe.Replace(text, "");
+
+            if (text.Length > 0)
+            {
+                text = text.Substring(0, 1).ToUpper() + text.Substring(1);
+
+                if (char.IsDigit(text[0]))
+                    text = "_" + text;
+            }
+
+            return text;
+        }
+
+        public static string ToIdentifierCamelCase(this string text)
+        {
+            string identifier = ToIdentifier(text);
+            if (text.Length > 0)
+                identifier = identifier.Substring(0, 1).ToLower() + identifier.Substring(1);
+
+            return identifier;
+        }
+
+        public static string TrimEllipse(this string text, int maxLength)
+        {
+            if (text == null || text.Length <= maxLength)
+                return text;
+
+            const string ellipse = "...";
+            return text.Substring(0, maxLength - ellipse.Length) + ellipse;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Runtime/Table.cs b/Runtime/Table.cs
new file mode 100644
index 000000000..789461258
--- /dev/null
+++ b/Runtime/Table.cs
@@ -0,0 +1,179 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+
+namespace TechTalk.SpecFlow
+{
+    public class Table
+    {
+        private readonly string[] header;
+        private readonly TableRows rows = new TableRows();
+
+        public IEnumerable Header
+        {
+            get { return header; }
+        }
+
+        public TableRows Rows
+        {
+            get { return rows; }
+        }
+
+        public int RowCount
+        {
+            get { return rows.Count; }
+        }
+
+        public Table(params string[] header)
+        {
+            if (header == null || header.Length == 0)
+                throw new ArgumentException("invalid header count", "header");
+
+            for (int colIndex = 0; colIndex < header.Length; colIndex++)
+                header[colIndex] = header[colIndex] ?? string.Empty;
+            this.header = header;
+        }
+
+        internal int GetHeaderIndex(string column)
+        {
+            int index = Array.IndexOf(header, column);
+            if (index < 0)
+                throw new Exception("could not find column");
+            return index;
+        }
+
+        public void AddRow(params string[] cells)
+        {
+            if (cells == null || cells.Length != header.Length)
+                throw new Exception("invalid cell count");
+
+            var row = new TableRow(this, cells);
+            rows.Add(row);
+        }
+
+        public override string ToString()
+        {
+            int[] columnWidths = new int[header.Length];
+            for (int colIndex = 0; colIndex < header.Length; colIndex++)
+                columnWidths[colIndex] = header[colIndex].Length;
+
+            foreach (TableRow row in rows)
+            {
+                for (int colIndex = 0; colIndex < header.Length; colIndex++)
+                    columnWidths[colIndex] = Math.Max(columnWidths[colIndex], row[colIndex].Length);
+            }
+
+            StringBuilder builder = new StringBuilder();
+            AddTableRow(builder, header, columnWidths);
+            foreach (TableRow row in rows)
+                AddTableRow(builder, row.Select(pair => pair.Value), columnWidths);
+            return builder.ToString();
+        }
+
+        private void AddTableRow(StringBuilder builder, IEnumerable cells, int[] widths)
+        {
+            const string margin = " ";
+            const string separator = "|";
+            int colIndex = 0;
+
+            builder.Append(separator);
+            foreach (string cell in cells)
+            {
+                builder.Append(margin);
+
+                builder.Append(cell);
+                builder.Append(' ', widths[colIndex] - cell.Length);
+
+                builder.Append(margin);
+                builder.Append(separator);
+
+                colIndex++;
+            }
+
+            builder.AppendLine();
+        }
+    }
+
+    public class TableRows : IEnumerable
+    {
+        private readonly List innerList = new List();
+
+        public int Count { get { return innerList.Count; } }
+
+        public TableRow this[int index]
+        {
+            get { return innerList[index]; }
+        }
+
+        public IEnumerator GetEnumerator()
+        {
+            return innerList.GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        internal void Add(TableRow row)
+        {
+            innerList.Add(row);
+        }
+    }
+
+    public class TableRow : IEnumerable>
+    {
+        private readonly Table table;
+        private readonly string[] items;
+
+        internal TableRow(Table table, string[] items)
+        {
+            for (int colIndex = 0; colIndex < items.Length; colIndex++)
+                items[colIndex] = items[colIndex] ?? string.Empty;
+
+            this.table = table;
+            this.items = items;
+        }
+
+        public string this[string header]
+        {
+            get
+            {
+                int itemIndex = table.GetHeaderIndex(header);
+                return items[itemIndex];
+            }
+        }
+
+        public string this[int index]
+        {
+            get
+            {
+                return items[index];
+            }
+        }
+
+        public int Count
+        {
+            get { return items.Length; }
+        }
+
+        public IEnumerator> GetEnumerator()
+        {
+            Debug.Assert(items.Length == table.Header.Count());
+            int itemIndex = 0;
+            foreach (string header in table.Header)
+            {
+                yield return new KeyValuePair(header, items[itemIndex]);
+                itemIndex++;
+            }
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Runtime/TechTalk.SpecFlow.csproj b/Runtime/TechTalk.SpecFlow.csproj
new file mode 100644
index 000000000..02901fe64
--- /dev/null
+++ b/Runtime/TechTalk.SpecFlow.csproj
@@ -0,0 +1,93 @@
+
+
+  
+    Debug
+    AnyCPU
+    9.0.30729
+    2.0
+    {413EE28C-4F89-4C6F-BA1E-2CDEE4CD43B4}
+    Library
+    Properties
+    TechTalk.SpecFlow
+    TechTalk.SpecFlow
+    v3.5
+    512
+    SAK
+    SAK
+    SAK
+    SAK
+  
+  
+    true
+    full
+    false
+    bin\Debug\
+    DEBUG;TRACE
+    prompt
+    4
+  
+  
+    pdbonly
+    true
+    bin\Release\
+    TRACE
+    prompt
+    4
+  
+  
+    
+      False
+      ..\lib\nunit\nunit.framework.dll
+    
+    
+    
+    
+      3.5
+    
+    
+      3.5
+    
+    
+      3.5
+    
+    
+    
+  
+  
+    
+      VersionInfo.cs
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  
+  
+  
+
\ No newline at end of file
diff --git a/Runtime/TechTalk.SpecFlow.csproj.vspscc b/Runtime/TechTalk.SpecFlow.csproj.vspscc
new file mode 100644
index 000000000..b6d32892f
--- /dev/null
+++ b/Runtime/TechTalk.SpecFlow.csproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/Runtime/TestFrameworkIntegration/ITestFrameworkIntegration.cs b/Runtime/TestFrameworkIntegration/ITestFrameworkIntegration.cs
new file mode 100644
index 000000000..5f23ad23c
--- /dev/null
+++ b/Runtime/TestFrameworkIntegration/ITestFrameworkIntegration.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace TechTalk.SpecFlow.TestFrameworkIntegration
+{
+    public interface ITestFrameworkIntegration
+    {
+        void TestInconclusive(string message);
+        void TestIgnore(string message);
+    }
+}
\ No newline at end of file
diff --git a/Runtime/TestFrameworkIntegration/NUnitIntegration.cs b/Runtime/TestFrameworkIntegration/NUnitIntegration.cs
new file mode 100644
index 000000000..8003d06a0
--- /dev/null
+++ b/Runtime/TestFrameworkIntegration/NUnitIntegration.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Linq;
+using NUnit.Framework;
+
+namespace TechTalk.SpecFlow.TestFrameworkIntegration
+{
+    public class NUnitIntegration : ITestFrameworkIntegration
+    {
+        public void TestInconclusive(string message)
+        {
+            Assert.Inconclusive(message);
+        }
+
+        public void TestIgnore(string message)
+        {
+            Assert.Ignore(message);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Runtime/TestRunner.cs b/Runtime/TestRunner.cs
new file mode 100644
index 000000000..999de8fb9
--- /dev/null
+++ b/Runtime/TestRunner.cs
@@ -0,0 +1,417 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Text.RegularExpressions;
+
+namespace TechTalk.SpecFlow
+{
+    public class TestRunner : ITestRunner
+    {
+        private BindingRegistry bindingRegistry = null;
+
+        public virtual void InitializeTestRunner(Assembly[] bindingAssemblies)
+        {
+            bindingRegistry = new BindingRegistry();
+            foreach (Assembly assembly in bindingAssemblies)
+            {
+                bindingRegistry.BuildBindingsFromAssembly(assembly);
+            }
+
+            OnTestRunnerStart();
+            AppDomain.CurrentDomain.DomainUnload += 
+                delegate
+                    {
+                        OnTestRunnerEnd();
+                    };
+        }
+
+        protected virtual void OnTestRunnerStart()
+        {
+            FireEvents(BindingEvent.TestRunStart, null);
+        }
+
+        protected virtual void OnTestRunnerEnd()
+        {
+            FireEvents(BindingEvent.TestRunEnd, null);
+        }
+
+        public void OnFeatureStart(FeatureInfo featureInfo)
+        {
+            ObjectContainer.FeatureContext = new FeatureContext(featureInfo);
+            FireEvents(BindingEvent.FeatureStart, ObjectContainer.FeatureContext.FeatureInfo.Tags);
+        }
+
+        public void OnFeatureEnd()
+        {
+            FireEvents(BindingEvent.FeatureEnd, ObjectContainer.FeatureContext.FeatureInfo.Tags);
+
+            if (Configuration.Current.TraceTimings)
+            {
+                ObjectContainer.FeatureContext.Stopwatch.Stop();
+                var duration = ObjectContainer.FeatureContext.Stopwatch.Elapsed;
+                ObjectContainer.TestTracer.TraceDuration(duration, "Feature: " + ObjectContainer.FeatureContext.FeatureInfo.Title);
+            }
+
+            ObjectContainer.FeatureContext = null;
+        }
+
+        public void OnScenarioStart(ScenarioInfo scenarioInfo)
+        {
+            ObjectContainer.ScenarioContext = new ScenarioContext(scenarioInfo);
+            FireScenarioEvents(BindingEvent.ScenarioStart);
+        }
+
+        public void CollectScenarioErrors()
+        {
+            if (Configuration.Current.TraceTimings)
+            {
+                ObjectContainer.ScenarioContext.Stopwatch.Stop();
+                var duration = ObjectContainer.ScenarioContext.Stopwatch.Elapsed;
+                ObjectContainer.TestTracer.TraceDuration(duration, "Scenario: " + ObjectContainer.ScenarioContext.ScenarioInfo.Title);
+            }
+
+            if (ObjectContainer.ScenarioContext.TestStatus == TestStatus.OK)
+                return;
+
+            if (ObjectContainer.ScenarioContext.TestStatus == TestStatus.StepDefinitionPending)
+            {
+                var pendingSteps = ObjectContainer.ScenarioContext.PendingSteps.Distinct().OrderBy(s => s);
+                ObjectContainer.TestFrameworkIntegration.TestInconclusive(string.Format("{0}{2}  {1}",
+                    GetPendingStepDefinitionError().Message,
+                    string.Join(Environment.NewLine + "  ", pendingSteps.ToArray()),
+                    Environment.NewLine));
+                return;
+            }
+
+            if (ObjectContainer.ScenarioContext.TestStatus == TestStatus.MissingStepDefinition)
+            {
+                var missingSteps = ObjectContainer.ScenarioContext.MissingSteps.Distinct().OrderBy(s => s);
+                string bindingSkeleton =
+                    ObjectContainer.TestTracer.GetBindingClassSkeleton(
+                        string.Join(Environment.NewLine, missingSteps.ToArray()));
+                ObjectContainer.TestFrameworkIntegration.TestInconclusive(string.Format("{0}{2}{1}",
+                    GetMissingStepDefinitionError().Message,
+                    bindingSkeleton,
+                    Environment.NewLine));
+                return;
+            }
+
+            if (ObjectContainer.ScenarioContext.TestError == null)
+                throw new InvalidOperationException("test failed with an unknown error");
+
+            PreserveStackTrace(ObjectContainer.ScenarioContext.TestError);
+            throw ObjectContainer.ScenarioContext.TestError;
+        }
+
+        public void OnScenarioEnd()
+        {
+            HandleBlockSwitch(ScenarioBlock.None);
+
+            FireScenarioEvents(BindingEvent.ScenarioEnd);
+            ObjectContainer.ScenarioContext = null;
+        }
+
+        protected virtual void OnBlockStart(ScenarioBlock block)
+        {
+            if (block == ScenarioBlock.None)
+                return;
+
+            FireScenarioEvents(BindingEvent.BlockStart); 
+        }
+
+        protected virtual void OnBlockEnd(ScenarioBlock block)
+        {
+            if (block == ScenarioBlock.None)
+                return;
+
+            FireScenarioEvents(BindingEvent.BlockEnd);
+        }
+
+        protected virtual void OnStepStart()
+        {
+            FireScenarioEvents(BindingEvent.StepStart); 
+        }
+
+        protected virtual void OnStepEnd()
+        {
+            FireScenarioEvents(BindingEvent.StepEnd);
+        }
+
+        #region Step/event execution
+        private readonly string[] emptyTagList = new string[0];
+
+        private void FireScenarioEvents(BindingEvent bindingEvent)
+        {
+            var tags = (ObjectContainer.FeatureContext.FeatureInfo.Tags ?? emptyTagList).Concat(
+                ObjectContainer.ScenarioContext.ScenarioInfo.Tags ?? emptyTagList);
+            FireEvents(bindingEvent, tags);
+        }
+
+        private void FireEvents(BindingEvent bindingEvent, IEnumerable tags)
+        {
+            foreach (EventBinding eventBinding in bindingRegistry.GetEvents(bindingEvent))
+            {
+                if (IsTagNeeded(eventBinding.Tags, tags))
+                {
+                    InvokeAction(eventBinding.BindingAction, null, eventBinding.MethodInfo);
+                }
+            }
+        }
+
+        private bool IsEmptyTagList(IEnumerable tags)
+        {
+            return tags == null || !tags.Any();
+        }
+
+        private bool IsTagNeeded(IEnumerable filterTags, IEnumerable currentTags)
+        {
+            if (IsEmptyTagList(filterTags))
+                return true;
+
+            if (currentTags == null)
+                return false;
+
+            return filterTags.Intersect(currentTags).Any();
+        }
+
+        private BindingMatch Match(StepBinding stepBinding, StepArgs stepArgs)
+        {
+            Match match = stepBinding.Regex.Match(stepArgs.Text);
+            if (!match.Success)
+                return null;
+
+            object[] extraArgs = null;
+            if (stepArgs.MultilineTextArgument != null || stepArgs.TableArgument != null)
+            {
+                List extraArgsList = new List();
+                if (stepArgs.MultilineTextArgument != null)
+                    extraArgsList.Add(stepArgs.MultilineTextArgument);
+                if (stepArgs.TableArgument != null)
+                    extraArgsList.Add(stepArgs.TableArgument);
+                extraArgs = extraArgsList.ToArray();
+            }
+
+            return new BindingMatch(stepBinding, match, extraArgs, stepArgs);
+        }
+
+        private void ExecuteStep(StepArgs stepArgs)
+        {
+            ObjectContainer.TestTracer.TraceStep(stepArgs, true);
+
+            HandleBlockSwitch(stepArgs.Type.ToScenarioBlock());
+
+            BindingMatch match = null;
+            object[] arguments = null;
+            try
+            {
+                match = GetStepMatch(stepArgs);
+                arguments = GetExecuteArguments(match);
+
+                if (ObjectContainer.ScenarioContext.TestStatus == TestStatus.OK)
+                {
+                    TimeSpan duration = ExecuteStepMatch(match, arguments);
+                    if (Configuration.Current.TraceSuccessfulSteps) 
+                        ObjectContainer.TestTracer.TraceLine("-> done: {0} ({1:F1}s)", ObjectContainer.TestTracer.GetMatchText(match, arguments), duration.TotalSeconds);
+                }
+                else
+                {
+                    //TRACE skipped
+                    ObjectContainer.TestTracer.TraceLine("-> skipped because of previous errors");
+                }
+            }
+            catch(PendingStepException)
+            {
+                Debug.Assert(match != null);
+                Debug.Assert(arguments != null);
+                string matchText = ObjectContainer.TestTracer.GetMatchText(match, arguments);
+                ObjectContainer.TestTracer.TraceLine("-> pending: {0}", matchText);
+                if (ObjectContainer.ScenarioContext.TestStatus < TestStatus.StepDefinitionPending)
+                    ObjectContainer.ScenarioContext.TestStatus = TestStatus.StepDefinitionPending;
+                ObjectContainer.ScenarioContext.PendingSteps.Add(matchText);
+            }
+            catch(MissingStepDefinitionException)
+            {
+                if (ObjectContainer.ScenarioContext.TestStatus < TestStatus.MissingStepDefinition)
+                    ObjectContainer.ScenarioContext.TestStatus = TestStatus.MissingStepDefinition;
+            }
+            catch(BindingException ex)
+            {
+                ObjectContainer.TestTracer.TraceLine("-> binding error: {0}", ex.Message);
+                if (ObjectContainer.ScenarioContext.TestStatus < TestStatus.BindingError)
+                {
+                    ObjectContainer.ScenarioContext.TestStatus = TestStatus.BindingError;
+                    ObjectContainer.ScenarioContext.TestError = ex;
+                }
+            }
+            catch(Exception ex)
+            {
+                ObjectContainer.TestTracer.TraceLine("-> error: {0}", ex.Message);
+                if (ObjectContainer.ScenarioContext.TestStatus < TestStatus.TestError)
+                {
+                    ObjectContainer.ScenarioContext.TestStatus = TestStatus.TestError;
+                    ObjectContainer.ScenarioContext.TestError = ex;
+                }
+                if (Configuration.Current.StopAtFirstError)
+                    throw;
+            }
+        }
+
+        private BindingMatch GetStepMatch(StepArgs stepArgs)
+        {
+            List matches = new List();
+
+            foreach (StepBinding binding in bindingRegistry.Where(b => b.Type == stepArgs.Type))
+            {
+                BindingMatch match = Match(binding, stepArgs);
+                if (match == null)
+                    continue;
+
+                matches.Add(match);
+                if (!Configuration.Current.DetectAmbiguousMatches)
+                    break;
+            }
+
+            if (matches.Count == 0)
+            {
+                ObjectContainer.TestTracer.NoMatchingStepDefinition(stepArgs);
+                ObjectContainer.ScenarioContext.MissingSteps.Add(ObjectContainer.TestTracer.GetStepDefinitionSkeleton(stepArgs));
+                throw GetMissingStepDefinitionError();
+            }
+            if (matches.Count > 1)
+            {
+                throw ObjectContainer.TestTracer.GetAmbiguousMatchError(matches, stepArgs);
+            }
+            return matches[0];
+        }
+
+        internal void PreserveStackTrace(Exception ex)
+        {
+            typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(ex, new object[0]);
+        }
+
+        private TimeSpan ExecuteStepMatch(BindingMatch match, object[] arguments)
+        {
+            OnStepStart();
+            TimeSpan duration = InvokeAction(match.StepBinding.BindingAction, arguments, match.StepBinding.MethodInfo);
+            OnStepEnd();
+
+            return duration;
+        }
+
+        private void HandleBlockSwitch(ScenarioBlock block)
+        {
+            if (ObjectContainer.ScenarioContext.CurrentScenarioBlock != block)
+            {
+                if (ObjectContainer.ScenarioContext.TestStatus == TestStatus.OK)
+                    OnBlockEnd(ObjectContainer.ScenarioContext.CurrentScenarioBlock);
+
+                ObjectContainer.ScenarioContext.CurrentScenarioBlock = block;
+
+                if (ObjectContainer.ScenarioContext.TestStatus == TestStatus.OK)
+                    OnBlockStart(ObjectContainer.ScenarioContext.CurrentScenarioBlock);
+            }
+        }
+
+        private TimeSpan InvokeAction(Delegate action, object[] arguments, MethodInfo methodInfo)
+        {
+            try
+            {
+                System.Diagnostics.Stopwatch stopwatch = new Stopwatch();
+                stopwatch.Start();
+                action.DynamicInvoke(arguments);
+                stopwatch.Stop();
+
+                if (Configuration.Current.TraceTimings && stopwatch.Elapsed >= Configuration.Current.MinTracedDuration)
+                {
+                    ObjectContainer.TestTracer.TraceDuration(stopwatch.Elapsed, methodInfo, arguments);
+                }
+
+                return stopwatch.Elapsed;
+            }
+            catch (ArgumentException ex)
+            {
+                throw ObjectContainer.TestTracer.GetCallError(methodInfo, ex);
+            }
+            catch (TargetInvocationException invEx)
+            {
+                var ex = invEx.InnerException;
+                PreserveStackTrace(ex);
+                throw ex;
+            }
+        }
+
+        private object[] GetExecuteArguments(BindingMatch match)
+        {
+            List arguments = new List();
+
+            var regexArgs = match.Match.Groups.Cast().Skip(1).Select(g => g.Value).ToArray();
+
+            if (regexArgs.Length > match.StepBinding.ParameterTypes.Length)
+                throw ObjectContainer.TestTracer.GetParameterCountError(match, regexArgs.Length + (match.ExtraArguments == null ? 0 : match.ExtraArguments.Length));
+
+            for (int argIndex = 0; argIndex < regexArgs.Length; argIndex++)
+            {
+                object convertedArg = Convert.ChangeType(regexArgs[argIndex], match.StepBinding.ParameterTypes[argIndex]);
+                arguments.Add(convertedArg);
+            }
+
+            if (match.ExtraArguments != null)
+                arguments.AddRange(match.ExtraArguments);
+
+            if (arguments.Count != match.StepBinding.ParameterTypes.Length)
+                throw ObjectContainer.TestTracer.GetParameterCountError(match, arguments.Count);
+
+            return arguments.ToArray();
+        }
+        #endregion
+
+        #region Error handling
+        private MissingStepDefinitionException GetMissingStepDefinitionError()
+        {
+            return new MissingStepDefinitionException();
+        }
+
+        private PendingStepException GetPendingStepDefinitionError()
+        {
+            return new PendingStepException();
+        }
+
+        #endregion
+
+        #region Given-When-Then
+        public void Given(string text, string multilineTextArg, Table tableArg)
+        {
+            ExecuteStep(new StepArgs(BindingType.Given, StepDefinitionKeyword.Given, text, multilineTextArg, tableArg));
+        }
+
+        public void When(string text, string multilineTextArg, Table tableArg)
+        {
+            ExecuteStep(new StepArgs(BindingType.When, StepDefinitionKeyword.When, text, multilineTextArg, tableArg));
+        }
+
+        public void Then(string text, string multilineTextArg, Table tableArg)
+        {
+            ExecuteStep(new StepArgs(BindingType.Then, StepDefinitionKeyword.Then, text, multilineTextArg, tableArg));
+        }
+
+        public void And(string text, string multilineTextArg, Table tableArg)
+        {
+            BindingType bindingType = ObjectContainer.ScenarioContext.CurrentScenarioBlock.ToBindingType();
+            ExecuteStep(new StepArgs(bindingType, StepDefinitionKeyword.And, text, multilineTextArg, tableArg));
+        }
+
+        public void But(string text, string multilineTextArg, Table tableArg)
+        {
+            BindingType bindingType = ObjectContainer.ScenarioContext.CurrentScenarioBlock.ToBindingType();
+            ExecuteStep(new StepArgs(bindingType, StepDefinitionKeyword.But, text, multilineTextArg, tableArg));
+        }
+        #endregion
+
+        public void Pending()
+        {
+            throw GetPendingStepDefinitionError();
+        }
+    }
+}
diff --git a/Runtime/TestTracer.cs b/Runtime/TestTracer.cs
new file mode 100644
index 000000000..06e682c77
--- /dev/null
+++ b/Runtime/TestTracer.cs
@@ -0,0 +1,194 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace TechTalk.SpecFlow
+{
+    public abstract class TestTracer
+    {
+        public void Warning(string text)
+        {
+            TraceLine("Warning: {0}", text);
+        }
+
+        private string GetStepDescription(StepArgs stepArgs)
+        {
+            return string.Format("{0} {1}", stepArgs.Type, stepArgs.Text);
+        }
+
+        private string GetParamString(object arg)
+        {
+            const int maxLength = 20;
+
+            if (arg == null)
+                return "null";
+
+            if (arg is string)
+                return "\"" + arg.ToString().Replace(Environment.NewLine, @"\r\n").TrimEllipse(maxLength) + "\"";
+
+            if (arg is Table)
+                return "";
+
+            return arg.ToString().TrimEllipse(maxLength);
+        }
+
+        internal string GetMatchText(BindingMatch match, object[] arguments)
+        {
+            var methodInfo = match.StepBinding.MethodInfo;
+            return GetMatchText(methodInfo, arguments);
+        }
+
+        internal string GetMatchText(MethodInfo methodInfo, object[] arguments)
+        {
+            string argText = arguments == null ? "" : string.Join(", ", arguments.Select(a => GetParamString(a)).ToArray());
+            return string.Format("{0}.{1}({2})", methodInfo.DeclaringType.Name, methodInfo.Name, argText);
+        }
+
+        internal void TraceStep(StepArgs stepArgs, bool showAdditionalArguments)
+        {
+            StringBuilder result = new StringBuilder();
+            result.Append(stepArgs.StepDefinitionKeyword.ToString());
+            result.Append(" ");
+            result.AppendLine(stepArgs.Text);
+
+            if (showAdditionalArguments)
+            {
+                if (stepArgs.MultilineTextArgument != null)
+                {
+                    result.AppendLine("--- multiline step argument ---".Indent("  "));
+                    result.AppendLine(stepArgs.MultilineTextArgument.Indent("  "));
+                }
+
+                if (stepArgs.TableArgument != null)
+                {
+                    result.AppendLine("--- table step argument ---".Indent("  "));
+                    result.AppendLine(stepArgs.TableArgument.ToString().Indent("  "));
+                }
+            }
+
+            Trace(result.ToString());
+        }
+
+        internal string GetMethodText(MethodInfo methodInfo)
+        {
+            return string.Format("{0}.{1}({2})", methodInfo.DeclaringType.Name, methodInfo.Name,
+                string.Join(", ", methodInfo.GetParameters().Select(pi => pi.ParameterType.Name).ToArray()));
+        }
+
+        internal Exception GetCallError(MethodInfo methodInfo, Exception ex)
+        {
+            return new BindingException(
+                string.Format("Error calling binding method '{0}': {1}",
+                              GetMethodText(methodInfo), ex.Message));
+        }
+
+        internal Exception GetParameterCountError(BindingMatch match, int expectedParameterCount)
+        {
+            return new BindingException(
+                string.Format("Parameter count mismatch! The binding method '{0}' should have {1} parameters",
+                              GetMethodText(match.StepBinding.MethodInfo), expectedParameterCount));
+        }
+
+        internal Exception GetAmbiguousMatchError(IEnumerable matches, StepArgs stepArgs)
+        {
+            string stepDescription = GetStepDescription(stepArgs);
+            return new BindingException(
+                string.Format("Ambiguous step definitions found for step '{0}': {1}",
+                              stepDescription,
+                              string.Join(", ", matches.Select(m => GetMethodText(m.StepBinding.MethodInfo)).ToArray())));
+        }
+
+        private string GetAttributeName(Type attributeType)
+        {
+            return attributeType.Name.Substring(0, attributeType.Name.Length - "Attribute".Length);
+        }
+
+        internal string GetStepDefinitionSkeleton(StepArgs stepArgs)
+        {
+            List extraArgs = new List();
+            if (stepArgs.MultilineTextArgument != null)
+                extraArgs.Add("string multilineText");
+            if (stepArgs.TableArgument != null)
+                extraArgs.Add("Table table");
+
+            StringBuilder result = new StringBuilder();
+            result.AppendFormat(@"[{0}(@""{1}"")]
+public void {0}{2}({3})
+{{
+    ScenarioContext.Current.Pending();
+}}",
+                stepArgs.Type,
+                EscapeRegex(stepArgs.Text),
+                stepArgs.Text.ToIdentifier(),
+                string.Join(", ", extraArgs.ToArray())
+                );
+            result.AppendLine();
+
+            return result.ToString();
+        }
+
+        internal string GetBindingClassSkeleton(string stepDefinitions)
+        {
+            StringBuilder result = new StringBuilder();
+            result.AppendFormat(@"[{0}]
+public class StepDefinitons
+{{
+{1}}}",
+                GetAttributeName(typeof(BindingAttribute)),
+                stepDefinitions.Indent("    "));
+            result.AppendLine();
+
+            return result.ToString();
+        }
+
+        internal void NoMatchingStepDefinition(StepArgs stepArgs)
+        {
+            TraceLine("-> No matching step definition found for the step. Use the following code to create one:");
+            TraceLine(GetBindingClassSkeleton(GetStepDefinitionSkeleton(stepArgs)).Indent("    "));
+        }
+
+        private string EscapeRegex(string text)
+        {
+            return Regex.Escape(text).Replace("\"", "\"\"").Replace("\\ ", " ");
+        }
+
+
+        public void TraceLine(string text)
+        {
+            Trace(text + Environment.NewLine);
+        }
+
+        public void TraceLine(string text, params object[] args)
+        {
+            Trace(text + Environment.NewLine, args);
+        }
+
+        public void Trace(string text, params object[] args)
+        {
+            Trace(string.Format(CultureInfo.InvariantCulture, text, args));
+        }
+        public abstract void Trace(string text);
+
+        public void TraceDuration(TimeSpan elapsed, MethodInfo methodInfo, object[] arguments)
+        {
+            TraceLine("-> duration: {0}: {1:F1}s", GetMatchText(methodInfo, arguments), elapsed.TotalSeconds);
+        }
+
+        public void TraceDuration(TimeSpan elapsed, string text)
+        {
+            TraceLine("-> duration: {0}: {1:F1}s", text, elapsed.TotalSeconds);
+        }
+    }
+
+    public class ConsoleTestTracer : TestTracer
+    {
+        public override void Trace(string text)
+        {
+            Console.Write(text);
+        }
+    }
+}
diff --git a/Runtime/bin/Debug/TechTalk.SpecFlow.dll b/Runtime/bin/Debug/TechTalk.SpecFlow.dll
new file mode 100644
index 000000000..a6a6c5cb3
Binary files /dev/null and b/Runtime/bin/Debug/TechTalk.SpecFlow.dll differ
diff --git a/Runtime/bin/Debug/TechTalk.SpecFlow.pdb b/Runtime/bin/Debug/TechTalk.SpecFlow.pdb
new file mode 100644
index 000000000..045d837dd
Binary files /dev/null and b/Runtime/bin/Debug/TechTalk.SpecFlow.pdb differ
diff --git a/Runtime/bin/Debug/nunit.framework.dll b/Runtime/bin/Debug/nunit.framework.dll
new file mode 100644
index 000000000..1c87f11bd
Binary files /dev/null and b/Runtime/bin/Debug/nunit.framework.dll differ
diff --git a/Runtime/obj/Debug/TechTalk.SpecFlow.csproj.FileListAbsolute.txt b/Runtime/obj/Debug/TechTalk.SpecFlow.csproj.FileListAbsolute.txt
new file mode 100644
index 000000000..cce6aeb3b
--- /dev/null
+++ b/Runtime/obj/Debug/TechTalk.SpecFlow.csproj.FileListAbsolute.txt
@@ -0,0 +1,6 @@
+C:\Users\jba\Code\Research\TechTalk.SpecFlow\Runtime\bin\Debug\TechTalk.SpecFlow.dll
+C:\Users\jba\Code\Research\TechTalk.SpecFlow\Runtime\bin\Debug\TechTalk.SpecFlow.pdb
+C:\Users\jba\Code\Research\TechTalk.SpecFlow\Runtime\bin\Debug\nunit.framework.dll
+C:\Users\jba\Code\Research\TechTalk.SpecFlow\Runtime\obj\Debug\ResolveAssemblyReference.cache
+C:\Users\jba\Code\Research\TechTalk.SpecFlow\Runtime\obj\Debug\TechTalk.SpecFlow.dll
+C:\Users\jba\Code\Research\TechTalk.SpecFlow\Runtime\obj\Debug\TechTalk.SpecFlow.pdb
diff --git a/Runtime/obj/Debug/TechTalk.SpecFlow.dll b/Runtime/obj/Debug/TechTalk.SpecFlow.dll
new file mode 100644
index 000000000..a6a6c5cb3
Binary files /dev/null and b/Runtime/obj/Debug/TechTalk.SpecFlow.dll differ
diff --git a/Runtime/obj/Debug/TechTalk.SpecFlow.pdb b/Runtime/obj/Debug/TechTalk.SpecFlow.pdb
new file mode 100644
index 000000000..045d837dd
Binary files /dev/null and b/Runtime/obj/Debug/TechTalk.SpecFlow.pdb differ
diff --git a/TechTalk.SpecFlow.sln b/TechTalk.SpecFlow.sln
new file mode 100644
index 000000000..f556977c3
--- /dev/null
+++ b/TechTalk.SpecFlow.sln
@@ -0,0 +1,115 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Setup", "Setup", "{DCE0C3C4-5BC6-4A30-86BE-3FEFF4677A01}"
+	ProjectSection(SolutionItems) = preProject
+		changelog.txt = changelog.txt
+	EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{A10B5CD6-38EC-4D7E-9D1C-2EBA8017E437}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{577A0375-1436-446C-802B-3C75C8CEF94F}"
+	ProjectSection(SolutionItems) = preProject
+		changelog.txt = changelog.txt
+		LICENSE.txt = LICENSE.txt
+		VersionInfo.cs = VersionInfo.cs
+	EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TechTalk.SpecFlow.Reporting", "Reporting\TechTalk.SpecFlow.Reporting.csproj", "{FC43509F-E7D3-40C4-B4C3-1E6C9D5530A4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TechTalk.SpecFlow", "Runtime\TechTalk.SpecFlow.csproj", "{413EE28C-4F89-4C6F-BA1E-2CDEE4CD43B4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TechTalk.SpecFlow.Parser", "Parser\TechTalk.SpecFlow.Parser.csproj", "{7CCEF6D6-FC17-422E-9BED-EDD752B6496F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParserTests", "Tests\ParserTests\ParserTests.csproj", "{70376361-0BE1-478D-8EEC-47BD1C768165}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RuntimeTests", "Tests\RuntimeTests\RuntimeTests.csproj", "{F8FACCF0-5497-4C6B-861F-78D72FD9561B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TechTalk.SpecFlow.VsIntegration", "VsIntegration\TechTalk.SpecFlow.VsIntegration.csproj", "{5703CA95-A08A-46AE-AE24-DB6B21FD6F7E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevenvSetupCustomAction", "Installer\DevenvSetupCustomAction\DevenvSetupCustomAction.csproj", "{02F3B86D-0421-4D45-A701-44F3C94CF07D}"
+EndProject
+Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "SpecFlowSetup", "Installer\SpecFlowSetup\SpecFlowSetup.vdproj", "{F6740296-282C-4A0F-941E-A8FD1B1DAC2D}"
+EndProject
+Global
+	GlobalSection(TeamFoundationVersionControl) = preSolution
+		SccNumberOfProjects = 9
+		SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
+		SccTeamFoundationServer = http://ttb-app01.corp.techtalk.at:8080/
+		SccLocalPath0 = .
+		SccProjectUniqueName1 = Reporting\\TechTalk.SpecFlow.Reporting.csproj
+		SccProjectName1 = Reporting
+		SccLocalPath1 = Reporting
+		SccProjectUniqueName2 = Runtime\\TechTalk.SpecFlow.csproj
+		SccProjectName2 = Runtime
+		SccLocalPath2 = Runtime
+		SccProjectUniqueName3 = Parser\\TechTalk.SpecFlow.Parser.csproj
+		SccProjectName3 = Parser
+		SccLocalPath3 = Parser
+		SccProjectUniqueName4 = Tests\\ParserTests\\ParserTests.csproj
+		SccProjectTopLevelParentUniqueName4 = TechTalk.SpecFlow.sln
+		SccProjectName4 = Tests/ParserTests
+		SccLocalPath4 = Tests\\ParserTests
+		SccProjectUniqueName5 = Tests\\RuntimeTests\\RuntimeTests.csproj
+		SccProjectTopLevelParentUniqueName5 = TechTalk.SpecFlow.sln
+		SccProjectName5 = Tests/RuntimeTests
+		SccLocalPath5 = Tests\\RuntimeTests
+		SccProjectUniqueName6 = VsIntegration\\TechTalk.SpecFlow.VsIntegration.csproj
+		SccProjectName6 = VsIntegration
+		SccLocalPath6 = VsIntegration
+		SccProjectUniqueName7 = Installer\\DevenvSetupCustomAction\\DevenvSetupCustomAction.csproj
+		SccProjectTopLevelParentUniqueName7 = TechTalk.SpecFlow.sln
+		SccProjectName7 = Installer/DevenvSetupCustomAction
+		SccLocalPath7 = Installer\\DevenvSetupCustomAction
+		SccProjectUniqueName8 = Installer\\SpecFlowSetup\\SpecFlowSetup.vdproj
+		SccProjectTopLevelParentUniqueName8 = TechTalk.SpecFlow.sln
+		SccProjectName8 = Installer/SpecFlowSetup
+		SccLocalPath8 = Installer\\SpecFlowSetup
+	EndGlobalSection
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{FC43509F-E7D3-40C4-B4C3-1E6C9D5530A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{FC43509F-E7D3-40C4-B4C3-1E6C9D5530A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{FC43509F-E7D3-40C4-B4C3-1E6C9D5530A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{FC43509F-E7D3-40C4-B4C3-1E6C9D5530A4}.Release|Any CPU.Build.0 = Release|Any CPU
+		{413EE28C-4F89-4C6F-BA1E-2CDEE4CD43B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{413EE28C-4F89-4C6F-BA1E-2CDEE4CD43B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{413EE28C-4F89-4C6F-BA1E-2CDEE4CD43B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{413EE28C-4F89-4C6F-BA1E-2CDEE4CD43B4}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7CCEF6D6-FC17-422E-9BED-EDD752B6496F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7CCEF6D6-FC17-422E-9BED-EDD752B6496F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7CCEF6D6-FC17-422E-9BED-EDD752B6496F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7CCEF6D6-FC17-422E-9BED-EDD752B6496F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{70376361-0BE1-478D-8EEC-47BD1C768165}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{70376361-0BE1-478D-8EEC-47BD1C768165}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{70376361-0BE1-478D-8EEC-47BD1C768165}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{70376361-0BE1-478D-8EEC-47BD1C768165}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F8FACCF0-5497-4C6B-861F-78D72FD9561B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F8FACCF0-5497-4C6B-861F-78D72FD9561B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F8FACCF0-5497-4C6B-861F-78D72FD9561B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F8FACCF0-5497-4C6B-861F-78D72FD9561B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5703CA95-A08A-46AE-AE24-DB6B21FD6F7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5703CA95-A08A-46AE-AE24-DB6B21FD6F7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5703CA95-A08A-46AE-AE24-DB6B21FD6F7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5703CA95-A08A-46AE-AE24-DB6B21FD6F7E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{02F3B86D-0421-4D45-A701-44F3C94CF07D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{02F3B86D-0421-4D45-A701-44F3C94CF07D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{02F3B86D-0421-4D45-A701-44F3C94CF07D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{02F3B86D-0421-4D45-A701-44F3C94CF07D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F6740296-282C-4A0F-941E-A8FD1B1DAC2D}.Debug|Any CPU.ActiveCfg = Debug
+		{F6740296-282C-4A0F-941E-A8FD1B1DAC2D}.Release|Any CPU.ActiveCfg = Release
+		{F6740296-282C-4A0F-941E-A8FD1B1DAC2D}.Release|Any CPU.Build.0 = Release
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{02F3B86D-0421-4D45-A701-44F3C94CF07D} = {DCE0C3C4-5BC6-4A30-86BE-3FEFF4677A01}
+		{F6740296-282C-4A0F-941E-A8FD1B1DAC2D} = {DCE0C3C4-5BC6-4A30-86BE-3FEFF4677A01}
+		{70376361-0BE1-478D-8EEC-47BD1C768165} = {A10B5CD6-38EC-4D7E-9D1C-2EBA8017E437}
+		{F8FACCF0-5497-4C6B-861F-78D72FD9561B} = {A10B5CD6-38EC-4D7E-9D1C-2EBA8017E437}
+	EndGlobalSection
+EndGlobal
diff --git a/TechTalk.SpecFlow.vssscc b/TechTalk.SpecFlow.vssscc
new file mode 100644
index 000000000..6cb031bcf
--- /dev/null
+++ b/TechTalk.SpecFlow.vssscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/Tests/ParserTests/ParserTests.csproj b/Tests/ParserTests/ParserTests.csproj
new file mode 100644
index 000000000..9d49ff357
--- /dev/null
+++ b/Tests/ParserTests/ParserTests.csproj
@@ -0,0 +1,125 @@
+
+
+  
+    Debug
+    AnyCPU
+    9.0.30729
+    2.0
+    {70376361-0BE1-478D-8EEC-47BD1C768165}
+    Library
+    Properties
+    ParserTests
+    ParserTests
+    v3.5
+    512
+    SAK
+    SAK
+    SAK
+    SAK
+  
+  
+    true
+    full
+    false
+    bin\Debug\
+    DEBUG;TRACE
+    prompt
+    4
+  
+  
+    pdbonly
+    true
+    bin\Release\
+    TRACE
+    prompt
+    4
+  
+  
+    
+      False
+      ..\..\lib\nunit\nunit.framework.dll
+    
+    
+    
+      3.5
+    
+    
+      3.5
+    
+    
+      3.5
+    
+    
+    
+  
+  
+    
+    
+    
+    
+    
+  
+  
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  
+  
+    
+      {7CCEF6D6-FC17-422E-9BED-EDD752B6496F}
+      TechTalk.SpecFlow.Parser
+    
+  
+  
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  
+  
+  
+
\ No newline at end of file
diff --git a/Tests/ParserTests/ParserTests.csproj.vspscc b/Tests/ParserTests/ParserTests.csproj.vspscc
new file mode 100644
index 000000000..b6d32892f
--- /dev/null
+++ b/Tests/ParserTests/ParserTests.csproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/Tests/ParserTests/Properties/AssemblyInfo.cs b/Tests/ParserTests/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..b4dec3f19
--- /dev/null
+++ b/Tests/ParserTests/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 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("ParserTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ParserTests")]
+[assembly: AssemblyCopyright("Copyright ©  2009")]
+[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)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("d5669f24-3655-4405-85c8-fa74909e84cc")]
+
+// 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/Tests/ParserTests/SuccessfulGenerationTest.cs b/Tests/ParserTests/SuccessfulGenerationTest.cs
new file mode 100644
index 000000000..967a206c8
--- /dev/null
+++ b/Tests/ParserTests/SuccessfulGenerationTest.cs
@@ -0,0 +1,182 @@
+using System;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Xml.Serialization;
+using Microsoft.CSharp;
+using NUnit.Framework;
+using TechTalk.SpecFlow.Parser;
+using TechTalk.SpecFlow.Parser.SyntaxElements;
+
+namespace ParserTests
+{
+    [TestFixture]
+    public class SuccessfulGenerationTest
+    {
+        [Test]
+        public void CanGenerateFromFiles()
+        {
+            foreach (var testFile in TestFileHelper.GetTestFiles())
+            {
+                CanGenerateFromFile(testFile);
+            }
+        }
+
+        [Test]
+        public void CanGenerateSimpleFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "simple.feature"));
+        }
+
+        [Test]
+        public void CanGenerateCommentsFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "comments.feature"));
+        }
+
+        [Test]
+        public void CanGenerateFeatureheaderFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "featureheader.feature"));
+        }
+
+        [Test]
+        public void CanGenerateTagsFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "tags.feature"));
+        }
+
+        [Test]
+        public void CanGeneratebackgroundFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "background.feature"));
+        }
+
+        [Test]
+        public void CanGeneratebackgroundWithTitleFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "background_withtitle.feature"));
+        }
+
+        [Test]
+        public void CanGenerateWhitespacesFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "whitespaces.feature"));
+        }
+
+        [Test]
+        public void CanGenerateGivenWhenThenDuplicationFeatureFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "givenwhenthenduplication.feature"));
+        }
+
+        [Test]
+        public void CanGenerateButFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "but.feature"));
+        }
+
+        [Test]
+        public void CanGenerateMultilinetitleFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "multilinetitle.feature"));
+        }
+
+        [Test]
+        public void CanGenerateMultilineargumentFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "multilineargument.feature"));
+        }
+
+        [Test]
+        public void CanGenerateTableargumentFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "tableargument.feature"));
+        }
+
+        [Test]
+        public void CanGenerateScneriooutlineFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "scenariooutline.feature"));
+        }
+
+        [Test]
+        public void CanGenerateMixedGWTFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanGenerateFromFile(Path.Combine(folder, "mixedgivenwhenthen.feature"));
+        }
+
+
+        [Test, TestCaseSource(typeof(TestFileHelper), "GetTestFiles")]
+        public void CanGenerateFromFile(string fileName)
+        {
+            Console.WriteLine(fileName);
+            SpecFlowLangParser parser = new SpecFlowLangParser();
+            using (var reader = new StreamReader(fileName))
+            {
+                Feature feature = parser.Parse(reader);
+                Assert.IsNotNull(feature);
+
+                string generatedCode = GenerateCodeFromFeature(feature);
+                Assert.IsNotNull(generatedCode);
+
+                // to regenerate the expected result file:
+                //GenerateCodeFromFeature(feature, fileName + ".cs");
+
+                //CompareWithExpectedResult(feature, fileName + ".cs");
+            }
+        }
+
+        private void CompareWithExpectedResult(Feature feature, string expectedResultFileName)
+        {
+            string expected = TestFileHelper.ReadFile(expectedResultFileName);
+            string got = GenerateCodeFromFeature(feature);
+
+            Assert.AreEqual(expected, got);
+        }
+
+        private void GenerateCodeFromFeature(Feature feature, TextWriter writer)
+        {
+            SpecFlowUnitTestConverter converter = new SpecFlowUnitTestConverter();
+            var compileUnit = converter.GenerateUnitTestFixture(feature, "TestClassName", "Target.Namespace");
+
+            CSharpCodeProvider codeProvider = new CSharpCodeProvider();
+            CodeGeneratorOptions options = new CodeGeneratorOptions();
+            codeProvider.GenerateCodeFromCompileUnit(compileUnit, writer, options);
+        }
+
+        private void GenerateCodeFromFeature(Feature feature, string fileName)
+        {
+            using (var writer = new StreamWriter(fileName, false, Encoding.UTF8))
+            {
+                GenerateCodeFromFeature(feature, writer);
+            }
+        }
+
+        private string GenerateCodeFromFeature(Feature feature)
+        {
+            using (var writer = new Utf8StringWriter())
+            {
+                GenerateCodeFromFeature(feature, writer);
+                return writer.ToString();
+            }
+        }
+    }
+}
diff --git a/Tests/ParserTests/SuccessfulParsingTest.cs b/Tests/ParserTests/SuccessfulParsingTest.cs
new file mode 100644
index 000000000..6862711d7
--- /dev/null
+++ b/Tests/ParserTests/SuccessfulParsingTest.cs
@@ -0,0 +1,170 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+using NUnit.Framework;
+using TechTalk.SpecFlow.Parser;
+using TechTalk.SpecFlow.Parser.SyntaxElements;
+
+namespace ParserTests
+{
+    [TestFixture]
+    public class SuccessfulParsingTest
+    {
+        [Test]
+        public void CanParseFiles()
+        {
+            foreach (var testFile in TestFileHelper.GetTestFiles())
+            {
+                CanParseFile(testFile);
+            }
+        }
+
+        [Test]
+        public void CanParseSimpleFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "simple.feature"));
+        }
+
+        [Test]
+        public void CanParseCommentsFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "comments.feature"));
+        }
+
+        [Test]
+        public void CanParseFeatureheaderFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "featureheader.feature"));
+        }
+ 
+        [Test]
+        public void CanParseTagsFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "tags.feature"));
+        }
+
+        [Test]
+        public void CanParsebackgroundFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "background.feature"));
+        }
+
+        [Test]
+        public void CanParsebackgroundWithTitleFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "background_withtitle.feature"));
+        }
+
+        [Test]
+        public void CanParseWhitespacesFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "whitespaces.feature"));
+        }
+
+        [Test]
+        public void CanParseGivenWhenThenDuplicationFeatureFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "givenwhenthenduplication.feature"));
+        }
+
+        [Test]
+        public void CanParseButFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "but.feature"));
+        }
+
+        [Test]
+        public void CanParseMultilinetitleFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "multilinetitle.feature"));
+        }
+
+        [Test]
+        public void CanParseMultilineargumentFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "multilineargument.feature"));
+        }
+
+        [Test]
+        public void CanParseTableargumentFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "tableargument.feature"));
+        }
+
+        [Test]
+        public void CanParseScneriooutlineFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "scenariooutline.feature"));
+        }
+
+        [Test]
+        public void CanParseMixedGWTFeature()
+        {
+            var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles"));
+            CanParseFile(Path.Combine(folder, "mixedgivenwhenthen.feature"));
+        }
+
+        [Test, TestCaseSource(typeof(TestFileHelper), "GetTestFiles")]
+        public void CanParseFile(string fileName)
+        {
+            Console.WriteLine(fileName);
+            SpecFlowLangParser parser = new SpecFlowLangParser();
+            using (var reader = new StreamReader(fileName))
+            {
+                Feature feature = parser.Parse(reader);
+                Assert.IsNotNull(feature);
+
+                // to regenerate the expected result file:
+                //SerializeFeature(feature, fileName + ".xml");
+
+                CompareWithExpectedResult(feature, fileName + ".xml");
+            }
+        }
+
+        private void CompareWithExpectedResult(Feature feature, string expectedResultFileName)
+        {
+            string expected = TestFileHelper.ReadFile(expectedResultFileName);
+            string got = SerializeFeature(feature);
+
+            Assert.AreEqual(expected, got);
+        }
+
+        private void SerializeFeature(Feature feature, TextWriter writer)
+        {
+            XmlSerializer serializer = new XmlSerializer(typeof(Feature));
+            serializer.Serialize(writer, feature);
+        }
+
+        private void SerializeFeature(Feature feature, string fileName)
+        {
+            using (var writer = new StreamWriter(fileName, false, Encoding.UTF8))
+            {
+                SerializeFeature(feature, writer);
+            }
+        }
+
+        private string SerializeFeature(Feature feature)
+        {
+            using (var writer = new Utf8StringWriter())
+            {
+                SerializeFeature(feature, writer);
+                return writer.ToString();
+            }
+        }
+    }
+}
diff --git a/Tests/ParserTests/TestFileHelper.cs b/Tests/ParserTests/TestFileHelper.cs
new file mode 100644
index 000000000..8ec00dabe
--- /dev/null
+++ b/Tests/ParserTests/TestFileHelper.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+
+namespace ParserTests
+{
+    public static class TestFileHelper
+    {
+        public static IEnumerable GetTestFiles()
+        {
+            string sampleFileFolder =
+                Path.GetFullPath(
+                    Path.Combine(
+                        GetProjectLocation(),
+                        "TestFiles"));
+
+            foreach (var file in Directory.GetFiles(sampleFileFolder, "*.feature"))
+            {
+                yield return file;
+            }
+        }
+
+        public static string GetAssemblyPath(Type type)
+        {
+            return new Uri(type.Assembly.CodeBase).AbsolutePath;
+        }
+
+        public static string GetProjectLocation()
+        {
+            string dllLocation = Path.GetDirectoryName(GetAssemblyPath(typeof(TestFileHelper)));
+            return Path.Combine(dllLocation, @"..\..\..\ParserTests");
+        }
+
+        public static string ReadFile(string fileName)
+        {
+            using (var reader = new StreamReader(fileName))
+            {
+                return reader.ReadToEnd();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Tests/ParserTests/TestFiles/background.feature b/Tests/ParserTests/TestFiles/background.feature
new file mode 100644
index 000000000..6f5799872
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/background.feature
@@ -0,0 +1,10 @@
+Feature: a very simple feature
+
+Background:
+	Given some precondition
+	And some other
+
+Scenario: a simple scenario
+Given some precondition
+When I do something
+Then something happens
diff --git a/Tests/ParserTests/TestFiles/background.feature.xml b/Tests/ParserTests/TestFiles/background.feature.xml
new file mode 100644
index 000000000..c8b2e8a18
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/background.feature.xml
@@ -0,0 +1,32 @@
+
+
+  
+    
+    <Steps>
+      <ScenarioStep xsi:type="Given">
+        <Text>some precondition</Text>
+      </ScenarioStep>
+      <ScenarioStep xsi:type="And">
+        <Text>some other</Text>
+      </ScenarioStep>
+    </Steps>
+  </Background>
+  <Scenarios>
+    <Scenario>
+      <Title>a simple scenario
+      
+        
+          some precondition
+        
+        
+          I do something
+        
+        
+          something happens
+        
+      
+    
+  
+  a very simple feature
+  
+
\ No newline at end of file
diff --git a/Tests/ParserTests/TestFiles/background_withtitle.feature b/Tests/ParserTests/TestFiles/background_withtitle.feature
new file mode 100644
index 000000000..9010864e0
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/background_withtitle.feature
@@ -0,0 +1,10 @@
+Feature: a very simple feature
+
+Background: these preconditions should be applied always
+	Given some precondition
+	And some other
+
+Scenario: a simple scenario
+Given some precondition
+When I do something
+Then something happens
diff --git a/Tests/ParserTests/TestFiles/background_withtitle.feature.xml b/Tests/ParserTests/TestFiles/background_withtitle.feature.xml
new file mode 100644
index 000000000..12ed74264
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/background_withtitle.feature.xml
@@ -0,0 +1,32 @@
+
+
+  
+    these preconditions should be applied always
+    
+      
+        some precondition
+      
+      
+        some other
+      
+    
+  
+  
+    
+      a simple scenario
+      
+        
+          some precondition
+        
+        
+          I do something
+        
+        
+          something happens
+        
+      
+    
+  
+  a very simple feature
+  
+
\ No newline at end of file
diff --git a/Tests/ParserTests/TestFiles/but.feature b/Tests/ParserTests/TestFiles/but.feature
new file mode 100644
index 000000000..b617f6e49
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/but.feature
@@ -0,0 +1,8 @@
+Feature: a very simple feature
+
+Scenario: a simple scenario
+Given some precondition
+When I do something
+Then something happens
+But this thing too
+And this as well
diff --git a/Tests/ParserTests/TestFiles/but.feature.xml b/Tests/ParserTests/TestFiles/but.feature.xml
new file mode 100644
index 000000000..f10be26df
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/but.feature.xml
@@ -0,0 +1,27 @@
+
+
+  
+    
+      a simple scenario
+      
+        
+          some precondition
+        
+        
+          I do something
+        
+        
+          something happens
+        
+        
+          this thing too
+        
+        
+          this as well
+        
+      
+    
+  
+  a very simple feature
+  
+
\ No newline at end of file
diff --git a/Tests/ParserTests/TestFiles/comments.feature b/Tests/ParserTests/TestFiles/comments.feature
new file mode 100644
index 000000000..1c745ebcd
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/comments.feature
@@ -0,0 +1,14 @@
+# no tags
+Feature: a very simple feature
+
+# no scenario tags
+   # still nothing
+Scenario: a simple scenario
+Given some precondition		#comment at EOL
+#When commented out
+	#Then commented out
+	
+# empty comment comes:
+# 
+	
+#comment at EOF
diff --git a/Tests/ParserTests/TestFiles/comments.feature.xml b/Tests/ParserTests/TestFiles/comments.feature.xml
new file mode 100644
index 000000000..297660dc4
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/comments.feature.xml
@@ -0,0 +1,15 @@
+
+
+  
+    
+      a simple scenario
+      
+        
+          some precondition
+        
+      
+    
+  
+  a very simple feature
+  
+
\ No newline at end of file
diff --git a/Tests/ParserTests/TestFiles/featureheader.feature b/Tests/ParserTests/TestFiles/featureheader.feature
new file mode 100644
index 000000000..2ff98770f
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/featureheader.feature
@@ -0,0 +1,13 @@
+
+
+Feature: a very simple feature
+
+but it has also a description...
+A long long description
+
+with new lines included
+
+Scenario: a simple scenario
+Given some precondition
+When I do something
+Then something happens
diff --git a/Tests/ParserTests/TestFiles/featureheader.feature.xml b/Tests/ParserTests/TestFiles/featureheader.feature.xml
new file mode 100644
index 000000000..11592ddca
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/featureheader.feature.xml
@@ -0,0 +1,23 @@
+
+
+  
+    
+      a simple scenario
+      
+        
+          some precondition
+        
+        
+          I do something
+        
+        
+          something happens
+        
+      
+    
+  
+  a very simple feature
+  but it has also a description...
+A long long description
+with new lines included
+
\ No newline at end of file
diff --git a/Tests/ParserTests/TestFiles/full.feature b/Tests/ParserTests/TestFiles/full.feature
new file mode 100644
index 000000000..631113c0b
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/full.feature
@@ -0,0 +1,6 @@
+Feature: TODO: a complex test file should come here
+
+Scenario: a simple scenario
+Given some precondition
+When I do something
+Then something happens
diff --git a/Tests/ParserTests/TestFiles/full.feature.xml b/Tests/ParserTests/TestFiles/full.feature.xml
new file mode 100644
index 000000000..4ed42e57f
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/full.feature.xml
@@ -0,0 +1,21 @@
+
+
+  
+    
+      a simple scenario
+      
+        
+          some precondition
+        
+        
+          I do something
+        
+        
+          something happens
+        
+      
+    
+  
+  TODO: a complex test file should come here
+  
+
\ No newline at end of file
diff --git a/Tests/ParserTests/TestFiles/givenwhenthenduplication.feature b/Tests/ParserTests/TestFiles/givenwhenthenduplication.feature
new file mode 100644
index 000000000..dadd3e458
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/givenwhenthenduplication.feature
@@ -0,0 +1,21 @@
+Feature: a very simple feature
+
+Scenario: a simple scenario with duplicated keywords
+Given some precondition
+Given some precondition
+When I do something
+When I do something
+Then something happens
+Then something happens
+
+Scenario: a simple scenario with mixed keywords
+Given some precondition
+Given some precondition
+And some precondition
+When I do something
+And I do something
+When I do something
+Then something happens
+But something happens
+And something happens
+Then something happens
diff --git a/Tests/ParserTests/TestFiles/givenwhenthenduplication.feature.xml b/Tests/ParserTests/TestFiles/givenwhenthenduplication.feature.xml
new file mode 100644
index 000000000..754e0d639
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/givenwhenthenduplication.feature.xml
@@ -0,0 +1,65 @@
+
+
+  
+    
+      a simple scenario with duplicated keywords
+      
+        
+          some precondition
+        
+        
+          some precondition
+        
+        
+          I do something
+        
+        
+          I do something
+        
+        
+          something happens
+        
+        
+          something happens
+        
+      
+    
+    
+      a simple scenario with mixed keywords
+      
+        
+          some precondition
+        
+        
+          some precondition
+        
+        
+          some precondition
+        
+        
+          I do something
+        
+        
+          I do something
+        
+        
+          I do something
+        
+        
+          something happens
+        
+        
+          something happens
+        
+        
+          something happens
+        
+        
+          something happens
+        
+      
+    
+  
+  a very simple feature
+  
+
\ No newline at end of file
diff --git a/Tests/ParserTests/TestFiles/mixedgivenwhenthen.feature b/Tests/ParserTests/TestFiles/mixedgivenwhenthen.feature
new file mode 100644
index 000000000..aabb09c31
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/mixedgivenwhenthen.feature
@@ -0,0 +1,14 @@
+Feature: a very simple feature with mixed given/when/then
+
+Scenario: a simple scenario
+Given some precondition
+And some other given
+When I do something
+And antother when
+Given yet another given
+Then something happens
+But this also happens
+When again a when
+Given a third given part
+And second step of the third given
+
diff --git a/Tests/ParserTests/TestFiles/mixedgivenwhenthen.feature.xml b/Tests/ParserTests/TestFiles/mixedgivenwhenthen.feature.xml
new file mode 100644
index 000000000..c839044be
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/mixedgivenwhenthen.feature.xml
@@ -0,0 +1,42 @@
+
+
+  
+    
+      a simple scenario
+      
+        
+          some precondition
+        
+        
+          some other given
+        
+        
+          I do something
+        
+        
+          antother when
+        
+        
+          yet another given
+        
+        
+          something happens
+        
+        
+          this also happens
+        
+        
+          again a when
+        
+        
+          a third given part
+        
+        
+          second step of the third given
+        
+      
+    
+  
+  a very simple feature with mixed given/when/then
+  
+
\ No newline at end of file
diff --git a/Tests/ParserTests/TestFiles/multilineargument.feature b/Tests/ParserTests/TestFiles/multilineargument.feature
new file mode 100644
index 000000000..c831b091a
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/multilineargument.feature
@@ -0,0 +1,24 @@
+Feature: a very simple feature
+
+Scenario: a scenario with a multiline argument
+ Given there is a multiline text argument
+  """
+  Some Title, Eh?
+  ==============
+  Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,
+  consectetur adipiscing elit.
+  """
+ When there is a multiline text argument
+  """
+  Some Title, Eh?
+  ==============
+  Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,
+  consectetur adipiscing elit.
+  """
+ Then there is a multiline text argument
+  """
+  Some Title, Eh?
+  ==============
+  Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,
+  consectetur adipiscing elit.
+  """
diff --git a/Tests/ParserTests/TestFiles/multilineargument.feature.xml b/Tests/ParserTests/TestFiles/multilineargument.feature.xml
new file mode 100644
index 000000000..07c9e6887
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/multilineargument.feature.xml
@@ -0,0 +1,36 @@
+
+
+  
+    
+      a scenario with a multiline argument
+      
+        
+          there is a multiline text argument
+          Some Title, Eh?
+==============
+Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,
+consectetur adipiscing elit.
+
+        
+        
+          there is a multiline text argument
+          Some Title, Eh?
+==============
+Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,
+consectetur adipiscing elit.
+
+        
+        
+          there is a multiline text argument
+          Some Title, Eh?
+==============
+Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,
+consectetur adipiscing elit.
+
+        
+      
+    
+  
+  a very simple feature
+  
+
\ No newline at end of file
diff --git a/Tests/ParserTests/TestFiles/multilinetitle.feature b/Tests/ParserTests/TestFiles/multilinetitle.feature
new file mode 100644
index 000000000..49acbe1ba
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/multilinetitle.feature
@@ -0,0 +1,11 @@
+Feature: a very simple feature
+
+Background: some background
+  with multi-line title
+  Given some precondition
+
+Scenario: a simple scenario
+	with multi-line title
+Given some precondition
+When I do something
+Then something happens
diff --git a/Tests/ParserTests/TestFiles/multilinetitle.feature.xml b/Tests/ParserTests/TestFiles/multilinetitle.feature.xml
new file mode 100644
index 000000000..e37e5a115
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/multilinetitle.feature.xml
@@ -0,0 +1,31 @@
+
+
+  
+    some background
+  with multi-line title
+    
+      
+        some precondition
+      
+    
+  
+  
+    
+      a simple scenario
+	with multi-line title
+      
+        
+          some precondition
+        
+        
+          I do something
+        
+        
+          something happens
+        
+      
+    
+  
+  a very simple feature
+  
+
\ No newline at end of file
diff --git a/Tests/ParserTests/TestFiles/scenariooutline.feature b/Tests/ParserTests/TestFiles/scenariooutline.feature
new file mode 100644
index 000000000..343f8ebaa
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/scenariooutline.feature
@@ -0,0 +1,23 @@
+Feature: a feature with a scenario outline
+
+Scenario Outline: a simple scenario outline
+Given some  precondition
+	| code	| rate	| date	 		| error code  |
+	| USD	| 1.2	| 	| OK          |
+	| EUR	| 1.2	| 	| OK          |
+When I do something
+Then something  happens
+
+Examples: first examples set
+	| templated	| date1	     | date2      |
+	| one       | 2009/09/14 | 2009/09/14 |
+	| two       | 2009/09/15 | 2009/09/15 |
+
+Scenarios: second example set
+	| templated	| date1	     | date2      |
+	| three     | 2009/09/14 | 2009/09/14 |
+
+#third example set without a name
+Scenarios:
+	| templated	| date1	     | date2      |
+	| four      | 2009/09/14 | 2009/09/14 |
diff --git a/Tests/ParserTests/TestFiles/scenariooutline.feature.xml b/Tests/ParserTests/TestFiles/scenariooutline.feature.xml
new file mode 100644
index 000000000..3b13e2436
--- /dev/null
+++ b/Tests/ParserTests/TestFiles/scenariooutline.feature.xml
@@ -0,0 +1,189 @@
+
+
+  
+    
+      a simple scenario outline
+      
+        
+          some <templated> precondition
+          
+            
+ + + code + + + rate + + + date + + + error code + + +
+ + + + + USD + + + 1.2 + + + <date1> + + + OK + + + + + + + EUR + + + 1.2 + + + <date2> + + + OK + + + + +
+
+ + I do something + + + something <templated> happens + +
+ + + + first examples set +
+
+ + + templated + + + date1 + + + date2 + + +
+ + + + + one + + + 2009/09/14 + + + 2009/09/14 + + + + + + + two + + + 2009/09/15 + + + 2009/09/15 + + + + +
+ + + second example set + +
+ + + templated + + + date1 + + + date2 + + +
+ + + + + three + + + 2009/09/14 + + + 2009/09/14 + + + + +
+
+ + + <Table> + <Header> + <Cells> + <Cell> + <Value>templated</Value> + </Cell> + <Cell> + <Value>date1</Value> + </Cell> + <Cell> + <Value>date2</Value> + </Cell> + </Cells> + </Header> + <Body> + <Row> + <Cells> + <Cell> + <Value>four</Value> + </Cell> + <Cell> + <Value>2009/09/14</Value> + </Cell> + <Cell> + <Value>2009/09/14</Value> + </Cell> + </Cells> + </Row> + </Body> + </Table> + </ExampleSet> + </ExampleSets> + </Examples> + </Scenario> + </Scenarios> + <Title>a feature with a scenario outline + + \ No newline at end of file diff --git a/Tests/ParserTests/TestFiles/simple.feature b/Tests/ParserTests/TestFiles/simple.feature new file mode 100644 index 000000000..84312b9de --- /dev/null +++ b/Tests/ParserTests/TestFiles/simple.feature @@ -0,0 +1,6 @@ +Feature: a very simple feature + +Scenario: a simple scenario +Given some precondition +When I do something +Then something happens diff --git a/Tests/ParserTests/TestFiles/simple.feature.xml b/Tests/ParserTests/TestFiles/simple.feature.xml new file mode 100644 index 000000000..dc639e51c --- /dev/null +++ b/Tests/ParserTests/TestFiles/simple.feature.xml @@ -0,0 +1,21 @@ + + + + + a simple scenario + + + some precondition + + + I do something + + + something happens + + + + + a very simple feature + + \ No newline at end of file diff --git a/Tests/ParserTests/TestFiles/tableargument.feature b/Tests/ParserTests/TestFiles/tableargument.feature new file mode 100644 index 000000000..0ac45d5d3 --- /dev/null +++ b/Tests/ParserTests/TestFiles/tableargument.feature @@ -0,0 +1,15 @@ +Feature: a very simple feature + +Scenario: a scenario with a table argument + Given there is a table argument + | code | rate | date | error code | + | USD | 1.2 | 2009/09/14 | OK | + | EUR | 1.2 | 2009/09/14 | OK | + When there is a table argument + | code | rate | date | error code | + | USD | 1.2 | 2009/09/14 | OK | + | EUR | 1.2 | 2009/09/14 | OK | + Then there is a table argument + | code | rate | date | error code | + | USD | 1.2 | 2009/09/14 | OK | + | EUR | 1.2 | 2009/09/14 | OK | diff --git a/Tests/ParserTests/TestFiles/tableargument.feature.xml b/Tests/ParserTests/TestFiles/tableargument.feature.xml new file mode 100644 index 000000000..bb6bbc95b --- /dev/null +++ b/Tests/ParserTests/TestFiles/tableargument.feature.xml @@ -0,0 +1,177 @@ + + + + + a scenario with a table argument + + + there is a table argument + +
+ + + code + + + rate + + + date + + + error code + + +
+ + + + + USD + + + 1.2 + + + 2009/09/14 + + + OK + + + + + + + EUR + + + 1.2 + + + 2009/09/14 + + + OK + + + + +
+
+ + there is a table argument + +
+ + + code + + + rate + + + date + + + error code + + +
+ + + + + USD + + + 1.2 + + + 2009/09/14 + + + OK + + + + + + + EUR + + + 1.2 + + + 2009/09/14 + + + OK + + + + +
+
+ + there is a table argument + +
+ + + code + + + rate + + + date + + + error code + + +
+ + + + + USD + + + 1.2 + + + 2009/09/14 + + + OK + + + + + + + EUR + + + 1.2 + + + 2009/09/14 + + + OK + + + + +
+
+
+
+
+ a very simple feature + +
\ No newline at end of file diff --git a/Tests/ParserTests/TestFiles/tags.feature b/Tests/ParserTests/TestFiles/tags.feature new file mode 100644 index 000000000..9e436c33b --- /dev/null +++ b/Tests/ParserTests/TestFiles/tags.feature @@ -0,0 +1,17 @@ +@ftag1 @ftag2 + +@ftag3 +Feature: a very simple feature + +@ftag1 @ftag2 + +@ftag3 +Scenario: a simple scenario +Given some precondition +When I do something +Then something happens + +@stag4 Scenario: a simple scenario with tags in the same line +Given some precondition +When I do something +Then something happens diff --git a/Tests/ParserTests/TestFiles/tags.feature.xml b/Tests/ParserTests/TestFiles/tags.feature.xml new file mode 100644 index 000000000..16b1f34ed --- /dev/null +++ b/Tests/ParserTests/TestFiles/tags.feature.xml @@ -0,0 +1,62 @@ + + + + + ftag1 + + + ftag2 + + + ftag3 + + + + + + + ftag1 + + + ftag2 + + + ftag3 + + + a simple scenario + + + some precondition + + + I do something + + + something happens + + + + + + + stag4 + + + a simple scenario with tags in the same line + + + some precondition + + + I do something + + + something happens + + + + + a very simple feature + + \ No newline at end of file diff --git a/Tests/ParserTests/TestFiles/whitespaces.feature b/Tests/ParserTests/TestFiles/whitespaces.feature new file mode 100644 index 000000000..e889744d7 --- /dev/null +++ b/Tests/ParserTests/TestFiles/whitespaces.feature @@ -0,0 +1,7 @@ + + Feature: a very simple feature + + Scenario: a simple scenario + Given some precondition + When I do something + Then something happens diff --git a/Tests/ParserTests/TestFiles/whitespaces.feature.xml b/Tests/ParserTests/TestFiles/whitespaces.feature.xml new file mode 100644 index 000000000..dc639e51c --- /dev/null +++ b/Tests/ParserTests/TestFiles/whitespaces.feature.xml @@ -0,0 +1,21 @@ + + + + + a simple scenario + + + some precondition + + + I do something + + + something happens + + + + + a very simple feature + + \ No newline at end of file diff --git a/Tests/ParserTests/Utf8StringWriter.cs b/Tests/ParserTests/Utf8StringWriter.cs new file mode 100644 index 000000000..02648ab04 --- /dev/null +++ b/Tests/ParserTests/Utf8StringWriter.cs @@ -0,0 +1,13 @@ +using System.IO; +using System.Text; + +namespace ParserTests +{ + internal class Utf8StringWriter : StringWriter + { + public override Encoding Encoding + { + get { return Encoding.UTF8; } + } + } +} \ No newline at end of file diff --git a/Tests/ParserTests/bin/Debug/Antlr3.Runtime.dll b/Tests/ParserTests/bin/Debug/Antlr3.Runtime.dll new file mode 100644 index 000000000..e39f7cf5c Binary files /dev/null and b/Tests/ParserTests/bin/Debug/Antlr3.Runtime.dll differ diff --git a/Tests/ParserTests/bin/Debug/ParserTests.dll b/Tests/ParserTests/bin/Debug/ParserTests.dll new file mode 100644 index 000000000..204e5ac7a Binary files /dev/null and b/Tests/ParserTests/bin/Debug/ParserTests.dll differ diff --git a/Tests/ParserTests/bin/Debug/ParserTests.pdb b/Tests/ParserTests/bin/Debug/ParserTests.pdb new file mode 100644 index 000000000..cbaa1f462 Binary files /dev/null and b/Tests/ParserTests/bin/Debug/ParserTests.pdb differ diff --git a/Tests/ParserTests/bin/Debug/TechTalk.SpecFlow.Parser.dll b/Tests/ParserTests/bin/Debug/TechTalk.SpecFlow.Parser.dll new file mode 100644 index 000000000..c29af2009 Binary files /dev/null and b/Tests/ParserTests/bin/Debug/TechTalk.SpecFlow.Parser.dll differ diff --git a/Tests/ParserTests/bin/Debug/TechTalk.SpecFlow.Parser.pdb b/Tests/ParserTests/bin/Debug/TechTalk.SpecFlow.Parser.pdb new file mode 100644 index 000000000..546fbb9a7 Binary files /dev/null and b/Tests/ParserTests/bin/Debug/TechTalk.SpecFlow.Parser.pdb differ diff --git a/Tests/ParserTests/bin/Debug/nunit.framework.dll b/Tests/ParserTests/bin/Debug/nunit.framework.dll new file mode 100644 index 000000000..1c87f11bd Binary files /dev/null and b/Tests/ParserTests/bin/Debug/nunit.framework.dll differ diff --git a/Tests/ParserTests/obj/Debug/ParserTests.csproj.FileListAbsolute.txt b/Tests/ParserTests/obj/Debug/ParserTests.csproj.FileListAbsolute.txt new file mode 100644 index 000000000..d325b58c6 --- /dev/null +++ b/Tests/ParserTests/obj/Debug/ParserTests.csproj.FileListAbsolute.txt @@ -0,0 +1,9 @@ +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\ParserTests\bin\Debug\ParserTests.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\ParserTests\bin\Debug\ParserTests.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\ParserTests\bin\Debug\nunit.framework.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\ParserTests\bin\Debug\TechTalk.SpecFlow.Parser.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\ParserTests\bin\Debug\Antlr3.Runtime.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\ParserTests\bin\Debug\TechTalk.SpecFlow.Parser.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\ParserTests\obj\Debug\ResolveAssemblyReference.cache +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\ParserTests\obj\Debug\ParserTests.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\ParserTests\obj\Debug\ParserTests.pdb diff --git a/Tests/ParserTests/obj/Debug/ParserTests.dll b/Tests/ParserTests/obj/Debug/ParserTests.dll new file mode 100644 index 000000000..204e5ac7a Binary files /dev/null and b/Tests/ParserTests/obj/Debug/ParserTests.dll differ diff --git a/Tests/ParserTests/obj/Debug/ParserTests.pdb b/Tests/ParserTests/obj/Debug/ParserTests.pdb new file mode 100644 index 000000000..cbaa1f462 Binary files /dev/null and b/Tests/ParserTests/obj/Debug/ParserTests.pdb differ diff --git a/Tests/RuntimeTests/ExecutionTestBase.cs b/Tests/RuntimeTests/ExecutionTestBase.cs new file mode 100644 index 000000000..e7b7f5376 --- /dev/null +++ b/Tests/RuntimeTests/ExecutionTestBase.cs @@ -0,0 +1,178 @@ +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.CSharp; +using NUnit.Framework; +using ParserTests; +using TechTalk.SpecFlow.Parser; +using TechTalk.SpecFlow.Parser.SyntaxElements; + +namespace TechTalk.SpecFlow.RuntimeTests +{ + public abstract class ExecutionTestBase + { + [Test] + public void CanExecuteFromFiles() + { + foreach (var testFile in TestFileHelper.GetTestFiles()) + { + CanGenerateFromFile(testFile); + } + } + + [Test] + public void CanExecuteSimpleFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "simple.feature")); + } + + [Test] + public void CanExecuteCommentsFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "comments.feature")); + } + + [Test] + public void CanExecuteFeatureheaderFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "featureheader.feature")); + } + + [Test] + public void CanExecuteTagsFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "tags.feature")); + } + + [Test] + public void CanExecutebackgroundFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "background.feature")); + } + + [Test] + public void CanExecutebackgroundWithTitleFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "background_withtitle.feature")); + } + + [Test] + public void CanExecuteWhitespacesFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "whitespaces.feature")); + } + + [Test] + public void CanExecuteGivenWhenThenDuplicationFeatureFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "givenwhenthenduplication.feature")); + } + + [Test] + public void CanExecuteButFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "but.feature")); + } + + [Test] + public void CanExecuteMultilinetitleFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "multilinetitle.feature")); + } + + [Test] + public void CanExecuteMultilineargumentFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "multilineargument.feature")); + } + + [Test] + public void CanExecuteTableargumentFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "tableargument.feature")); + } + + [Test] + public void CanExecuteScneriooutlineFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "scenariooutline.feature")); + } + + [Test] + public void CanExecuteMixedGWTFeature() + { + var folder = Path.GetFullPath(Path.Combine(TestFileHelper.GetProjectLocation(), "TestFiles")); + CanGenerateFromFile(Path.Combine(folder, "mixedgivenwhenthen.feature")); + } + + + [Test, TestCaseSource(typeof(TestFileHelper), "GetTestFiles")] + public void CanGenerateFromFile(string fileName) + { + Console.WriteLine(fileName); + SpecFlowLangParser parser = new SpecFlowLangParser(); + using (var reader = new StreamReader(fileName)) + { + Feature feature = parser.Parse(reader); + Assert.IsNotNull(feature); + + ExecuteTests(feature, fileName); + } + } + + private void ExecuteTests(Feature feature, string fileName) + { + object test = CompileAndCreateTest(fileName, feature); + + ExecuteTests(test, feature); + } + + protected abstract void ExecuteTests(object test, Feature feature); + + private object CompileAndCreateTest(string fileName, Feature feature) + { + string className = Path.GetFileNameWithoutExtension(fileName); + const string targetNamespace = "Target.Namespace"; + SpecFlowUnitTestConverter converter = new SpecFlowUnitTestConverter(); + var compileUnit = converter.GenerateUnitTestFixture(feature, className, targetNamespace); + + Dictionary providerOptions = new Dictionary(); + providerOptions["CompilerVersion"] = "v3.5"; + + CSharpCodeProvider codeProvider = new CSharpCodeProvider(providerOptions); + + CompilerParameters compilerParameters = new CompilerParameters(); + compilerParameters.GenerateInMemory = true; + compilerParameters.TempFiles.KeepFiles = true; + + compilerParameters.ReferencedAssemblies.Add( + TestFileHelper.GetAssemblyPath(typeof (TestAttribute))); //NUnit + compilerParameters.ReferencedAssemblies.Add( + TestFileHelper.GetAssemblyPath(typeof (ITestRunner))); //TechTalk.SpecFlow + + var results = codeProvider.CompileAssemblyFromDom(compilerParameters, compileUnit); + + if (results.NativeCompilerReturnValue != 0) + throw new InvalidOperationException("Test cannot be compiled: " + + string.Join(Environment.NewLine, results.Errors.Cast().Select(ce => ce.ToString()).ToArray())); + + Type testType = results.CompiledAssembly.GetType(targetNamespace + "." + className, true); + return Activator.CreateInstance(testType); + } + } +} \ No newline at end of file diff --git a/Tests/RuntimeTests/NUnitTestExecutor.cs b/Tests/RuntimeTests/NUnitTestExecutor.cs new file mode 100644 index 000000000..343c462ec --- /dev/null +++ b/Tests/RuntimeTests/NUnitTestExecutor.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using NUnit.Framework; + +namespace TechTalk.SpecFlow.RuntimeTests +{ + class NUnitTestExecutor + { + public static void ExecuteNUnitTests(object test) + { + // fixture setup + ExecuteWithAttribute(test, typeof(TestFixtureSetUpAttribute)); + + foreach (var testMethod in GetMethodsWithAttribute(test, typeof(TestAttribute))) + { + // test setup + ExecuteWithAttribute(test, typeof(SetUpAttribute)); + + InvokeMethod(test, testMethod); + + // test teardown + ExecuteWithAttribute(test, typeof(TearDownAttribute)); + } + + // fixture teardown + ExecuteWithAttribute(test, typeof(TestFixtureTearDownAttribute)); + } + + private static void InvokeMethod(object test, MethodInfo testMethod) + { + try + { + testMethod.Invoke(test, null); + } + catch (TargetInvocationException invEx) + { + var ex = invEx.InnerException; + PreserveStackTrace(ex); + throw ex; + } + } + + internal static void PreserveStackTrace(Exception ex) + { + typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(ex, new object[0]); + } + + private static void ExecuteWithAttribute(object test, Type attributeType) + { + foreach (var methodInfo in GetMethodsWithAttribute(test, attributeType)) + { + InvokeMethod(test, methodInfo); + } + } + + private static IEnumerable GetMethodsWithAttribute(object test, Type attributeType) + { + foreach (var methodInfo in test.GetType().GetMethods()) + { + var attr = Attribute.GetCustomAttribute(methodInfo, attributeType, true); + if (attr == null) + continue; + + yield return methodInfo; + } + } + } +} diff --git a/Tests/RuntimeTests/Properties/AssemblyInfo.cs b/Tests/RuntimeTests/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..150bb28de --- /dev/null +++ b/Tests/RuntimeTests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 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("RuntimeTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("RuntimeTests")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2009")] +[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)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("62621aba-d6cd-4d41-88eb-e16f63963a07")] + +// 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/Tests/RuntimeTests/RuntimeTests.csproj b/Tests/RuntimeTests/RuntimeTests.csproj new file mode 100644 index 000000000..93a717eda --- /dev/null +++ b/Tests/RuntimeTests/RuntimeTests.csproj @@ -0,0 +1,89 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {F8FACCF0-5497-4C6B-861F-78D72FD9561B} + Library + Properties + TechTalk.SpecFlow.RuntimeTests + TechTalk.SpecFlow.RuntimeTests + v3.5 + 512 + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\lib\nunit\nunit.framework.dll + + + False + ..\..\lib\mocking\Rhino.Mocks.dll + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + + {70376361-0BE1-478D-8EEC-47BD1C768165} + ParserTests + + + {7CCEF6D6-FC17-422E-9BED-EDD752B6496F} + TechTalk.SpecFlow.Parser + + + {413EE28C-4F89-4C6F-BA1E-2CDEE4CD43B4} + TechTalk.SpecFlow + + + + + \ No newline at end of file diff --git a/Tests/RuntimeTests/RuntimeTests.csproj.vspscc b/Tests/RuntimeTests/RuntimeTests.csproj.vspscc new file mode 100644 index 000000000..b6d32892f --- /dev/null +++ b/Tests/RuntimeTests/RuntimeTests.csproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/Tests/RuntimeTests/SuccessfulCompilationTest.cs b/Tests/RuntimeTests/SuccessfulCompilationTest.cs new file mode 100644 index 000000000..b184ed36b --- /dev/null +++ b/Tests/RuntimeTests/SuccessfulCompilationTest.cs @@ -0,0 +1,16 @@ +using System; +using System.Linq; +using NUnit.Framework; +using TechTalk.SpecFlow.Parser.SyntaxElements; + +namespace TechTalk.SpecFlow.RuntimeTests +{ + [TestFixture] + public class SuccessfulCompilationTest : ExecutionTestBase + { + protected override void ExecuteTests(object test, Feature feature) + { + //nop + } + } +} \ No newline at end of file diff --git a/Tests/RuntimeTests/SuccessfulExecutionTest.cs b/Tests/RuntimeTests/SuccessfulExecutionTest.cs new file mode 100644 index 000000000..19c1859bf --- /dev/null +++ b/Tests/RuntimeTests/SuccessfulExecutionTest.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using NUnit.Framework; +using TechTalk.SpecFlow.Parser.SyntaxElements; + +namespace TechTalk.SpecFlow.RuntimeTests +{ + [TestFixture] + public class SuccessfulExecutionTest : ExecutionTestBase + { + [TestFixtureSetUp] + public void FixtureSetup() + { + var testRunner = new TestRunner(); + testRunner.InitializeTestRunner(new Assembly[0]); // no bindings + ObjectContainer.TestRunner = testRunner; + } + + protected override void ExecuteTests(object test, Feature feature) + { + try + { + NUnitTestExecutor.ExecuteNUnitTests(test); + Assert.Fail("incloncusive exception expected"); + } + catch(InconclusiveException) + { + + } + } + } +} diff --git a/Tests/RuntimeTests/ValidateStepAndEventOrdersTest.cs b/Tests/RuntimeTests/ValidateStepAndEventOrdersTest.cs new file mode 100644 index 000000000..0baf91064 --- /dev/null +++ b/Tests/RuntimeTests/ValidateStepAndEventOrdersTest.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using Rhino.Mocks; +using Rhino.Mocks.Interfaces; +using TechTalk.SpecFlow.Parser.SyntaxElements; +using Is=Rhino.Mocks.Constraints.Is; + +namespace TechTalk.SpecFlow.RuntimeTests +{ + [TestFixture] + public class ValidateStepAndEventOrdersTest : ExecutionTestBase + { + protected override void ExecuteTests(object test, Feature feature) + { + MockRepository mockRepository = SetupTests(feature); + + NUnitTestExecutor.ExecuteNUnitTests(test); + + mockRepository.VerifyAll(); + } + + private MockRepository SetupTests(Feature feature) + { + MockRepository mockRepository = new MockRepository(); + + SetupTestRunnerMock(mockRepository, feature); + + mockRepository.ReplayAll(); + return mockRepository; + } + + private void SetupTestRunnerMock(MockRepository mockRepository, Feature feature) + { + var testRunnerMock = mockRepository.StrictMock(); + ObjectContainer.TestRunner = testRunnerMock; + using (mockRepository.Ordered()) + { + testRunnerMock.Expect(tr => tr.OnFeatureStart(null)).IgnoreArguments(); + + using (mockRepository.Unordered()) + { + foreach (var scenario in feature.Scenarios) + { + if (scenario is ScenarioOutline) + { + ScenarioOutline scenarioOutline = (ScenarioOutline) scenario; + foreach (var exampleSet in scenarioOutline.Examples.ExampleSets) + { + foreach (var example in exampleSet.Table.Body) + { + Dictionary paramSubst = new Dictionary(); + for (int i = 0; i < exampleSet.Table.Header.Cells.Length; i++) + { + paramSubst.Add(exampleSet.Table.Header.Cells[i].Value, example.Cells[i].Value); + } + + SetupScenario(testRunnerMock, feature, scenario, paramSubst); + } + } + } + else + { + SetupScenario(testRunnerMock, feature, scenario, null); + } + } + } + + testRunnerMock.Expect(tr => tr.OnFeatureEnd()).IgnoreArguments(); + } + } + + private void SetupScenario(ITestRunner testRunnerMock, Feature feature, Scenario scenario, Dictionary paramSubst) + { + testRunnerMock.Expect(tr => tr.OnScenarioStart(null)).IgnoreArguments(); + + if (feature.Background != null) + foreach (var step in feature.Background.Steps) + SetupStepMock(testRunnerMock, step, paramSubst); + + foreach (var step in scenario.Steps) + SetupStepMock(testRunnerMock, step, paramSubst); + + testRunnerMock.Expect(tr => tr.CollectScenarioErrors()).IgnoreArguments(); + testRunnerMock.Expect(tr => tr.OnScenarioEnd()).IgnoreArguments(); + } + + private bool IsOf(ScenarioStep step) + { + return step is TPhase; + } + + private void SetupStepMock(ITestRunner testRunnerMock, ScenarioStep step, Dictionary paramSubst) + { + if (IsOf(step)) + AddStepConstraints(testRunnerMock.Expect(tr => tr.Given(null, null, null)), step, paramSubst); + else if (IsOf(step)) + AddStepConstraints(testRunnerMock.Expect(tr => tr.When(null, null, null)), step, paramSubst); + else if (IsOf(step)) + AddStepConstraints(testRunnerMock.Expect(tr => tr.Then(null, null, null)), step, paramSubst); + else if (IsOf(step)) + AddStepConstraints(testRunnerMock.Expect(tr => tr.And(null, null, null)), step, paramSubst); + else if (IsOf(step)) + AddStepConstraints(testRunnerMock.Expect(tr => tr.But(null, null, null)), step, paramSubst); + } + + private void AddStepConstraints(IMethodOptions methodOptions, ScenarioStep step, Dictionary paramSubst) + { + methodOptions + .IgnoreArguments() + .Constraints( + Is.Equal(GetReplacedText(step.Text, paramSubst)), + Is.Equal(GetReplacedText(step.MultiLineTextArgument, paramSubst)), + step.TableArg == null ? Is.Equal(null) : Is.NotNull()); + } + + private string GetReplacedText(string text, Dictionary paramSubst) + { + if (text == null || paramSubst == null) + return text; + + foreach (var subst in paramSubst) + { + text = text.Replace("<" + subst.Key + ">", subst.Value); + } + + return text; + } + } +} \ No newline at end of file diff --git a/Tests/RuntimeTests/bin/Debug/Antlr3.Runtime.dll b/Tests/RuntimeTests/bin/Debug/Antlr3.Runtime.dll new file mode 100644 index 000000000..e39f7cf5c Binary files /dev/null and b/Tests/RuntimeTests/bin/Debug/Antlr3.Runtime.dll differ diff --git a/Tests/RuntimeTests/bin/Debug/ParserTests.dll b/Tests/RuntimeTests/bin/Debug/ParserTests.dll new file mode 100644 index 000000000..204e5ac7a Binary files /dev/null and b/Tests/RuntimeTests/bin/Debug/ParserTests.dll differ diff --git a/Tests/RuntimeTests/bin/Debug/ParserTests.pdb b/Tests/RuntimeTests/bin/Debug/ParserTests.pdb new file mode 100644 index 000000000..cbaa1f462 Binary files /dev/null and b/Tests/RuntimeTests/bin/Debug/ParserTests.pdb differ diff --git a/Tests/RuntimeTests/bin/Debug/Rhino.Mocks.dll b/Tests/RuntimeTests/bin/Debug/Rhino.Mocks.dll new file mode 100644 index 000000000..3fc4b2ae4 Binary files /dev/null and b/Tests/RuntimeTests/bin/Debug/Rhino.Mocks.dll differ diff --git a/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.Parser.dll b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.Parser.dll new file mode 100644 index 000000000..c29af2009 Binary files /dev/null and b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.Parser.dll differ diff --git a/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.Parser.pdb b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.Parser.pdb new file mode 100644 index 000000000..546fbb9a7 Binary files /dev/null and b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.Parser.pdb differ diff --git a/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.RuntimeTests.dll b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.RuntimeTests.dll new file mode 100644 index 000000000..422e81726 Binary files /dev/null and b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.RuntimeTests.dll differ diff --git a/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.RuntimeTests.pdb b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.RuntimeTests.pdb new file mode 100644 index 000000000..38479f91e Binary files /dev/null and b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.RuntimeTests.pdb differ diff --git a/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.dll b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.dll new file mode 100644 index 000000000..a6a6c5cb3 Binary files /dev/null and b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.dll differ diff --git a/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.pdb b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.pdb new file mode 100644 index 000000000..045d837dd Binary files /dev/null and b/Tests/RuntimeTests/bin/Debug/TechTalk.SpecFlow.pdb differ diff --git a/Tests/RuntimeTests/bin/Debug/nunit.framework.dll b/Tests/RuntimeTests/bin/Debug/nunit.framework.dll new file mode 100644 index 000000000..1c87f11bd Binary files /dev/null and b/Tests/RuntimeTests/bin/Debug/nunit.framework.dll differ diff --git a/Tests/RuntimeTests/obj/Debug/ResolveAssemblyReference.cache b/Tests/RuntimeTests/obj/Debug/ResolveAssemblyReference.cache new file mode 100644 index 000000000..be06aab64 Binary files /dev/null and b/Tests/RuntimeTests/obj/Debug/ResolveAssemblyReference.cache differ diff --git a/Tests/RuntimeTests/obj/Debug/RuntimeTests.csproj.FileListAbsolute.txt b/Tests/RuntimeTests/obj/Debug/RuntimeTests.csproj.FileListAbsolute.txt new file mode 100644 index 000000000..46287be89 --- /dev/null +++ b/Tests/RuntimeTests/obj/Debug/RuntimeTests.csproj.FileListAbsolute.txt @@ -0,0 +1,14 @@ +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\bin\Debug\TechTalk.SpecFlow.RuntimeTests.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\bin\Debug\TechTalk.SpecFlow.RuntimeTests.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\bin\Debug\nunit.framework.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\bin\Debug\ParserTests.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\bin\Debug\Rhino.Mocks.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\bin\Debug\TechTalk.SpecFlow.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\bin\Debug\TechTalk.SpecFlow.Parser.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\bin\Debug\Antlr3.Runtime.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\bin\Debug\TechTalk.SpecFlow.Parser.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\bin\Debug\ParserTests.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\bin\Debug\TechTalk.SpecFlow.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\obj\Debug\ResolveAssemblyReference.cache +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\obj\Debug\TechTalk.SpecFlow.RuntimeTests.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\Tests\RuntimeTests\obj\Debug\TechTalk.SpecFlow.RuntimeTests.pdb diff --git a/Tests/RuntimeTests/obj/Debug/TechTalk.SpecFlow.RuntimeTests.dll b/Tests/RuntimeTests/obj/Debug/TechTalk.SpecFlow.RuntimeTests.dll new file mode 100644 index 000000000..422e81726 Binary files /dev/null and b/Tests/RuntimeTests/obj/Debug/TechTalk.SpecFlow.RuntimeTests.dll differ diff --git a/Tests/RuntimeTests/obj/Debug/TechTalk.SpecFlow.RuntimeTests.pdb b/Tests/RuntimeTests/obj/Debug/TechTalk.SpecFlow.RuntimeTests.pdb new file mode 100644 index 000000000..38479f91e Binary files /dev/null and b/Tests/RuntimeTests/obj/Debug/TechTalk.SpecFlow.RuntimeTests.pdb differ diff --git a/VersionInfo.cs b/VersionInfo.cs new file mode 100644 index 000000000..aa24d1edc --- /dev/null +++ b/VersionInfo.cs @@ -0,0 +1,6 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyVersion("1.0.2.0")] +[assembly: AssemblyFileVersion("1.0.2.0")] diff --git a/VsIntegration/BaseCodeGenerator.cs b/VsIntegration/BaseCodeGenerator.cs new file mode 100644 index 000000000..5ae036922 --- /dev/null +++ b/VsIntegration/BaseCodeGenerator.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.Shell.Interop; + +namespace TechTalk.SpecFlow.VsIntegration +{ + [System.Runtime.InteropServices.ComVisible(true)] + [Guid("8EC3552F-9C6A-472f-8E64-630C7CAE0179")] + public abstract class BaseCodeGenerator : IVsSingleFileGenerator + { + private IVsGeneratorProgress codeGeneratorProgress; + private string codeFileNameSpace = String.Empty; + private string codeFilePath = String.Empty; + + public string CodeFileNameSpace + { + get { return codeFileNameSpace; } + } + + public string CodeFilePath + { + get { return codeFilePath; } + } + + public IVsGeneratorProgress CodeGeneratorProgress + { + get { return codeGeneratorProgress; } + } + + int IVsSingleFileGenerator.DefaultExtension( + out string pbstrDefaultExtension) + { + pbstrDefaultExtension = GetDefaultExtension(); + return VSConstants.S_OK; + } + + protected virtual string GetMessage(Exception ex) + { + if (ex.InnerException == null) + return ex.Message; + + return ex.Message + " -> " + GetMessage(ex.InnerException); + } + + int IVsSingleFileGenerator.Generate(string wszInputFilePath, + string bstrInputFileContents, + string wszDefaultNamespace, + IntPtr[] rgbOutputFileContents, + out uint pcbOutput, + IVsGeneratorProgress pGenerateProgress) + { + codeFilePath = wszInputFilePath; + codeFileNameSpace = wszDefaultNamespace; + codeGeneratorProgress = pGenerateProgress; + byte[] bytes = null; + try + { + BeforeCodeGenerated(); + bytes = Encoding.UTF8.GetBytes(GenerateCode(bstrInputFileContents)); + AfterCodeGenerated(false); + } + catch(Exception ex) + { + string message = GenerateError(pGenerateProgress, ex); + AfterCodeGenerated(true); + bytes = Encoding.UTF8.GetBytes(message); + } + +// if (bytes == null) +// { +// // --- This signals that GenerateCode() has failed. +// rgbOutputFileContents = null; +// pcbOutput = 0; +// return VSConstants.E_FAIL; +// } + + int outputLength = bytes.Length; + rgbOutputFileContents[0] = Marshal.AllocCoTaskMem(outputLength); + Marshal.Copy(bytes, 0, rgbOutputFileContents[0], outputLength); + pcbOutput = (uint)outputLength; + return VSConstants.S_OK; + } + + protected virtual string GenerateError(IVsGeneratorProgress pGenerateProgress, Exception ex) + { + string message = GetMessage(ex); + pGenerateProgress.GeneratorError(0, 4, message, 0xFFFFFFFF, 0xFFFFFFFF); + return message; + } + + protected virtual void BeforeCodeGenerated() + { + //nop + } + + protected virtual void AfterCodeGenerated(bool error) + { + //nop + } + + protected abstract string GetDefaultExtension(); + protected abstract string GenerateCode(string inputFileContent); + } +} \ No newline at end of file diff --git a/VsIntegration/BaseCodeGeneratorWithSite.cs b/VsIntegration/BaseCodeGeneratorWithSite.cs new file mode 100644 index 000000000..43caca636 --- /dev/null +++ b/VsIntegration/BaseCodeGeneratorWithSite.cs @@ -0,0 +1,206 @@ +using System; +using System.CodeDom.Compiler; +using System.Collections; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using EnvDTE; +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.Designer.Interfaces; +using Microsoft.VisualStudio.Shell.Interop; +using VSOLE = Microsoft.VisualStudio.OLE.Interop; +using Microsoft.VisualStudio.Shell; + +namespace TechTalk.SpecFlow.VsIntegration +{ + [System.Runtime.InteropServices.ComVisible(true)] + [Guid("800FD294-E1AF-4a80-AFF2-FFBCE664D020")] + public abstract class BaseCodeGeneratorWithSite : BaseCodeGenerator, VSOLE.IObjectWithSite + { + private object site = null; + private ServiceProvider serviceProvider = null; + private CodeDomProvider codeDomProvider = null; + + void VSOLE.IObjectWithSite.SetSite(object pUnkSite) + { + site = pUnkSite; + codeDomProvider = null; + serviceProvider = null; + } + + void VSOLE.IObjectWithSite.GetSite(ref Guid riid, out IntPtr ppvSite) + { + if (site == null) + { + throw new COMException("object is not sited", + VSConstants.E_FAIL); + } + IntPtr pUnknownPointer = Marshal.GetIUnknownForObject(site); + IntPtr intPointer = IntPtr.Zero; + Marshal.QueryInterface(pUnknownPointer, ref riid, out intPointer); + if (intPointer == IntPtr.Zero) + { + throw new COMException( + "site does not support requested interface", + VSConstants.E_NOINTERFACE); + } + ppvSite = intPointer; + } + + private ServiceProvider SiteServiceProvider + { + get + { + if (serviceProvider == null) + { + serviceProvider = + new ServiceProvider(site as VSOLE.IServiceProvider); + } + return serviceProvider; + } + } + + protected object GetService(Type serviceType) + { + return SiteServiceProvider.GetService(serviceType); + } + + protected virtual CodeDomProvider GetCodeProvider() + { + if (codeDomProvider == null) + { + IVSMDCodeDomProvider provider = + GetService(typeof(SVSMDCodeDomProvider)) + as IVSMDCodeDomProvider; + if (provider != null) + { + codeDomProvider = provider.CodeDomProvider as CodeDomProvider; + } + else + { + codeDomProvider = CodeDomProvider.CreateProvider("C#"); + } + } + return codeDomProvider; + } + + public static bool Failed(int hr) + { + return (hr < 0); + } + + protected DTE Dte + { + get + { + DTE objectForIUnknown = null; + IVsHierarchy service = this.GetService(typeof(IVsHierarchy)) as IVsHierarchy; + if (service != null) + { + VSOLE.IServiceProvider ppSP = null; + if (!Failed(service.GetSite(out ppSP)) && (ppSP != null)) + { + Guid gUID = typeof(DTE).GUID; + IntPtr zero = IntPtr.Zero; + ErrorHandler.ThrowOnFailure(ppSP.QueryService(ref gUID, ref gUID, out zero)); + if (zero != IntPtr.Zero) + { + objectForIUnknown = Marshal.GetObjectForIUnknown(zero) as DTE; + } + } + } + return objectForIUnknown; + } + } + + protected IVsHierarchy VsHierarchy + { + get + { + return this.GetService(typeof (IVsHierarchy)) as IVsHierarchy; + } + } + + protected IVsErrorList ErrorList + { + get + { + IVsErrorList objectForIUnknown = null; + IVsHierarchy service = this.GetService(typeof(IVsHierarchy)) as IVsHierarchy; + if (service != null) + { + VSOLE.IServiceProvider ppSP = null; + if (!Failed(service.GetSite(out ppSP)) && (ppSP != null)) + { + Guid gUID = typeof(SVsErrorList).GUID; + Guid riid = typeof(IVsErrorList).GUID; + IntPtr zero = IntPtr.Zero; + ErrorHandler.ThrowOnFailure(ppSP.QueryService(ref gUID, ref riid, out zero)); + if (zero != IntPtr.Zero) + { + objectForIUnknown = Marshal.GetObjectForIUnknown(zero) as IVsErrorList; + } + } + } + return objectForIUnknown; + } + } + + /* + private void SetTargetNamespace() + { + if (!string.IsNullOrEmpty(this.CodeFileNameSpace)) + { + TargetNamespace = CodeFileNameSpace; + return; + } + + DTE dte = Dte; + if (dte == null) + return; + IEnumerable activeProjects = dte.ActiveSolutionProjects as IEnumerable; + if (activeProjects == null) + return; + Project project = activeProjects.OfType().First(); + if (project == null) + return; + var defaultNamespace = project.Properties.Item("DefaultNamespace"); + if (defaultNamespace != null && defaultNamespace.Value is string) + { + string targetNamespace = (string)defaultNamespace.Value; + string projectFolder = Path.GetDirectoryName(project.FullName); + string sourceFileFolder = Path.GetDirectoryName(this.CodeFilePath); + if (sourceFileFolder.StartsWith(sourceFileFolder, StringComparison.InvariantCultureIgnoreCase)) + { + string extraFolders = sourceFileFolder.Substring(projectFolder.Length); + if (extraFolders.Length > 0) + { + string[] parts = extraFolders.TrimStart('\\').Split('\\'); + targetNamespace += "." + string.Join(".", + parts.Select(p => p.ToIdentifier()).ToArray()); + } + targetNamespace += extraFolders.Replace("\\", "."); + } + TargetNamespace = targetNamespace; + } + } +*/ + + protected override void AfterCodeGenerated(bool error) + { + base.AfterCodeGenerated(error); + + if (error) + { + IVsErrorList errorList = ErrorList; + if (errorList != null) + { + errorList.BringToFront(); + errorList.ForceShowErrors(); + } + } + } + } +} \ No newline at end of file diff --git a/VsIntegration/CodeGeneratorRegistrationAttribute.cs b/VsIntegration/CodeGeneratorRegistrationAttribute.cs new file mode 100644 index 000000000..db346672f --- /dev/null +++ b/VsIntegration/CodeGeneratorRegistrationAttribute.cs @@ -0,0 +1,158 @@ +/*************************************************************************** + +Copyright (c) Microsoft Corporation. All rights reserved. +This code is licensed under the Visual Studio SDK license terms. +THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. + +***************************************************************************/ + +using System; +using System.Globalization; + +namespace Microsoft.VisualStudio.Shell +{ + /// + /// This attribute adds a custom file generator registry entry for specific file + /// type. + /// For Example: + /// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Generators\ + /// {fae04ec1-301f-11d3-bf4b-00c04f79efbc}\MyGenerator] + /// "CLSID"="{AAAA53CC-3D4F-40a2-BD4D-4F3419755476}" + /// "GeneratesDesignTimeSource" = d'1' + /// + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] + public sealed class CodeGeneratorRegistrationAttribute : RegistrationAttribute + { + private string _contextGuid; + private Type _generatorType; + private Guid _generatorGuid; + private string _generatorName; + private string _generatorRegKeyName; + private bool _generatesDesignTimeSource = false; + private bool _generatesSharedDesignTimeSource = false; + /// + /// Creates a new CodeGeneratorRegistrationAttribute attribute to register a custom + /// code generator for the provided context. + /// + /// The type of Code generator. Type that implements IVsSingleFileGenerator + /// The generator name + /// The context GUID this code generator would appear under. + public CodeGeneratorRegistrationAttribute(Type generatorType, string generatorName, string contextGuid) + { + if (generatorType == null) + throw new ArgumentNullException("generatorType"); + if (generatorName == null) + throw new ArgumentNullException("generatorName"); + if (contextGuid == null) + throw new ArgumentNullException("contextGuid"); + + _contextGuid = contextGuid; + _generatorType = generatorType; + _generatorName = generatorName; + _generatorRegKeyName = generatorType.Name; + _generatorGuid = generatorType.GUID; + } + + /// + /// Get the generator Type + /// + public Type GeneratorType + { + get { return _generatorType; } + } + + /// + /// Get the Guid representing the project type + /// + public string ContextGuid + { + get { return _contextGuid; } + } + + /// + /// Get the Guid representing the generator type + /// + public Guid GeneratorGuid + { + get { return _generatorGuid; } + } + + /// + /// Get or Set the GeneratesDesignTimeSource value + /// + public bool GeneratesDesignTimeSource + { + get { return _generatesDesignTimeSource; } + set { _generatesDesignTimeSource = value; } + } + + /// + /// Get or Set the GeneratesSharedDesignTimeSource value + /// + public bool GeneratesSharedDesignTimeSource + { + get { return _generatesSharedDesignTimeSource; } + set { _generatesSharedDesignTimeSource = value; } + } + + + /// + /// Gets the Generator name + /// + public string GeneratorName + { + get { return _generatorName; } + } + + /// + /// Gets the Generator reg key name under + /// + public string GeneratorRegKeyName + { + get { return _generatorRegKeyName; } + set { _generatorRegKeyName = value; } + } + + /// + /// Property that gets the generator base key name + /// + private string GeneratorRegKey + { + get { return string.Format(CultureInfo.InvariantCulture, @"Generators\{0}\{1}", ContextGuid, GeneratorRegKeyName); } + } + /// + /// Called to register this attribute with the given context. The context + /// contains the location where the registration inforomation should be placed. + /// It also contains other information such as the type being registered and path information. + /// + public override void Register(RegistrationContext context) + { + using (Key childKey = context.CreateKey(GeneratorRegKey)) + { + childKey.SetValue(string.Empty, GeneratorName); + childKey.SetValue("CLSID", GeneratorGuid.ToString("B")); + + if (GeneratesDesignTimeSource) + childKey.SetValue("GeneratesDesignTimeSource", 1); + + if (GeneratesSharedDesignTimeSource) + childKey.SetValue("GeneratesSharedDesignTimeSource", 1); + + } + + } + + /// + /// Unregister this file extension. + /// + /// + public override void Unregister(RegistrationContext context) + { + context.RemoveKey(GeneratorRegKey); + } + } +} diff --git a/VsIntegration/GlobalSuppressions.cs b/VsIntegration/GlobalSuppressions.cs new file mode 100644 index 000000000..746e3daee --- /dev/null +++ b/VsIntegration/GlobalSuppressions.cs @@ -0,0 +1,11 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. Project-level +// suppressions either have no target or are given a specific target +// and scoped to a namespace, type, member, etc. +// +// To add a suppression to this file, right-click the message in the +// Error List, point to "Suppress Message(s)", and click "In Project +// Suppression File". You do not need to add suppressions to this +// file manually. + +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")] diff --git a/VsIntegration/Guids.cs b/VsIntegration/Guids.cs new file mode 100644 index 000000000..88889e065 --- /dev/null +++ b/VsIntegration/Guids.cs @@ -0,0 +1,14 @@ +// Guids.cs +// MUST match guids.h +using System; + +namespace TechTalk.SpecFlow.VsIntegration +{ + static class GuidList + { + public const string guidTechTalk_SpecFlowPkgString = "3a62f4e2-b3d5-4eed-a62d-4acb4936b6c6"; + public const string guidTechTalk_SpecFlowCmdSetString = "d355cecd-5776-4439-a76a-c0d97f8c246a"; + + public static readonly Guid guidTechTalk_SpecFlowCmdSet = new Guid(guidTechTalk_SpecFlowCmdSetString); + }; +} \ No newline at end of file diff --git a/VsIntegration/ItemTemplates/SpecFlowEventDefinition/SpecFlowEventDefinition.vstemplate b/VsIntegration/ItemTemplates/SpecFlowEventDefinition/SpecFlowEventDefinition.vstemplate new file mode 100644 index 000000000..36b80edea --- /dev/null +++ b/VsIntegration/ItemTemplates/SpecFlowEventDefinition/SpecFlowEventDefinition.vstemplate @@ -0,0 +1,13 @@ + + + EventDefinition.cs + SpecFlowEventDefinition + SpecFlow Event Definition + CSharp + 10 + SpecFlowEventDefinitionIcon.ico + + + SpecFlowEventDefinition1.cs + + \ No newline at end of file diff --git a/VsIntegration/ItemTemplates/SpecFlowEventDefinition/SpecFlowEventDefinition1.cs b/VsIntegration/ItemTemplates/SpecFlowEventDefinition/SpecFlowEventDefinition1.cs new file mode 100644 index 000000000..b8264c1f4 --- /dev/null +++ b/VsIntegration/ItemTemplates/SpecFlowEventDefinition/SpecFlowEventDefinition1.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using TechTalk.SpecFlow; + +namespace $rootnamespace$ +{ + [Binding] + public static class $safeitemname$ + { + [BeforeStep] + public static void BeforeStep() + { + //TODO: implement logic that has to run before each scenario step + // For storing and retrieving scenario-specific or feature-specific data, the + // ScenarioContext.Current, FeatureContext.Current + // collections can be used. + // Use the attribute overload to specify tags. If tags are specified, the event + // handler will be executed only if any of the tags are specified for the + // feature or the scenario. + // [BeforeStep("mytag")] + } + + [AfterStep] + public static void AfterStep() + { + //TODO: implement logic that has to run after each scenario step + } + + [BeforeScenarioBlock] + public static void BeforeScenarioBlock() + { + //TODO: implement logic that has to run before each scenario block (given-when-then) + } + + [AfterScenarioBlock] + public static void AfterScenarioBlock() + { + //TODO: implement logic that has to run after each scenario block (given-when-then) + } + + [BeforeScenario] + public static void BeforeScenario() + { + //TODO: implement logic that has to run before executing each scenario + } + + [AfterScenario] + public static void AfterScenario() + { + //TODO: implement logic that has to run after executing each scenario + } + + [BeforeFeature] + public static void BeforeFeature() + { + //TODO: implement logic that has to run before executing each feature + } + + [AfterFeature] + public static void AfterFeature() + { + //TODO: implement logic that has to run after executing each feature + } + + [BeforeTestRun] + public static void BeforeTestRun() + { + //TODO: implement logic that has to run before the entire test run + } + + [AfterTestRun] + public static void AfterTestRun() + { + //TODO: implement logic that has to run after the entire test run + } + } +} diff --git a/VsIntegration/ItemTemplates/SpecFlowEventDefinition/SpecFlowEventDefinitionIcon.ico b/VsIntegration/ItemTemplates/SpecFlowEventDefinition/SpecFlowEventDefinitionIcon.ico new file mode 100644 index 000000000..7ab089ad0 Binary files /dev/null and b/VsIntegration/ItemTemplates/SpecFlowEventDefinition/SpecFlowEventDefinitionIcon.ico differ diff --git a/VsIntegration/ItemTemplates/SpecFlowFeature/SpecFlowFeature.vstemplate b/VsIntegration/ItemTemplates/SpecFlowFeature/SpecFlowFeature.vstemplate new file mode 100644 index 000000000..3517b62d3 --- /dev/null +++ b/VsIntegration/ItemTemplates/SpecFlowFeature/SpecFlowFeature.vstemplate @@ -0,0 +1,13 @@ + + + SpecFlowFeature.feature + SpecFlowFeature + SpecFlow Feature + CSharp + 10 + SpecFlowFeatureIcon.ico + + + SpecFlowFeature1.feature + + \ No newline at end of file diff --git a/VsIntegration/ItemTemplates/SpecFlowFeature/SpecFlowFeature1.feature b/VsIntegration/ItemTemplates/SpecFlowFeature/SpecFlowFeature1.feature new file mode 100644 index 000000000..00293d8dd --- /dev/null +++ b/VsIntegration/ItemTemplates/SpecFlowFeature/SpecFlowFeature1.feature @@ -0,0 +1,11 @@ +Feature: Addition + In order to avoid silly mistakes + As a meth idiot + I want to be told the sum of two numbers + +@mytag +Scenario: Add two numbers + Given I have entered 50 into the calculator + And I have entered 70 into the calculator + When I press add + Then the result should be 120 on the screen diff --git a/VsIntegration/ItemTemplates/SpecFlowFeature/SpecFlowFeatureIcon.ico b/VsIntegration/ItemTemplates/SpecFlowFeature/SpecFlowFeatureIcon.ico new file mode 100644 index 000000000..7ab089ad0 Binary files /dev/null and b/VsIntegration/ItemTemplates/SpecFlowFeature/SpecFlowFeatureIcon.ico differ diff --git a/VsIntegration/ItemTemplates/SpecFlowStepDefinition/SpecFlowStepDefinition.vstemplate b/VsIntegration/ItemTemplates/SpecFlowStepDefinition/SpecFlowStepDefinition.vstemplate new file mode 100644 index 000000000..5444406f6 --- /dev/null +++ b/VsIntegration/ItemTemplates/SpecFlowStepDefinition/SpecFlowStepDefinition.vstemplate @@ -0,0 +1,13 @@ + + + StepDefinition.cs + SpecFlowStepDefinition + SpecFlow Step Definition + CSharp + 10 + SpecFlowStepDefinitionIcon.ico + + + SpecFlowStepDefinition1.cs + + \ No newline at end of file diff --git a/VsIntegration/ItemTemplates/SpecFlowStepDefinition/SpecFlowStepDefinition1.cs b/VsIntegration/ItemTemplates/SpecFlowStepDefinition/SpecFlowStepDefinition1.cs new file mode 100644 index 000000000..579527bb9 --- /dev/null +++ b/VsIntegration/ItemTemplates/SpecFlowStepDefinition/SpecFlowStepDefinition1.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using TechTalk.SpecFlow; + +namespace $rootnamespace$ +{ + [Binding] + public class $safeitemname$ + { + [Given("I have entered (.*) into the calculator")] + public void GivenIHaveEnteredSomethingIntoTheCalculator(int number) + { + //TODO: implement arrange (recondition) logic + // For storing and retrieving scenario-specific data, + // the instance fields of the class or the + // ScenarioContext.Current + // collection can be used. + // To use the multiline text or the table argument of the scenario, + // additional string/Table parameters can be defined on the step definition + // method. + } + + [When("I press add")] + public void WhenIPressAdd() + { + //TODO: implement act (action) logic + } + + [Then("the result should be (.*) on the screen")] + public void ThenTheResultShouldBe(int result) + { + //TODO: implement assert (verification) logic + } + } +} diff --git a/VsIntegration/ItemTemplates/SpecFlowStepDefinition/SpecFlowStepDefinitionIcon.ico b/VsIntegration/ItemTemplates/SpecFlowStepDefinition/SpecFlowStepDefinitionIcon.ico new file mode 100644 index 000000000..7ab089ad0 Binary files /dev/null and b/VsIntegration/ItemTemplates/SpecFlowStepDefinition/SpecFlowStepDefinitionIcon.ico differ diff --git a/VsIntegration/Key.snk b/VsIntegration/Key.snk new file mode 100644 index 000000000..ae1326e9b Binary files /dev/null and b/VsIntegration/Key.snk differ diff --git a/VsIntegration/Properties/AssemblyInfo.cs b/VsIntegration/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..a4b9387a3 --- /dev/null +++ b/VsIntegration/Properties/AssemblyInfo.cs @@ -0,0 +1,21 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 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("SpecFlow")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("TechTalk")] +[assembly: AssemblyProduct("SpecFlow")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] +[assembly: CLSCompliant(false)] +[assembly: NeutralResourcesLanguage("en-US")] + diff --git a/VsIntegration/Resources.Designer.cs b/VsIntegration/Resources.Designer.cs new file mode 100644 index 000000000..716e6f0ae --- /dev/null +++ b/VsIntegration/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.4918 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace TechTalk.SpecFlow.VsIntegration { + using System; + + + /// + /// 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", "2.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 (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TechTalk.SpecFlow.VsIntegration.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/VsIntegration/Resources.resx b/VsIntegration/Resources.resx new file mode 100644 index 000000000..7ad9af7ae --- /dev/null +++ b/VsIntegration/Resources.resx @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/VsIntegration/Resources/Package.ico b/VsIntegration/Resources/Package.ico new file mode 100644 index 000000000..ea3b23fe8 Binary files /dev/null and b/VsIntegration/Resources/Package.ico differ diff --git a/VsIntegration/SingleFileGeneratorSupportRegistrationAttribute.cs b/VsIntegration/SingleFileGeneratorSupportRegistrationAttribute.cs new file mode 100644 index 000000000..dcf40da4b --- /dev/null +++ b/VsIntegration/SingleFileGeneratorSupportRegistrationAttribute.cs @@ -0,0 +1,83 @@ +/*************************************************************************** + +Copyright (c) Microsoft Corporation. All rights reserved. +This code is licensed under the Visual Studio SDK license terms. +THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. + +***************************************************************************/ + +using System; +using System.Globalization; + +namespace Microsoft.VisualStudio.Shell +{ + /// + /// This attribute adds a custom file generator registry entry for specific file + /// type. + /// For Example: + /// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Generators\ + /// [proj_fac_guid] + /// + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] + public sealed class SingleFileGeneratorSupportRegistrationAttribute : RegistrationAttribute + { + private Guid _prjFacGuid; + /// + /// Creates a new SingleFileGeneratorSupportRegistrationAttribute attribute to register a custom + /// code generator for the provided context. + /// + /// The type of Code generator. Type that implements IVsSingleFileGenerator + /// The generator name + /// The context GUID this code generator would appear under. + public SingleFileGeneratorSupportRegistrationAttribute(Type prjFactoryType) + { + if (prjFactoryType == null) + throw new ArgumentNullException("prjFactoryType"); + + _prjFacGuid = prjFactoryType.GUID; + } + + + /// + /// Get the Guid representing the generator type + /// + public Guid ProjectFactoryGuid + { + get { return _prjFacGuid; } + } + + /// + /// Property that gets the generator base key name + /// + private string GeneratorRegKey + { + get { return string.Format(CultureInfo.InvariantCulture, @"Generators\{0}", ProjectFactoryGuid.ToString("B")); } + } + /// + /// Called to register this attribute with the given context. The context + /// contains the location where the registration inforomation should be placed. + /// It also contains other information such as the type being registered and path information. + /// + public override void Register(RegistrationContext context) + { + using (Key childKey = context.CreateKey(GeneratorRegKey)) + { + childKey.SetValue(string.Empty, string.Empty); + } + + } + + /// + /// Unregister this file extension. + /// + /// + public override void Unregister(RegistrationContext context) + { + context.RemoveKey(GeneratorRegKey); + } + } +} diff --git a/VsIntegration/SpecFlowPackage.cs b/VsIntegration/SpecFlowPackage.cs new file mode 100644 index 000000000..e23c86296 --- /dev/null +++ b/VsIntegration/SpecFlowPackage.cs @@ -0,0 +1,77 @@ +/*// VsPkg.cs : Implementation of TechTalk_SpecFlow +// + +using System; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.InteropServices; +using System.ComponentModel.Design; +using Microsoft.Win32; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.OLE.Interop; +using Microsoft.VisualStudio.Shell; +using TechTalk.SpecFlow.VsIntegration; + +namespace TechTalk.SpecFlow.VsIntegration +{ + /// + /// This is the class that implements the package exposed by this assembly. + /// + /// The minimum requirement for a class to be considered a valid package for Visual Studio + /// is to implement the IVsPackage interface and register itself with the shell. + /// This package uses the helper classes defined inside the Managed Package Framework (MPF) + /// to do it: it derives from the Package class that provides the implementation of the + /// IVsPackage interface and uses the registration attributes defined in the framework to + /// register itself and its components with the shell. + /// + // This attribute tells the registration utility (regpkg.exe) that this class needs + // to be registered as package. + [PackageRegistration(UseManagedResourcesOnly = true)] + // A Visual Studio component can be registered under different regitry roots; for instance + // when you debug your package you want to register it in the experimental hive. This + // attribute specifies the registry root to use if no one is provided to regpkg.exe with + // the /root switch. + [DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0")] + // This attribute is used to register the informations needed to show the this package + // in the Help/About dialog of Visual Studio. + [InstalledProductRegistration(false, "#110", "#112", "1.0", IconResourceID = 400)] + // In order be loaded inside Visual Studio in a machine that has not the VS SDK installed, + // package needs to have a valid load key (it can be requested at + // http://msdn.microsoft.com/vstudio/extend/). This attributes tells the shell that this + // package has a load key embedded in its resources. + [ProvideLoadKey("Standard", "1.0", "SpecFlow", "TechTalk", 1)] + [Guid(GuidList.guidTechTalk_SpecFlowPkgString)] + public sealed class SpecFlowPackage : Package + { + /// + /// Default constructor of the package. + /// Inside this method you can place any initialization code that does not require + /// any Visual Studio service because at this point the package object is created but + /// not sited yet inside Visual Studio environment. The place to do all the other + /// initialization is the Initialize method. + /// + public SpecFlowPackage() + { + Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString())); + } + + + + ///////////////////////////////////////////////////////////////////////////// + // Overriden Package Implementation + #region Package Members + + /// + /// Initialization of the package; this method is called right after the package is sited, so this is the place + /// where you can put all the initilaization code that rely on services provided by VisualStudio. + /// + protected override void Initialize() + { + Trace.WriteLine (string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString())); + base.Initialize(); + + } + #endregion + + } +}*/ \ No newline at end of file diff --git a/VsIntegration/SpecFlowSingleFileGenerator.cs b/VsIntegration/SpecFlowSingleFileGenerator.cs new file mode 100644 index 000000000..238d4dbcd --- /dev/null +++ b/VsIntegration/SpecFlowSingleFileGenerator.cs @@ -0,0 +1,95 @@ +using System; +using System.CodeDom; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using System.Xml; +using Microsoft.VisualStudio.Designer.Interfaces; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.TextTemplating.VSHost; +using TechTalk.SpecFlow.Parser; +using VSLangProj80; + +namespace TechTalk.SpecFlow.VsIntegration +{ + [System.Runtime.InteropServices.ComVisible(true)] + [Guid("3C9CF10A-A9AB-4899-A0FB-4B3BE4A36C15")] + [CodeGeneratorRegistration(typeof(SpecFlowSingleFileGenerator), + "C# XML Class Generator", vsContextGuids.vsContextGuidVCSProject, + GeneratesDesignTimeSource = true)] + [CodeGeneratorRegistration(typeof(SpecFlowSingleFileGenerator), + "VB XML Class Generator", vsContextGuids.vsContextGuidVBProject, + GeneratesDesignTimeSource = true)] + [CodeGeneratorRegistration(typeof(SpecFlowSingleFileGenerator), + "J# XML Class Generator", vsContextGuids.vsContextGuidVJSProject, + GeneratesDesignTimeSource = true)] + [ProvideObject(typeof(SpecFlowSingleFileGenerator))] + public class SpecFlowSingleFileGenerator : BaseCodeGeneratorWithSite + { + protected override string GetDefaultExtension() + { + return ".feature.cs"; + } + + protected override string GenerateCode(string inputFileContent) + { + CodeDomProvider provider = GetCodeProvider(); + + CodeCompileUnit compileUnit = SpecFlowTestGenerator.GenerateTestFile(inputFileContent, CodeFilePath, CodeFileNameSpace); + using (StringWriter writer = new StringWriter(new StringBuilder())) + { + CodeGeneratorOptions options = new CodeGeneratorOptions(); + options.BracingStyle = "C"; + provider.GenerateCodeFromCompileUnit(compileUnit, writer, + options); + writer.Flush(); + + return writer.ToString(); + } + } + + protected override string GenerateError(Microsoft.VisualStudio.Shell.Interop.IVsGeneratorProgress pGenerateProgress, Exception ex) + { + if (ex is SpecFlowParserException) + { + SpecFlowParserException sfpex = (SpecFlowParserException) ex; + if (sfpex.DetailedErrors == null) + return base.GenerateError(pGenerateProgress, ex); + + Regex coordRe = new Regex(@"^\((?\d+),(?\d+)\)"); + var match = coordRe.Match(sfpex.DetailedErrors[0]); + if (!match.Success) + return base.GenerateError(pGenerateProgress, ex); + + string message = GetMessage(ex); + pGenerateProgress.GeneratorError(0, 4, message, + uint.Parse(match.Groups["line"].Value) - 1, + uint.Parse(match.Groups["col"].Value)); + return message; + } + + return base.GenerateError(pGenerateProgress, ex); + } + +// protected override string GetMessage(Exception ex) +// { +// if (ex is SpecFlowParserException) +// { +// SpecFlowParserException sfpex = (SpecFlowParserException)ex; +// if (sfpex.DetailedErrors == null) +// return base.GetMessage(ex); +// +// return string.Join( +// Environment.NewLine, +// sfpex.DetailedErrors.Select(e => CodeFilePath + e).ToArray()); +// } +// return base.GetMessage(ex); +// } + } +} \ No newline at end of file diff --git a/VsIntegration/SpecFlowTestGenerator.cs b/VsIntegration/SpecFlowTestGenerator.cs new file mode 100644 index 000000000..677ca759e --- /dev/null +++ b/VsIntegration/SpecFlowTestGenerator.cs @@ -0,0 +1,25 @@ +using System; +using System.CodeDom; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using TechTalk.SpecFlow.Parser; +using TechTalk.SpecFlow.Parser.SyntaxElements; + +namespace TechTalk.SpecFlow.VsIntegration +{ + public class SpecFlowTestGenerator + { + static public CodeCompileUnit GenerateTestFile(string content, string featureFileName, string targetNamespace) + { + SpecFlowLangParser parser = new SpecFlowLangParser(); + Feature feature = parser.Parse(new StringReader(content)); + + SpecFlowUnitTestConverter testConverter = new SpecFlowUnitTestConverter(); + CodeCompileUnit codeCompileUnit = testConverter.GenerateUnitTestFixture(feature, null, targetNamespace); + + return codeCompileUnit; + } + } +} diff --git a/VsIntegration/TechTalk.SpecFlow.VsIntegration.csproj b/VsIntegration/TechTalk.SpecFlow.VsIntegration.csproj new file mode 100644 index 000000000..9a871fc8e --- /dev/null +++ b/VsIntegration/TechTalk.SpecFlow.VsIntegration.csproj @@ -0,0 +1,135 @@ + + + Debug + AnyCPU + 9.0.30729 + 2.0 + Library + Properties + TechTalk.SpecFlow.VsIntegration + TechTalk.SpecFlow.VsIntegration + False + Key.snk + v3.5 + {5703CA95-A08A-46AE-AE24-DB6B21FD6F7E} + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + + + + False + C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies\EnvDTE.dll + + + + + + + + + + + + + 3.5 + + + + + + + + + + + + StringExtensions.cs + + + VersionInfo.cs + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + true + + + + + + + + + + + + + + {7CCEF6D6-FC17-422E-9BED-EDD752B6496F} + TechTalk.SpecFlow.Parser + + + + + + + + true + true + + + + + \ No newline at end of file diff --git a/VsIntegration/TechTalk.SpecFlow.VsIntegration.csproj.vspscc b/VsIntegration/TechTalk.SpecFlow.VsIntegration.csproj.vspscc new file mode 100644 index 000000000..b6d32892f --- /dev/null +++ b/VsIntegration/TechTalk.SpecFlow.VsIntegration.csproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/VsIntegration/VSPackage.resx b/VsIntegration/VSPackage.resx new file mode 100644 index 000000000..bfd3895f7 --- /dev/null +++ b/VsIntegration/VSPackage.resx @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + SpecFlow + + + SpecFlow by TechTalk + + + Resources\Package.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/VsIntegration/bin/Debug/Antlr3.Runtime.dll b/VsIntegration/bin/Debug/Antlr3.Runtime.dll new file mode 100644 index 000000000..e39f7cf5c Binary files /dev/null and b/VsIntegration/bin/Debug/Antlr3.Runtime.dll differ diff --git a/VsIntegration/bin/Debug/TechTalk.SpecFlow.Parser.dll b/VsIntegration/bin/Debug/TechTalk.SpecFlow.Parser.dll new file mode 100644 index 000000000..c29af2009 Binary files /dev/null and b/VsIntegration/bin/Debug/TechTalk.SpecFlow.Parser.dll differ diff --git a/VsIntegration/bin/Debug/TechTalk.SpecFlow.Parser.pdb b/VsIntegration/bin/Debug/TechTalk.SpecFlow.Parser.pdb new file mode 100644 index 000000000..546fbb9a7 Binary files /dev/null and b/VsIntegration/bin/Debug/TechTalk.SpecFlow.Parser.pdb differ diff --git a/VsIntegration/bin/Debug/TechTalk.SpecFlow.VsIntegration.dll b/VsIntegration/bin/Debug/TechTalk.SpecFlow.VsIntegration.dll new file mode 100644 index 000000000..4420a2632 Binary files /dev/null and b/VsIntegration/bin/Debug/TechTalk.SpecFlow.VsIntegration.dll differ diff --git a/VsIntegration/bin/Debug/TechTalk.SpecFlow.VsIntegration.pdb b/VsIntegration/bin/Debug/TechTalk.SpecFlow.VsIntegration.pdb new file mode 100644 index 000000000..50d588a01 Binary files /dev/null and b/VsIntegration/bin/Debug/TechTalk.SpecFlow.VsIntegration.pdb differ diff --git a/VsIntegration/bin/Debug/TechTalk.SpecFlow.VsIntegration.pkgdef b/VsIntegration/bin/Debug/TechTalk.SpecFlow.VsIntegration.pkgdef new file mode 100644 index 000000000..ea1d9d02a --- /dev/null +++ b/VsIntegration/bin/Debug/TechTalk.SpecFlow.VsIntegration.pkgdef @@ -0,0 +1,21 @@ +Windows Registry Editor Version 5.00 + +[$RootKey$\Generators\{164B10B9-B200-11D0-8C61-00A0C91E29D5}\SpecFlowSingleFileGenerator] +@="VB XML Class Generator" +"CLSID"="{3c9cf10a-a9ab-4899-a0fb-4b3be4a36c15}" +"GeneratesDesignTimeSource"=dword:00000001 +[$RootKey$\Generators\{E6FDF8B0-F3D1-11D4-8576-0002A516ECE8}\SpecFlowSingleFileGenerator] +@="J# XML Class Generator" +"CLSID"="{3c9cf10a-a9ab-4899-a0fb-4b3be4a36c15}" +"GeneratesDesignTimeSource"=dword:00000001 +[$RootKey$\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\SpecFlowSingleFileGenerator] +@="C# XML Class Generator" +"CLSID"="{3c9cf10a-a9ab-4899-a0fb-4b3be4a36c15}" +"GeneratesDesignTimeSource"=dword:00000001 +[$RootKey$\CLSID\{3c9cf10a-a9ab-4899-a0fb-4b3be4a36c15}] +@="TechTalk.SpecFlow.VsIntegration.SpecFlowSingleFileGenerator" +"InprocServer32"="%windir%\\SYSTEM32\\MSCOREE.DLL" +"Class"="TechTalk.SpecFlow.VsIntegration.SpecFlowSingleFileGenerator" +"Assembly"="TechTalk.SpecFlow.VsIntegration, Version=1.0.2.0, Culture=neutral, PublicKeyToken=null" +"ThreadingModel"="Both" + diff --git a/VsIntegration/obj/Debug/DevEnvSetup.cache b/VsIntegration/obj/Debug/DevEnvSetup.cache new file mode 100644 index 000000000..88714dac6 --- /dev/null +++ b/VsIntegration/obj/Debug/DevEnvSetup.cache @@ -0,0 +1 @@ +DevEnv /Setup succeeded. diff --git a/VsIntegration/obj/Debug/RegPkg.cache b/VsIntegration/obj/Debug/RegPkg.cache new file mode 100644 index 000000000..1a16c2a92 --- /dev/null +++ b/VsIntegration/obj/Debug/RegPkg.cache @@ -0,0 +1 @@ +RegPkg succeeded. diff --git a/VsIntegration/obj/Debug/ResolveAssemblyReference.cache b/VsIntegration/obj/Debug/ResolveAssemblyReference.cache new file mode 100644 index 000000000..b0f3ee21e Binary files /dev/null and b/VsIntegration/obj/Debug/ResolveAssemblyReference.cache differ diff --git a/VsIntegration/obj/Debug/SpecFlowEventDefinition.zip b/VsIntegration/obj/Debug/SpecFlowEventDefinition.zip new file mode 100644 index 000000000..50b034c63 Binary files /dev/null and b/VsIntegration/obj/Debug/SpecFlowEventDefinition.zip differ diff --git a/VsIntegration/obj/Debug/SpecFlowFeature.zip b/VsIntegration/obj/Debug/SpecFlowFeature.zip new file mode 100644 index 000000000..9bf6cd854 Binary files /dev/null and b/VsIntegration/obj/Debug/SpecFlowFeature.zip differ diff --git a/VsIntegration/obj/Debug/SpecFlowStepDefinition.zip b/VsIntegration/obj/Debug/SpecFlowStepDefinition.zip new file mode 100644 index 000000000..4b4fac199 Binary files /dev/null and b/VsIntegration/obj/Debug/SpecFlowStepDefinition.zip differ diff --git a/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.Resources.resources b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.Resources.resources new file mode 100644 index 000000000..06c24d06c Binary files /dev/null and b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.Resources.resources differ diff --git a/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.VSPackage.resources b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.VSPackage.resources new file mode 100644 index 000000000..7655f0dc4 Binary files /dev/null and b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.VSPackage.resources differ diff --git a/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.csproj.FileListAbsolute.txt b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.csproj.FileListAbsolute.txt new file mode 100644 index 000000000..e38dbba70 --- /dev/null +++ b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.csproj.FileListAbsolute.txt @@ -0,0 +1,15 @@ +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\bin\Debug\TechTalk.SpecFlow.VsIntegration.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\bin\Debug\TechTalk.SpecFlow.VsIntegration.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\bin\Debug\TechTalk.SpecFlow.VsIntegration.pkgdef +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\bin\Debug\TechTalk.SpecFlow.Parser.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\bin\Debug\Antlr3.Runtime.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\bin\Debug\TechTalk.SpecFlow.Parser.pdb +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\obj\Debug\ResolveAssemblyReference.cache +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\obj\Debug\TechTalk.SpecFlow.VsIntegration.Resources.resources +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\obj\Debug\TechTalk.SpecFlow.VsIntegration.VSPackage.resources +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\obj\Debug\TechTalk.SpecFlow.VsIntegration.csproj.GenerateResource.Cache +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\obj\Debug\SpecFlowStepDefinition.zip +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\obj\Debug\SpecFlowEventDefinition.zip +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\obj\Debug\SpecFlowFeature.zip +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\obj\Debug\TechTalk.SpecFlow.VsIntegration.dll +C:\Users\jba\Code\Research\TechTalk.SpecFlow\VsIntegration\obj\Debug\TechTalk.SpecFlow.VsIntegration.pdb diff --git a/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.csproj.GenerateResource.Cache b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.csproj.GenerateResource.Cache new file mode 100644 index 000000000..a09e1e2f9 Binary files /dev/null and b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.csproj.GenerateResource.Cache differ diff --git a/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.dll b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.dll new file mode 100644 index 000000000..4420a2632 Binary files /dev/null and b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.dll differ diff --git a/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.pdb b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.pdb new file mode 100644 index 000000000..50d588a01 Binary files /dev/null and b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.pdb differ diff --git a/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.pkgdef b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.pkgdef new file mode 100644 index 000000000..ea1d9d02a --- /dev/null +++ b/VsIntegration/obj/Debug/TechTalk.SpecFlow.VsIntegration.pkgdef @@ -0,0 +1,21 @@ +Windows Registry Editor Version 5.00 + +[$RootKey$\Generators\{164B10B9-B200-11D0-8C61-00A0C91E29D5}\SpecFlowSingleFileGenerator] +@="VB XML Class Generator" +"CLSID"="{3c9cf10a-a9ab-4899-a0fb-4b3be4a36c15}" +"GeneratesDesignTimeSource"=dword:00000001 +[$RootKey$\Generators\{E6FDF8B0-F3D1-11D4-8576-0002A516ECE8}\SpecFlowSingleFileGenerator] +@="J# XML Class Generator" +"CLSID"="{3c9cf10a-a9ab-4899-a0fb-4b3be4a36c15}" +"GeneratesDesignTimeSource"=dword:00000001 +[$RootKey$\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\SpecFlowSingleFileGenerator] +@="C# XML Class Generator" +"CLSID"="{3c9cf10a-a9ab-4899-a0fb-4b3be4a36c15}" +"GeneratesDesignTimeSource"=dword:00000001 +[$RootKey$\CLSID\{3c9cf10a-a9ab-4899-a0fb-4b3be4a36c15}] +@="TechTalk.SpecFlow.VsIntegration.SpecFlowSingleFileGenerator" +"InprocServer32"="%windir%\\SYSTEM32\\MSCOREE.DLL" +"Class"="TechTalk.SpecFlow.VsIntegration.SpecFlowSingleFileGenerator" +"Assembly"="TechTalk.SpecFlow.VsIntegration, Version=1.0.2.0, Culture=neutral, PublicKeyToken=null" +"ThreadingModel"="Both" + diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 000000000..941e73afb --- /dev/null +++ b/changelog.txt @@ -0,0 +1,17 @@ + +1.0.1 - 2009/10/13 + +Initial publish on http://www.specflow.org + +1.0.2 - 2009/10/20 + +Fixed issues: ++ VS: Error message is displayed when you add a SpecFlow project item to your project. ++ Parser: mixed order of Given/When/Then is not supported ++ Runtime: the original phrasing of the keywords (Given/And/But) is not preserved ++ Generator: the generated test class has a "Fixture" suffix ++ Parser: specifying any "given" should be optional + +New features: ++ Runtime: allow non-static bindings ++ Runtime: support multiple step attributes on a single binding method diff --git a/lib/antlr/Antlr3.Runtime.dll b/lib/antlr/Antlr3.Runtime.dll new file mode 100644 index 000000000..e39f7cf5c Binary files /dev/null and b/lib/antlr/Antlr3.Runtime.dll differ diff --git a/lib/antlr/antlr-3.1.2.jar b/lib/antlr/antlr-3.1.2.jar new file mode 100644 index 000000000..3c7e51e06 Binary files /dev/null and b/lib/antlr/antlr-3.1.2.jar differ diff --git a/lib/mocking/Rhino.Mocks.dll b/lib/mocking/Rhino.Mocks.dll new file mode 100644 index 000000000..3fc4b2ae4 Binary files /dev/null and b/lib/mocking/Rhino.Mocks.dll differ diff --git a/lib/nunit/nunit.framework.dll b/lib/nunit/nunit.framework.dll new file mode 100644 index 000000000..1c87f11bd Binary files /dev/null and b/lib/nunit/nunit.framework.dll differ