Example #1
0
        private static void RenderProviderGetter(StringWriter rw,
                                                 InjectionSpecificationInjection injection,
                                                 EmittedKernelSpec spec)
        {
            if (injection.Singleton)
            {
                rw.WriteLine("static {0}() {{", injection.ConcreteClassName);
                rw.WriteLine("{0} = new Lazy<{1}>(() => {{", spec.PrivateFieldName, spec.PrivateFieldType);
            }
            else
            {
                rw.WriteLine("{0} static {1} Get() {{", _renderAccessModifier, spec.ReturnType);
            }

            rw.WriteLine("var x = new {0}().Create();", injection.Provider);
            rw.WriteLine("return x;");

            if (injection.Singleton)
            {
                rw.WriteLine("});");
                rw.WriteLine("}");
                rw.WriteLine("{0} static {1} Get() {{ return {2}.Value; }}", _renderAccessModifier, spec.ReturnType, spec.PrivateFieldName);
                rw.WriteLine("{0} static Lazy<{1}> GetLazy() {{ return {2}; }}", _renderAccessModifier, spec.ReturnType, spec.PrivateFieldName);
            }
            else
            {
                rw.WriteLine("}");
                rw.WriteLine("{0} static Lazy<{1}> GetLazy() {{ return new Lazy<{1}>(Get); }}", _renderAccessModifier, spec.ReturnType);
            }
        }
Example #2
0
 private static void RenderClearAndRebind(StringWriter rw,
                                          EmittedKernelSpec spec)
 {
     rw.WriteLine("{0} static void Clear() {{ {2} = new Lazy<{1}>(() => null); }}", _renderAccessModifier, spec.PrivateFieldType, spec.PrivateFieldName);
     rw.WriteLine("{0} static void Rebind({1} value) {{ {2} = new Lazy<{1}>(() => value); }}",
                  _renderAccessModifier,
                  spec.PrivateFieldType,
                  spec.PrivateFieldName);
 }
Example #3
0
        private static void AddRenderedKernel(EmittedKernelSpec spec, InjectionSpecificationInjection injection)
        {
            spec.Namespaces = CalculateNamespacesForInjection(injection);
            spec.Namespaces = spec.Namespaces.Distinct().ToList();

            if (RenderedKernels.ContainsKey(spec.KernelClassName))
            {
                throw new InvalidOperationException("Not unique?");
            }

            RenderedKernels.Add(spec.KernelClassName, spec);
        }
Example #4
0
        private static void AddRenderedKernel(EmittedKernelSpec spec, InjectionSpecificationInjection injection)
        {
            spec.Namespaces = CalculateNamespacesForInjection(injection);
            spec.Namespaces = spec.Namespaces.Distinct().ToList();

            if (RenderedKernels.ContainsKey(spec.KernelClassName))
            {
                throw new InvalidOperationException("Not unique?");
            }

            RenderedKernels.Add(spec.KernelClassName, spec);
        }
Example #5
0
        private static string RenderPrivateField(StringWriter rw,
                                                 EmittedKernelSpec spec,
                                                 bool singleton)
        {
            int    indexOf   = spec.KernelClassName.IndexOf('_');
            string fieldName = spec.KernelClassName.Remove(0, indexOf);

            if (singleton)
            {
                rw.WriteLine("private static Lazy<{0}> {1};", spec.PrivateFieldType, fieldName);
            }
            else
            {
                rw.WriteLine("private static {0} {1};", spec.PrivateFieldType, fieldName);
            }
            return(fieldName);
        }
