public override void GenerateSourceCode(IEnumerable<IList<Chunk>> viewTemplates, IEnumerable<IList<Chunk>> allResources)
        {
            var globalSymbols = new Dictionary<string, object>();

            var writer = new StringWriter();
            var source = new SourceWriter(writer);

            var usingGenerator = new UsingNamespaceVisitor(source);
            var baseClassGenerator = new BaseClassVisitor { BaseClass = BaseClass };
            var globalsGenerator = new GlobalMembersVisitor(source, globalSymbols, NullBehaviour);

            // using <namespaces>;
            foreach (var ns in UseNamespaces ?? new string[0])
                usingGenerator.UsingNamespace(ns);

            foreach (var assembly in UseAssemblies ?? new string[0])
                usingGenerator.UsingAssembly(assembly);

            foreach (var resource in allResources)
                usingGenerator.Accept(resource);

            foreach (var resource in allResources)
                baseClassGenerator.Accept(resource);

            var viewClassName = "View" + GeneratedViewId.ToString("n");

            if (string.IsNullOrEmpty(TargetNamespace))
            {
                ViewClassFullName = viewClassName;
            }
            else
            {
                ViewClassFullName = TargetNamespace + "." + viewClassName;

                source
                    .WriteLine()
                    .WriteLine(string.Format("namespace {0}", TargetNamespace))
                    .WriteLine("{").AddIndent();
            }

            source.WriteLine();

            if (Descriptor != null)
            {
                // [SparkView] attribute
                source.WriteLine("[global::Spark.SparkViewAttribute(");
                if (TargetNamespace != null)
                    source.WriteFormat("    TargetNamespace=\"{0}\",", TargetNamespace).WriteLine();
                source.WriteLine("    Templates = new string[] {");
                source.Write("      ").WriteLine(string.Join(",\r\n      ",
                                                               Descriptor.Templates.Select(
                                                                   t => "\"" + t.Replace("\\", "\\\\") + "\"").ToArray()));
                source.WriteLine("    })]");
            }

            // public class ViewName : BasePageType
            source
                .Write("public class ")
                .Write(viewClassName)
                .Write(" : ")
                .WriteCode(baseClassGenerator.BaseClassTypeName)
                .WriteLine();
            source.WriteLine("{").AddIndent();

            source.WriteLine();
            EditorBrowsableStateNever(source, 4);
            source.WriteLine("private static System.Guid _generatedViewId = new System.Guid(\"{0:n}\");", GeneratedViewId);
            source.WriteLine("public override System.Guid GeneratedViewId");
            source.WriteLine("{ get { return _generatedViewId; } }");

            if (Descriptor != null && Descriptor.Accessors != null)
            {
                foreach (var accessor in Descriptor.Accessors)
                {
                    source.WriteLine();
                    source.Write("public ").WriteLine(accessor.Property);
                    source.Write("{ get { return ").Write(accessor.GetValue).WriteLine("; } }");
                }
            }

            // properties and macros
            foreach (var resource in allResources)
                globalsGenerator.Accept(resource);

            // public void RenderViewLevelx()
            int renderLevel = 0;
            foreach (var viewTemplate in viewTemplates)
            {
                source.WriteLine();
                EditorBrowsableStateNever(source, 4);
                source.WriteLine(string.Format("private void RenderViewLevel{0}()", renderLevel));
                source.WriteLine("{").AddIndent();
                var viewGenerator = new GeneratedCodeVisitor(source, globalSymbols, NullBehaviour);
                viewGenerator.Accept(viewTemplate);
                source.RemoveIndent().WriteLine("}");
                ++renderLevel;
            }

            // public void RenderView()

            source.WriteLine();
            EditorBrowsableStateNever(source, 4);
            source.WriteLine("public override void Render()");
            source.WriteLine("{").AddIndent();
            for (var invokeLevel = 0; invokeLevel != renderLevel; ++invokeLevel)

            {
                if (invokeLevel != renderLevel - 1)
                {
                    source.WriteLine("using (OutputScope()) {{RenderViewLevel{0}(); Content[\"view\"] = Output;}}", invokeLevel);
                }
                else
                {

                    source.WriteLine("        RenderViewLevel{0}();", invokeLevel);
                }
            }
            source.RemoveIndent().WriteLine("}");

            // end class
            source.RemoveIndent().WriteLine("}");

            if (!string.IsNullOrEmpty(TargetNamespace))
            {
                source.RemoveIndent().WriteLine("}");
            }

            SourceCode = source.ToString();
            SourceMappings = source.Mappings;
        }
