コード例 #1
0
        public IProcessTransformationRunner PrepareTransformationRunner(string content, ITextTemplatingEngineHost host, IProcessTransformationRunFactory runFactory, bool debugging = false)
        {
            if (content == null)
            {
                throw new ArgumentNullException(nameof(content));
            }
            if (host == null)
            {
                throw new ArgumentNullException(nameof(host));
            }
            if (runFactory == null)
            {
                throw new ArgumentNullException(nameof(runFactory));
            }

            if (host is ITextTemplatingSessionHost sessionHost)
            {
                if (sessionHost.Session == null)
                {
                    sessionHost.Session = sessionHost.CreateSession();
                }
            }

            IProcessTransformationRunner runner = null;

            ParsedTemplate pt = ParsedTemplate.FromText(content, host);

            TemplateSettings settings = GetSettings(host, pt);

            settings.Debug = debugging || settings.CachedTemplates;

            EnsureParameterValuesExist(settings, host, pt);

            try {
                if (pt.Errors.HasErrors)
                {
                    return(null);
                }

                runner = CompileAndPrepareRunner(pt, content, host, runFactory, settings);
            }
            catch (Exception ex) {
                if (IsCriticalException(ex))
                {
                    throw;
                }
                pt.LogError(string.Format(CultureInfo.CurrentCulture, VsTemplatingErrorResources.ExceptionProcessingTemplate, ex), new Location(host.TemplateFile, -1, -1));
            }
            finally {
                host.LogErrors(pt.Errors);
            }

            return(runner);
        }
コード例 #2
0
ファイル: ParsedTemplate.cs プロジェクト: ByronMayne/VSCodeT4
        public static ParsedTemplate FromText(string content, ITextTemplatingEngineHost host)
        {
            ParsedTemplate template = new ParsedTemplate(host.TemplateFile);

            try {
                template.Parse(host, new Tokeniser(host.TemplateFile, content));
            } catch (ParserException ex) {
                template.LogError(ex.Message, ex.Location);
            }
            return(template);
        }
コード例 #3
0
        public string ProcessTemplate(string content, ITextTemplatingEngineHost host)
        {
            ParsedTemplate pt = ParsedTemplate.FromText(content, host);

            if (pt.Errors.HasErrors)
            {
                host.LogErrors(pt.Errors);
                return(null);
            }

            TemplateSettings settings = GetSettings(host, pt);

            if (pt.Errors.HasErrors)
            {
                host.LogErrors(pt.Errors);
                return(null);
            }

            CodeCompileUnit ccu = GenerateCompileUnit(host, pt, settings);

            if (pt.Errors.HasErrors)
            {
                host.LogErrors(pt.Errors);
                return(null);
            }

            System.Reflection.Assembly results = GenerateCode(host, pt, settings, ccu);
            if (pt.Errors.HasErrors)
            {
                host.LogErrors(pt.Errors);
                return(null);
            }

            if (!String.IsNullOrEmpty(settings.Extension))
            {
                host.SetFileExtension(settings.Extension);
            }
            if (settings.Encoding != null)
            {
                //FIXME: when is this called with false?
                host.SetOutputEncoding(settings.Encoding, true);
            }

            string output = "";

            try {
                output = Run(results, settings.Namespace + "." + settings.Name, host, settings.Culture);
            } catch (Exception ex) {
                pt.LogError("Error running transform: " + ex.ToString());
            }
            host.LogErrors(pt.Errors);
            return(output);
        }
コード例 #4
0
        public string Process()
        {
            string output = "";

            try {
                output = TemplatingEngine.Run(assembly, settings.Namespace + "." + settings.Name, host, settings.Culture);
            } catch (Exception ex) {
                parsedTemplate.LogError("Error running transform: " + ex);
            }

            host.LogErrors(parsedTemplate.Errors);
            return(output);
        }
コード例 #5
0
        public static ParsedTemplate FromText(string content, ITextTemplatingEngineHost host)
        {
            if (host == null)
            {
                throw new ArgumentNullException(nameof(host));
            }

            var template = new ParsedTemplate(host.TemplateFile);

            try {
                template.Parse(host, new Tokeniser(host.TemplateFile, content));
            } catch (ParserException ex) {
                template.LogError(ex.Message, ex.Location);
            }
            return(template);
        }