Example #6
0
        private static void RenderConcreteBuilderGetter(StringWriter rw,
                                                        InjectionSpecificationInjection injection,
                                                        EmittedKernelSpec spec)
        {
            if (!string.IsNullOrEmpty(injection.Provider))
            {
                throw new ParseException("Injection concrete '{0}' alse has provider '{1}' defined",
                                         injection.Concrete,
                                         injection.Provider);
            }

            string concreteToBuild = injection.Concrete;

            CSharpFile fileDefinition = injection.NoScan
                                            ? new CSharpFile(concreteToBuild)
                                            : FileScan(concreteToBuild, true);

            if (injection.Singleton)
            {
                rw.WriteLine("static {0}() {{", injection.ConcreteClassName);
                rw.WriteLine("{0} = new Lazy<{1}>(() => {{", spec.PrivateFieldName, spec.PrivateFieldType);
            }
            else
            {
                rw.WriteLine("{0} static {1} Get() {{", _renderAccessModifier, spec.ReturnType);
            }

            // There is no StackTrace on Metro :-(
            if (!_inputTokens.Contains("NETFX_CORE"))
            {
                if (!spec.IsDebug)
                {
                    rw.WriteLine("#if DEBUG");
                }
                rw.WriteLine("var stack = new StackTrace().GetFrames();");
                rw.WriteLine("var methodName = stack.First().GetMethod().DeclaringType.Name;");
                rw.WriteLine("if (stack.Count(y => y.GetMethod().DeclaringType.Name == methodName) > 2) { throw new Exception(\"Infinite loop detected\"); }");
                if (!spec.IsDebug)
                {
                    rw.WriteLine("#endif");
                }
            }
            if (_benchmarking)
            {
                if (!spec.IsDebug)
                {
                    rw.WriteLine("#if DEBUG");
                }
                rw.WriteLine("Debug.WriteLine(\"Thread(\" + System.Threading.Thread.CurrentThread.ManagedThreadId + \") : Kernel TypeConstruct: {0}\");", injection.ConcreteClassName);
                rw.WriteLine("var stopWatch = System.Diagnostics.Stopwatch.StartNew();");
                if (!spec.IsDebug)
                {
                    rw.WriteLine("#endif");
                }
            }

            rw.WriteLine("var x = new {0}(", concreteToBuild);

            if (injection.ConstructorArgument != null && injection.ConstructorArgument.Length > 0)
            {
                InjectionSpecificationInjectionConstructorArgument[] cArgs = injection.ConstructorArgument;
                for (int i = 0; i < cArgs.Length; i++)
                {
                    if (i != 0)
                    {
                        rw.Write(',');
                    }

                    rw.WriteLine(injection.ConstructorArgument[i].Value);
                }
            }
            else
            {
                IList <string> cArgs = fileDefinition.ConstructorArgs ?? new List <string>();
                for (int i = 0; i < cArgs.Count; i++)
                {
                    if (i != 0)
                    {
                        rw.Write(',');
                    }

                    string interfaceRequired = cArgs[i];
                    string concreteFunction  = GetConcreteYieldingFunction(interfaceRequired);
                    rw.WriteLine(concreteFunction);
                }
            }

            rw.WriteLine(");");

            if (_benchmarking)
            {
                if (!spec.IsDebug)
                {
                    rw.WriteLine("#if DEBUG");
                }
                rw.WriteLine("stopWatch.Stop();");
                rw.WriteLine("Debug.WriteLine(\"Thread(\" + System.Threading.Thread.CurrentThread.ManagedThreadId + \") : Kernel TypeConstruct: {0}, MillisecondsElapsed: \" + stopWatch.ElapsedMilliseconds);", injection.ConcreteClassName);
                if (!spec.IsDebug)
                {
                    rw.WriteLine("#endif");
                }
            }

            if (!injection.NoScan)
            {
                if (_benchmarking)
                {
                    if (!spec.IsDebug)
                    {
                        rw.WriteLine("#if DEBUG");
                    }
                    rw.WriteLine("stopWatch = System.Diagnostics.Stopwatch.StartNew();");
                    if (!spec.IsDebug)
                    {
                        rw.WriteLine("#endif");
                    }
                }

                var hasProperties = RenderPropertyInjections(rw, fileDefinition);

                if (_benchmarking)
                {
                    if (!spec.IsDebug)
                    {
                        rw.WriteLine("#if DEBUG");
                    }
                    rw.WriteLine("stopWatch.Stop();");
                    if (hasProperties)
                    {
                        rw.WriteLine("Debug.WriteLine(\"Thread(\" + System.Threading.Thread.CurrentThread.ManagedThreadId + \") : Kernel TypePropertiesSet: {0}, MillisecondsElapsed: \" + stopWatch.ElapsedMilliseconds);", injection.ConcreteClassName);
                    }
                    if (!spec.IsDebug)
                    {
                        rw.WriteLine("#endif");
                    }
                }
            }

            rw.WriteLine("return x;");

            if (injection.Singleton)
            {
                rw.WriteLine("});");
                rw.WriteLine("}");
                rw.WriteLine("{0} static {1} Get() {{ return {2}.Value; }}", _renderAccessModifier, spec.ReturnType, spec.PrivateFieldName);
                rw.WriteLine("{0} static Lazy<{1}> GetLazy() {{ return {2}; }}", _renderAccessModifier, spec.ReturnType, spec.PrivateFieldName);
            }
            else
            {
                rw.WriteLine("}");
                rw.WriteLine("{0} static Lazy<{1}> GetLazy() {{ return new Lazy<{1}>(Get); }}", _renderAccessModifier, spec.ReturnType, spec.PrivateFieldName);
            }
        }