Exemple #2
0
        public override void GenerateSourceCode(IEnumerable<IList<Chunk>> viewTemplates, IEnumerable<IList<Chunk>> allResources)
        {
            var script = new SourceWriter();
            var globals = new Dictionary<string, object>();

            var globalMembersVisitor = new GlobalMembersVisitor(script, globals);
            foreach(var resource in allResources)
                globalMembersVisitor.Accept(resource);

            var globalFunctionsVisitor = new GlobalFunctionsVisitor(script, globals);
            foreach (var resource in allResources)
                globalFunctionsVisitor.Accept(resource);

            var templateIndex = 0;
            foreach (var template in viewTemplates)
            {
                script.Write("def RenderViewLevel").Write(templateIndex).WriteLine("():");
                script.Indent++;
                foreach (var global in globals.Keys)
                    script.Write("global ").WriteLine(global);
                var generator = new GeneratedCodeVisitor(script, globals);
                generator.Accept(template);
                script.Indent--;
                script.WriteLine();
                templateIndex++;
            }

            for (var renderIndex = 0; renderIndex != templateIndex; ++renderIndex)
            {
                if (renderIndex < templateIndex - 1)
                {
                    script.WriteLine("scope=OutputScopeAdapter(None)");
                    script.Write("RenderViewLevel").Write(renderIndex).WriteLine("()");
                    script.WriteLine("Content[\"view\"] = Output");
                    script.WriteLine("scope.Dispose()");
                }
                else
                {
                    script.Write("RenderViewLevel").Write(renderIndex).WriteLine("()");
                }
            }

            var baseClassGenerator = new BaseClassVisitor { BaseClass = BaseClass };
            foreach (var resource in allResources)
                baseClassGenerator.Accept(resource);

            BaseClass = baseClassGenerator.BaseClassTypeName;

            var source = new StringBuilder();

            var viewClassName = "View" + GeneratedViewId.ToString("n");
            if (Descriptor != null && !string.IsNullOrEmpty(Descriptor.TargetNamespace))
            {
                ViewClassFullName = Descriptor.TargetNamespace + "." + viewClassName;
                source.Append("namespace ").AppendLine(Descriptor.TargetNamespace);
                source.AppendLine("{");
            }
            else
            {
                ViewClassFullName = viewClassName;
            }

            if (Descriptor != null)
            {
                // [SparkView] attribute
                source.AppendLine("[global::Spark.SparkViewAttribute(");
                if (TargetNamespace != null)
                    source.AppendFormat("    TargetNamespace=\"{0}\",", TargetNamespace).AppendLine();
                source.AppendLine("    Templates = new string[] {");
                source.Append("      ").AppendLine(string.Join(",\r\n      ",
                                                               Descriptor.Templates.Select(
                                                                   t => "\"" + SparkViewAttribute.ConvertToAttributeFormat(t) + "\"").ToArray()));
                source.AppendLine("    })]");
            }

            source.Append("public class ").Append(viewClassName).Append(" : ").Append(BaseClass).AppendLine(", global::Spark.Python.IScriptingSparkView");
            source.AppendLine("{");

            source.Append("static System.Guid _generatedViewId = new System.Guid(\"").Append(GeneratedViewId).AppendLine("\");");
            source.AppendLine("public override System.Guid GeneratedViewId");
            source.AppendLine("{");
            source.AppendLine("get { return _generatedViewId; }");
            source.AppendLine("}");

            source.AppendLine("public global::System.IDisposable OutputScopeAdapter(object arg) ");
            source.AppendLine("{");
            source.AppendLine("if (arg == null) return OutputScope();");
            source.AppendLine("if (arg is string) return OutputScope((string)arg);");
            source.AppendLine("if (arg is global::System.IO.TextWriter) return OutputScope((global::System.IO.TextWriter)arg);");
            source.AppendLine("throw new global::Spark.Compiler.CompilerException(\"Invalid argument for OutputScopeAdapter\");");
            source.AppendLine("}");

            source.AppendLine("public void OutputWriteAdapter(object arg) ");
            source.AppendLine("{");
            source.AppendLine("Output.Write(arg);");
            source.AppendLine("}");

            source.AppendLine("public global::Microsoft.Scripting.Hosting.CompiledCode CompiledCode {get;set;}");

            source.AppendLine("public string ScriptSource");
            source.AppendLine("{");
            source.Append("get { return @\"").Append(script.ToString().Replace("\"", "\"\"")).AppendLine("\"; }");
            source.AppendLine("}");

            source.AppendLine("public override void Render()");
            source.AppendLine("{");
            source.AppendLine("CompiledCode.Execute(");
            source.AppendLine("CompiledCode.Engine.CreateScope(");
            source.AppendLine("new global::Spark.Python.ScriptingViewSymbolDictionary(this)");
            source.AppendLine("));");
            source.AppendLine("}");

            source.AppendLine("}");

            if (Descriptor != null && !string.IsNullOrEmpty(Descriptor.TargetNamespace))
            {
                source.AppendLine("}");
            }

            SourceCode = source.ToString();
        }