コード例 #6
0
        public static System.Reflection.Assembly GenerateCode(ITextTemplatingEngineHost host, ParsedTemplate pt,
                                                              TemplateSettings settings, CodeCompileUnit ccu)
        {
            CompilerParameters pars = new CompilerParameters();

            pars.GenerateExecutable = false;

            if (settings.Debug)
            {
                pars.GenerateInMemory        = false;
                pars.IncludeDebugInformation = true;
                pars.TempFiles.KeepFiles     = true;
            }
            else
            {
                pars.GenerateInMemory        = true;
                pars.IncludeDebugInformation = false;
            }

            //resolve and add assembly references
            var assemblies = new Dictionary <string, object>();

            UnionWith(assemblies, settings.Assemblies);
            UnionWith(assemblies, host.StandardAssemblyReferences);
            foreach (string assem in assemblies.Keys)
            {
                string resolvedAssem = host.ResolveAssemblyReference(assem);
                if (!String.IsNullOrEmpty(resolvedAssem))
                {
                    pars.ReferencedAssemblies.Add(resolvedAssem);
                }
                else
                {
                    pt.LogError("Could not resolve assembly reference '" + assem + "'");
                    return(null);
                }
            }
            CompilerResults results = settings.Provider.CompileAssemblyFromDom(pars, ccu);

            pt.Errors.AddRange(results.Errors);
            if (pt.Errors.HasErrors)
            {
                return(null);
            }
            return(results.CompiledAssembly);
        }
コード例 #7
0
 static void EnsureParameterValuesExist(TemplateSettings settings, ITextTemplatingEngineHost host, ParsedTemplate pt)
 {
     foreach (var directive in settings.CustomDirectives)
     {
         if (directive.ProcessorName == nameof(ParameterDirectiveProcessor))
         {
             if (directive.Directive.Attributes.TryGetValue("name", out string parameterName))
             {
                 if (!string.IsNullOrEmpty(host.ResolveParameterValue(directive.Directive.Name, directive.ProcessorName, parameterName)))
                 {
                     continue;
                 }
             }
             pt.LogError(string.Format(CultureInfo.CurrentCulture, VsTemplatingErrorResources.CouldNotVerifyParameterValue, parameterName));
         }
     }
 }
コード例 #8
0
        public static TemplateSettings GetSettings(ITextTemplatingEngineHost host, ParsedTemplate pt)
        {
            string language = null;

            TemplateSettings settings = new TemplateSettings();

            foreach (Directive dt in pt.Directives)
            {
                switch (dt.Name)
                {
                case "template":
                    string val = dt.Extract("language");
                    if (val != null)
                    {
                        language = val;
                    }
                    val = dt.Extract("debug");
                    if (val != null)
                    {
                        settings.Debug = string.Compare(val, "true", StringComparison.OrdinalIgnoreCase) == 0;
                    }
                    val = dt.Extract("inherits");
                    if (val != null)
                    {
                        settings.Inherits = val;
                    }
                    val = dt.Extract("culture");
                    if (val != null)
                    {
                        System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.GetCultureInfo(val);
                        if (culture == null)
                        {
                            pt.LogWarning("Could not find culture '" + val + "'", dt.StartLocation);
                        }
                        else
                        {
                            settings.Culture = culture;
                        }
                    }
                    val = dt.Extract("hostspecific");
                    if (val != null)
                    {
                        settings.HostSpecific = string.Compare(val, "true", StringComparison.OrdinalIgnoreCase) == 0;
                    }
                    break;

                case "assembly":
                    string name = dt.Extract("name");
                    if (name == null)
                    {
                        pt.LogError("Missing name attribute in assembly directive", dt.StartLocation);
                    }
                    else
                    {
                        settings.Assemblies.Add(name);
                    }
                    break;

                case "import":
                    string namespac = dt.Extract("namespace");
                    if (namespac == null)
                    {
                        pt.LogError("Missing namespace attribute in import directive", dt.StartLocation);
                    }
                    else
                    {
                        settings.Imports.Add(namespac);
                    }
                    break;

                case "output":
                    settings.Extension = dt.Extract("extension");
                    string encoding = dt.Extract("encoding");
                    if (encoding != null)
                    {
                        settings.Encoding = Encoding.GetEncoding("encoding");
                    }
                    break;

                case "include":
                    throw new InvalidOperationException("Include is handled in the parser");

                default:
                    throw new NotImplementedException("Custom directives are not supported yet");
                }
                ComplainExcessAttributes(dt, pt);
            }

            if (settings.Name == null)
            {
                settings.Name = string.Format("GeneratedTextTransformation{0:x}", new System.Random().Next());
            }
            if (settings.Namespace == null)
            {
                settings.Namespace = typeof(TextTransformation).Namespace;
            }

            //resolve the CodeDOM provider
            if (String.IsNullOrEmpty(language))
            {
                pt.LogError("No language was specified for the template");
                return(settings);
            }

            if (language == "C#v3.5")
            {
                Dictionary <string, string> providerOptions = new Dictionary <string, string> ();
                providerOptions.Add("CompilerVersion", "v3.5");
                settings.Provider = new CSharpCodeProvider(providerOptions);
            }
            else
            {
                settings.Provider = CodeDomProvider.CreateProvider(language);
            }

            if (settings.Provider == null)
            {
                pt.LogError("A provider could not be found for the language '" + language + "'");
                return(settings);
            }

            return(settings);
        }