Example #7
0
        private static void Render(StringWriter rw, InjectionSpecificationInjection injection)
        {
            if (injection == null)
            {
                throw new ArgumentNullException("injection");
            }

            bool debugEmit = injection.DebugOnly;

            if (debugEmit)
            {
                rw.WriteLine("#if DEBUG");
            }

            string outerKernelClassName = injection.ConcreteClassName;

            var spec = new EmittedKernelSpec
            {
                KernelClassName = outerKernelClassName,
                IsDebug         = injection.DebugOnly,
                Singleton       = injection.Singleton
            };

            rw.WriteLine("[CoverageExclude]");
            rw.WriteLine("{0} static class {1} {{", _renderAccessModifier, outerKernelClassName);

            if (!string.IsNullOrEmpty(injection.Provider))
            {
                if (injection.Interface.Length == 1)
                {
                    spec.PrivateFieldType = injection.Interface.First().Value;
                }
                else
                {
                    if (string.IsNullOrEmpty(injection.Concrete))
                    {
                        throw new Exception("Providers with no concrete and interfaces.Count != 1 not supported");
                    }

                    spec.PrivateFieldType = injection.Concrete;
                }

                if (injection.Singleton)
                {
                    spec.PrivateFieldName = RenderPrivateField(rw, spec, injection.Singleton);
                }

                spec.ReturnType = injection.Interface != null && injection.Interface.Length == 1
                                      ? injection.Interface.First().Value
                                      : injection.Concrete;

                RenderProviderGetter(rw, injection, spec);

                if (injection.Singleton)
                {
                    RenderClearAndRebind(rw, spec);
                }
            }
            else if (!string.IsNullOrEmpty(injection.Concrete))
            {
                spec.PrivateFieldType = injection.Interface != null && injection.Interface.Length == 1
                                            ? injection.Interface.First().Value
                                            : injection.Concrete;
                spec.ReturnType = spec.PrivateFieldType;

                if (injection.Singleton)
                {
                    spec.PrivateFieldName = RenderPrivateField(rw, spec, injection.Singleton);
                }

                RenderConcreteBuilderGetter(rw, injection, spec);

                if (injection.Singleton)
                {
                    RenderClearAndRebind(rw, spec);
                }
            }
            else
            {
                throw new ParseException("Injection defined with no Concrete or Provider?");
            }

            rw.WriteLine('}');

            AddRenderedKernel(spec, injection);

            // Render additional interfaces...
            if (injection.Interface != null)
            {
                foreach (InjectionSpecificationInjectionInterface @interface in injection.Interface)
                {
                    string interfaceName = @interface.Value;

                    if (!interfaceName.StartsWith("I"))
                    {
                        throw new ParseException(
                                  string.Format(
                                      "All interfaces need to start with 'I'. Check the InjectionSpecification is formated correctly without line breaks or similare in the node. Current interface name being read: '{0}'.",
                                      interfaceName));
                    }

                    string interfaceNameNoI = interfaceName.Substring(1, interfaceName.Length - 1).RemoveDodgyTokens();

                    EmittedKernelSpec existingSpec =
                        RenderedKernels.Where(x => x.Value.ReturnType == interfaceName).Select(x => x.Value).
                        SingleOrDefault();

                    if (!injection.ShouldHaveConcreteCoreRender && existingSpec != null)
                    {
                        // We've already built this above...
                        continue;
                    }

                    // Render Kernel Reference which points to the concrete...
                    var spec2 = new EmittedKernelSpec
                    {
                        KernelClassName  = string.Format("Kernel_{0}", interfaceNameNoI),
                        PrivateFieldType = interfaceName,
                        IsDebug          = false,
                        Singleton        = injection.Singleton
                    };

                    rw.WriteLine("[CoverageExclude]");
                    rw.WriteLine("{0} static class {1} {{",
                                 _renderAccessModifier,
                                 spec2.KernelClassName);

                    spec2.ReturnType = spec2.PrivateFieldType;

                    if (injection.Singleton)
                    {
                        spec2.PrivateFieldName = RenderPrivateField(rw, spec2, injection.Singleton);

                        rw.WriteLine(
                            "static {0}() {{ {1} = new Lazy<{2}>({3}.Get); }}",
                            spec2.KernelClassName,
                            spec2.PrivateFieldName,
                            spec2.ReturnType,
                            injection.ConcreteClassName);
                        rw.WriteLine(
                            "{0} static {1} Get() {{ return {2}.Value; }}",
                            _renderAccessModifier,
                            spec2.ReturnType,
                            spec2.PrivateFieldName);
                        rw.WriteLine(
                            "{0} static Lazy<{1}> GetLazy() {{ return {2}; }}",
                            _renderAccessModifier,
                            spec2.ReturnType,
                            spec2.PrivateFieldName);

                        RenderClearAndRebind(rw, spec2);
                    }
                    else
                    {
                        rw.WriteLine(
                            "{0} static {1} Get() {{ return {3}.Get(); }}",
                            _renderAccessModifier,
                            spec2.ReturnType,
                            spec2.PrivateFieldName,
                            injection.ConcreteClassName);
                        rw.WriteLine(
                            "{0} static Lazy<{1}> GetLazy() {{ return new Lazy<{1}>({2}.Get); }}",
                            _renderAccessModifier,
                            spec2.ReturnType,
                            injection.ConcreteClassName);
                    }

                    rw.WriteLine('}');

                    AddRenderedKernel(spec2, injection);
                }
            }

            if (debugEmit)
            {
                rw.WriteLine("#endif");
            }
        }
