File: BaseTemplateBuildProvider.cs

package info (click to toggle)
mono 6.12.0.199%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,296,836 kB
  • sloc: cs: 11,181,803; xml: 2,850,076; ansic: 699,709; cpp: 123,344; perl: 59,361; javascript: 30,841; asm: 21,853; makefile: 20,405; sh: 15,009; python: 4,839; pascal: 925; sql: 859; sed: 16; php: 1
file content (215 lines) | stat: -rw-r--r-- 7,543 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//------------------------------------------------------------------------------
// <copyright file="BaseTemplateBuildProvider.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------



namespace System.Web.Compilation {

using System;
using System.IO;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Web.Util;
using System.Web.UI;

internal abstract class BaseTemplateBuildProvider: InternalBuildProvider {

    private TemplateParser _parser;
    internal TemplateParser Parser { get { return _parser; } }

    internal override IAssemblyDependencyParser AssemblyDependencyParser {
        get { return _parser; }
    }

    private string _instantiatableFullTypeName;
    private string _intermediateFullTypeName;

    protected abstract TemplateParser CreateParser();

    internal abstract BaseCodeDomTreeGenerator CreateCodeDomTreeGenerator(TemplateParser parser);

    protected internal override CodeCompileUnit GetCodeCompileUnit(out IDictionary linePragmasTable) {
        Debug.Assert(_parser != null);

        // Return the provider type and compiler params
        Type codeDomProviderType = _parser.CompilerType.CodeDomProviderType;

        // Create a code generator for the language
        CodeDomProvider codeDomProvider = CompilationUtil.CreateCodeDomProviderNonPublic(
            codeDomProviderType);

        // Create a designer mode codedom tree for the page
        BaseCodeDomTreeGenerator treeGenerator = CreateCodeDomTreeGenerator(_parser);
        treeGenerator.SetDesignerMode();
        CodeCompileUnit ccu = treeGenerator.GetCodeDomTree(codeDomProvider,
            new StringResourceBuilder(), VirtualPathObject);
        linePragmasTable = treeGenerator.LinePragmasTable;

// This code is used to see the full generated code in the debugger.  Just uncomment and look at
// generatedCode in the debugger.  Don't check in with this code uncommented!
#if TESTCODE
        Stream stream = new MemoryStream();
        StreamWriter writer = new StreamWriter(stream, System.Text.Encoding.Unicode);
        codeDomProvider.GenerateCodeFromCompileUnit(ccu, writer, null /*CodeGeneratorOptions*/);
        writer.Flush();
        stream.Seek(0, SeekOrigin.Begin);
        TextReader reader = new StreamReader(stream);
        string generatedCode = reader.ReadToEnd();
#endif

        return ccu;
    }

    public override CompilerType CodeCompilerType {
        get {
            Debug.Assert(_parser == null);

            _parser = CreateParser();

            if (IgnoreParseErrors)
                _parser.IgnoreParseErrors = true;

            if (IgnoreControlProperties)
                _parser.IgnoreControlProperties = true;

            if (!ThrowOnFirstParseError)
                _parser.ThrowOnFirstParseError = false;

            _parser.Parse(ReferencedAssemblies, VirtualPathObject);

            // If the page is non-compiled, don't ask for a language
            if (!Parser.RequiresCompilation)
                return null;

            return _parser.CompilerType;
        }
    }

    internal override ICollection GetCompileWithDependencies() {

        // If there is a code besides file, return it

        if (_parser.CodeFileVirtualPath == null)
            return null;

        // no-compile pages should not have any compile with dependencies
        Debug.Assert(Parser.RequiresCompilation);

        return new SingleObjectCollection(_parser.CodeFileVirtualPath);
    }

    public override void GenerateCode(AssemblyBuilder assemblyBuilder) {

        // Don't generate any code for no-compile pages
        if (!Parser.RequiresCompilation)
            return;

        BaseCodeDomTreeGenerator treeGenerator = CreateCodeDomTreeGenerator(_parser);

        CodeCompileUnit ccu = treeGenerator.GetCodeDomTree(assemblyBuilder.CodeDomProvider,
            assemblyBuilder.StringResourceBuilder, VirtualPathObject);

        if (ccu != null) {
            // Add all the assemblies
            if (_parser.AssemblyDependencies != null) {
                foreach (Assembly assembly in _parser.AssemblyDependencies) {
                    assemblyBuilder.AddAssemblyReference(assembly, ccu);
                }
            }

            assemblyBuilder.AddCodeCompileUnit(this, ccu);
        }

        // Get the name of the generated type that can be instantiated.  It may be null
        // in updatable compilation scenarios.
        _instantiatableFullTypeName = treeGenerator.GetInstantiatableFullTypeName();

        // tell the assembly builder to generate a fast factory for this type
        if (_instantiatableFullTypeName != null)
            assemblyBuilder.GenerateTypeFactory(_instantiatableFullTypeName);

        _intermediateFullTypeName = treeGenerator.GetIntermediateFullTypeName();
    }

    public override Type GetGeneratedType(CompilerResults results) {
        return GetGeneratedType(results, useDelayLoadTypeIfEnabled: false);
    }

    internal Type GetGeneratedType(CompilerResults results, bool useDelayLoadTypeIfEnabled) {

        // No Type is generated for no-compile pages
        if (!Parser.RequiresCompilation)
            return null;

        // Figure out the Type that needs to be persisted
        string typeName;

        if (_instantiatableFullTypeName == null) {

            if (Parser.CodeFileVirtualPath != null) {
                // Updatable precomp of a code separation page: use the intermediate type
                typeName = _intermediateFullTypeName;
            }
            else {
                // Updatable precomp of a single page: use the base type, since nothing got compiled
                return Parser.BaseType;
            }
        }
        else {
            typeName = _instantiatableFullTypeName;
        }

        Debug.Assert(typeName != null);

        Type generatedType;
        if (useDelayLoadTypeIfEnabled && DelayLoadType.Enabled) {
            string assemblyFilename = Path.GetFileName(results.PathToAssembly);
            string assemblyName = Util.GetAssemblyNameFromFileName(assemblyFilename);
            generatedType = new DelayLoadType(assemblyName, typeName);
        }
        else {
            generatedType = results.CompiledAssembly.GetType(typeName);
        }

        // It should always extend the required base type
        // Note: removing this assert as advanced ControlBuilder scenarios allow changing the base type
        //Debug.Assert(Parser.BaseType.IsAssignableFrom(generatedType));

        return generatedType;
    }

    internal override BuildResultCompiledType CreateBuildResult(Type t) {
        return new BuildResultCompiledTemplateType(t);
    }

    public override ICollection VirtualPathDependencies {
        get {
            return _parser.SourceDependencies;
        }
    }

    internal override ICollection GetGeneratedTypeNames() {
        if (_parser.GeneratedClassName == null && _parser.BaseTypeName == null) {
            return null;
        }

        ArrayList collection = new ArrayList();
        if (_parser.GeneratedClassName != null) {
            collection.Add(_parser.GeneratedClassName);
        }

        if (_parser.BaseTypeName != null) {
            collection.Add(Util.MakeFullTypeName(_parser.BaseTypeNamespace, _parser.BaseTypeName));
        }

        return collection;
    }
}

}