コード例 #9
0
        protected virtual IProcessTransformationRunner CompileAndPrepareRunner(ParsedTemplate pt, string content, ITextTemplatingEngineHost host, IProcessTransformationRunFactory runFactory, TemplateSettings settings)
        {
            TransformationRunner runner = null;
            bool success = false;

            if (pt == null)
            {
                throw new ArgumentNullException(nameof(pt));
            }

            if (host == null)
            {
                throw new ArgumentNullException(nameof(host));
            }

            if (runFactory == null)
            {
                throw new ArgumentNullException(nameof(runFactory));
            }

            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            try {
                try {
                    if (runFactory.CreateTransformationRunner() is TransformationRunner theRunner)
                    {
                        runner = theRunner;
                    }
                }
                catch (Exception ex) {
                    if (IsCriticalException(ex))
                    {
                        throw;
                    }
                    pt.LogError(ex.ToString(), new Location(host.TemplateFile));
                }
                if (runner != null && !runner.Errors.HasErrors)
                {
                    // reference the assemblies and ensure they are path rooted
                    settings.SetAssemblies(ProcessReferences(host, pt, settings));
                    if (!pt.Errors.HasErrors)
                    {
                        try {
                            success = runFactory.PrepareTransformation(runner.RunnerId, pt, content, host, settings);
                        }
                        catch (SerializationException) {
                            pt.LogError(VsTemplatingErrorResources.SessionHostMarshalError, new Location(host.TemplateFile));
                            throw;
                        }
                    }
                }
            }
            catch (Exception ex) {
                if (IsCriticalException(ex))
                {
                    throw;
                }
                pt.LogError(ex.ToString(), new Location(host.TemplateFile, -1, -1));
            }
            finally {
                if (runner != null)
                {
                    pt.Errors.AddRange(runFactory.GetErrors(runner.RunnerId));
                }
            }

            return(success ? runner : null);
        }
コード例 #10
0
        static void GenerateTransformMethod(CodeTypeDeclaration templateType, TemplateSettings settings, ParsedTemplate pt, string templateFile, bool isOverride)
        {
            string baseDirectory = Path.GetDirectoryName(templateFile);

            var transformMeth = Declare.Method("TransformText").Returns <string> ().AsVirtual();

            if (isOverride)
            {
                transformMeth.AsOverride();
            }

            transformMeth.WithStatements(Expression.This.SetProperty("GenerationEnvironment", Expression.Null));

            CodeExpression toStringHelper = settings.IsPreprocessed
                                ? Expression.This.Property("ToStringHelper")
                                : TypeReference.Global(typeof(ToStringHelper)).AsExpression();

            //method references that will need to be used multiple times
            var  writeMeth    = Expression.This.Method("Write");
            var  toStringMeth = toStringHelper.Method("ToStringWithCulture");
            bool helperMode   = false;

            //build the code from the segments
            foreach (TemplateSegment seg in pt.Content)
            {
                CodeStatement  st       = null;
                CodeLinePragma location = null;
                if (!settings.NoLinePragmas)
                {
                    var f = seg.StartLocation.FileName ?? templateFile;
                    if (!string.IsNullOrEmpty(f))
                    {
                        // FIXME: we need to know where the output file will be to make this work properly
                        if (settings.RelativeLinePragmas)
                        {
                            f = FileUtil.AbsoluteToRelativePath(baseDirectory, f);
                        }
                        else
                        {
                            f = Path.GetFullPath(f);
                        }
                    }
                    location = new CodeLinePragma(f, seg.StartLocation.Line);
                }
                switch (seg.Type)
                {
                case SegmentType.Block:
                    if (helperMode)
                    {
                        //TODO: are blocks permitted after helpers?
                        pt.LogError("Blocks are not permitted after helpers", seg.TagStartLocation);
                    }
                    st = Statement.Snippet(seg.Text);
                    break;

                case SegmentType.Expression:
                    st = writeMeth.Invoke(toStringMeth.Invoke(Expression.Snippet(seg.Text))).AsStatement();
                    break;

                case SegmentType.Content:
                    st = writeMeth.Invoke(Expression.Primitive(seg.Text)).AsStatement();
                    break;

                case SegmentType.Helper:
                    if (!string.IsNullOrEmpty(seg.Text))
                    {
                        templateType.AddSnippetMember(seg.Text, location);
                    }
                    helperMode = true;
                    break;

                default:
                    throw new InvalidOperationException();
                }
                if (st != null)
                {
                    if (helperMode)
                    {
                        //convert the statement into a snippet member and attach it to the top level type
                        //TODO: is there a way to do this for languages that use indentation for blocks, e.g. python?
                        using (var writer = new StringWriter()) {
                            settings.Provider.GenerateCodeFromStatement(st, writer, null);
                            var text = writer.ToString();
                            if (!string.IsNullOrEmpty(text))
                            {
                                templateType.AddSnippetMember(text, location);
                            }
                        }
                    }
                    else
                    {
                        st.LinePragma = location;
                        transformMeth.Statements.Add(st);
                        continue;
                    }
                }
            }

            transformMeth.WithStatements(Statement.Return(Expression.This.Property("GenerationEnvironment").InvokeMethod("ToString")));

            templateType.AddMember(transformMeth);
        }