Example #8
0
        private static void RenderNamespaces(StreamWriter rw)
        {
            var namespaces      = new List <string>();
            var debugNamespaces = new List <string>();

            namespaces.Add("System");
            namespaces.Add("System.Diagnostics");
            namespaces.Add("System.Linq");
            namespaces.Add("System.Reflection");

            foreach (string kernelKey in RenderedKernels.Keys)
            {
                EmittedKernelSpec kernel = RenderedKernels[kernelKey];

                foreach (string @namespace in kernel.Namespaces)
                {
                    if (kernel.IsDebug)
                    {
                        debugNamespaces.Add(@namespace);
                    }
                    else
                    {
                        namespaces.Add(@namespace);
                    }
                }
            }

            // Add explicit namespaces
            if (_injectionSpecification.Namespaces != null)
            {
                foreach (InjectionSpecificationNamespace explicitNamespace in _injectionSpecification.Namespaces)
                {
                    string condition = explicitNamespace.Condition;

                    bool valid = true;

                    if (!String.IsNullOrEmpty(condition))
                    {
                        bool invertCondition = false;

                        if (condition.StartsWith("!"))
                        {
                            invertCondition = true;
                            condition       = condition.Substring(1, condition.Length - 1);
                        }

                        valid = _inputTokens.Contains(condition) != invertCondition;
                    }

                    if (valid)
                    {
                        if (explicitNamespace.DebugOnlySpecified && explicitNamespace.DebugOnly)
                        {
                            debugNamespaces.Add(explicitNamespace.Value);
                        }
                        else
                        {
                            namespaces.Add(explicitNamespace.Value);
                        }
                    }
                }
            }

            // Filter and sort
            namespaces      = namespaces.Distinct().OrderBy(x => x).ToList();
            debugNamespaces = debugNamespaces.Where(x => !namespaces.Contains(x)).Distinct().OrderBy(x => x).ToList();

            if (debugNamespaces.Count > 0)
            {
                rw.WriteLine("#if DEBUG");
            }

            foreach (string @namespace in debugNamespaces)
            {
                rw.WriteLine("using {0};", @namespace);
            }

            if (debugNamespaces.Count > 0)
            {
                rw.WriteLine("#endif");
            }

            foreach (string @namespace in namespaces)
            {
                rw.WriteLine("using {0};", @namespace);
            }
        }
Example #9
0
 private static void RenderProviderGetter(StringWriter rw,
                                          InjectionSpecificationInjection injection,
                                          EmittedKernelSpec spec)
 {
     rw.WriteLine("{0} static {1} Get() {{", _renderAccessModifier, spec.ReturnType);
     if (injection.Singleton)
     {
         rw.WriteLine("if({0} != null) return {0};", spec.PrivateFieldName);
     }
     rw.WriteLine("{0} = new {1}().Create();", spec.PrivateFieldName, injection.Provider);
     rw.WriteLine("return {0};", spec.PrivateFieldName);
     rw.WriteLine("}");
 }
Example #10
0
 private static string RenderPrivateField(StringWriter rw, EmittedKernelSpec spec)
 {
     int indexOf = spec.KernelClassName.IndexOf('_');
     string fieldName = spec.KernelClassName.Remove(0, indexOf);
     rw.WriteLine("private static {0} {1};", spec.PrivateFieldType, fieldName);
     return fieldName;
 }
Example #11
0
        private static void RenderConcreteBuilderGetter(StringWriter rw,
                                                        InjectionSpecificationInjection injection,
                                                        EmittedKernelSpec spec)
        {
            if (!string.IsNullOrEmpty(injection.Provider))
            {
                throw new ParseException("Injection concrete '{0}' alse has provider '{1}' defined",
                                         injection.Concrete,
                                         injection.Provider);
            }

            string concreteToBuild = injection.Concrete;

            CSharpFile fileDefinition = injection.NoScan
                                            ? new CSharpFile(concreteToBuild)
                                            : FileScan(concreteToBuild, true);

            rw.WriteLine("{0} static {1} Get() {{", _renderAccessModifier, spec.ReturnType);

            if (injection.Singleton)
            {
                rw.WriteLine("if({0} != null) return {0};", spec.PrivateFieldName);
            }

            // There is no StackTrace on Metro :-(
            if (!_inputTokens.Contains("NETFX_CORE"))
            {
                if (!spec.IsDebug)
                {
                    rw.WriteLine("#if DEBUG");
                }
                rw.WriteLine("var stack = new StackTrace().GetFrames();");
                rw.WriteLine("var methodName = stack.First().GetMethod().DeclaringType.Name;");
                rw.WriteLine(
                    "if (stack.Count(y => y.GetMethod().DeclaringType.Name == methodName) > 1) { throw new Exception(\"Infinite loop detected\"); }");
                if (!spec.IsDebug)
                {
                    rw.WriteLine("#endif");
                }
            }

            rw.WriteLine("var x = new {0}(", concreteToBuild);

            if (injection.ConstructorArgument != null && injection.ConstructorArgument.Length > 0)
            {
                InjectionSpecificationInjectionConstructorArgument[] cArgs = injection.ConstructorArgument;
                for (int i = 0; i < cArgs.Length; i++)
                {
                    if (i != 0)
                    {
                        rw.Write(',');
                    }

                    rw.WriteLine(injection.ConstructorArgument[i].Value);
                }
            }
            else
            {
                IList<string> cArgs = fileDefinition.ConstructorArgs ?? new List<string>();
                for (int i = 0; i < cArgs.Count; i++)
                {
                    if (i != 0)
                    {
                        rw.Write(',');
                    }

                    string interfaceRequired = cArgs[i];
                    string concreteFunction = GetConcreteYieldingFunction(interfaceRequired);
                    rw.WriteLine(concreteFunction);
                }
            }

            rw.WriteLine(");");
            rw.WriteLine("{0} = x;", spec.PrivateFieldName);

            if (!injection.NoScan)
            {
                RenderPropertyInjections(rw, fileDefinition);
            }

            rw.WriteLine("return {0};", spec.PrivateFieldName);
            rw.WriteLine("}");
        }
Example #12
0
 private static void RenderClearAndRebind(StringWriter rw, EmittedKernelSpec spec)
 {
     // Annoyingly, I wanted to do these through reflection to ensure encapsulation, but silverlight has removed the
     // ability to assign private fields, so I'm forced to make these public...
     rw.WriteLine("{0} static void Clear() {{ {1} = null; }}", _renderAccessModifier, spec.PrivateFieldName);
     rw.WriteLine("{0} static void Rebind({1} value) {{ {2} = value; }}",
                  _renderAccessModifier,
                  spec.PrivateFieldType,
                  spec.PrivateFieldName);
 }
Example #13
0
        private static void Render(StringWriter rw, InjectionSpecificationInjection injection)
        {
            if (injection == null)
            {
                throw new ArgumentNullException("injection");
            }

            bool debugEmit = injection.DebugOnly;
            if (debugEmit)
            {
                rw.WriteLine("#if DEBUG");
            }

            string outerKernelClassName = injection.ConcreteClassName;

            var spec = new EmittedKernelSpec
                           {
                               KernelClassName = outerKernelClassName,
                               IsDebug = injection.DebugOnly
                           };

            rw.WriteLine("[CoverageExclude]");
            rw.WriteLine("{0} static class {1} {{", _renderAccessModifier, outerKernelClassName);

            RenderStaticConstructorDebugLog(injection, debugEmit, rw);

            if (!string.IsNullOrEmpty(injection.Provider))
            {
                if (string.IsNullOrEmpty(injection.Concrete))
                {
                    if (injection.Interface.Count() != 1)
                    {
                        throw new Exception("Providers with no concrete and interfaces.Count != 1 not supported");
                    }
                    spec.PrivateFieldType = injection.Interface.First().Value;
                    spec.PrivateFieldName = RenderPrivateField(rw, spec);
                }
                else
                {
                    spec.PrivateFieldType = injection.Concrete;
                    spec.PrivateFieldName = RenderPrivateField(rw, spec);
                }

                spec.ReturnType = injection.Interface != null && injection.Interface.Length == 1
                                      ? injection.Interface.First().Value
                                      : injection.Concrete;

                RenderProviderGetter(rw, injection, spec);
                RenderClearAndRebind(rw, spec);
            }
            else if (!string.IsNullOrEmpty(injection.Concrete))
            {
                spec.PrivateFieldType = injection.Interface != null && injection.Interface.Length == 1
                                            ? injection.Interface.First().Value
                                            : injection.Concrete;
                spec.ReturnType = spec.PrivateFieldType;
                spec.PrivateFieldName = RenderPrivateField(rw, spec);
                RenderConcreteBuilderGetter(rw, injection, spec);
                RenderClearAndRebind(rw, spec);
            }
            else
            {
                throw new ParseException("Injection defined with no Concrete or Provider?");
            }

            rw.WriteLine('}');

            AddRenderedKernel(spec, injection);

            // Render additional interfaces...
            if (injection.Interface != null)
            {
                foreach (InjectionSpecificationInjectionInterface @interface in injection.Interface)
                {
                    string interfaceName = @interface.Value;

                    if (!interfaceName.StartsWith("I"))
                    {
                        throw new ParseException(
                            string.Format(
                                "All interfaces need to start with 'I'. Check the InjectionSpecification is formated correctly without line breaks or similare in the node. Current interface name being read: '{0}'.",
                                interfaceName));
                    }

                    string interfaceNameNoI = interfaceName.Substring(1, interfaceName.Length - 1).RemoveDodgyTokens();

                    EmittedKernelSpec existingSpec =
                        RenderedKernels.Where(x => x.Value.ReturnType == interfaceName).Select(x => x.Value).
                                        SingleOrDefault();

                    if (!injection.ShouldHaveConcreteCoreRender && existingSpec != null)
                    {
                        // We've already built this above...
                        continue;
                    }

                    // Render Kernel Reference which points to the concrete...
                    var spec2 = new EmittedKernelSpec
                                    {
                                        KernelClassName = string.Format("Kernel_{0}", interfaceNameNoI),
                                        PrivateFieldType = interfaceName,
                                        IsDebug = false
                                    };

                    rw.WriteLine("[CoverageExclude]");
                    rw.WriteLine("{0} static class {1} {{",
                                 _renderAccessModifier,
                                 spec2.KernelClassName);

                    spec2.PrivateFieldName = RenderPrivateField(rw, spec2);
                    spec2.ReturnType = spec2.PrivateFieldType;

                    rw.WriteLine(
                        "{0} static {1} Get() {{ if({2} != null) {{ return {2}; }} var x = {3}.Get(); {2} = x; return x; }}",
                        _renderAccessModifier,
                        spec2.ReturnType,
                        spec2.PrivateFieldName,
                        injection.ConcreteClassName);

                    RenderClearAndRebind(rw, spec2);

                    rw.WriteLine('}');

                    AddRenderedKernel(spec2, injection);
                }
            }

            if (debugEmit)
            {
                rw.WriteLine("#endif");
            }
        }