|
//------------------------------------------------------------------------------
// <copyright file="ParseRecorder.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Web.UI {
using System.CodeDom;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Web.Compilation;
using System.Web.Util;
/// <summary>
/// Abstract base class for an object that wants to be notified of parse
/// events during page parsing.
/// </summary>
public abstract class ParseRecorder {
internal static readonly ParseRecorder Null = new NullParseRecorder();
private static List<Func<ParseRecorder>> _factories;
/// <summary>
/// Functions added to this list are called to instantiate ParseRecorders
/// for each TemplateParser.
/// </summary>
public static IList<Func<ParseRecorder>> RecorderFactories {
get {
if (_factories == null) {
_factories = new List<Func<ParseRecorder>>();
}
return _factories;
}
}
internal static ParseRecorder CreateRecorders(TemplateParser parser) {
List<ParseRecorder> recorders = new List<ParseRecorder>();
if(_factories != null) {
foreach (Func<ParseRecorder> factory in _factories) {
ParseRecorder recorder = factory();
if (recorder != null) {
recorders.Add(recorder);
}
}
}
else {
if (!BinaryCompatibility.Current.TargetsAtLeastFramework472) {
return ParseRecorder.Null;
}
}
// Support depedency injection in control type.
// Have to replace the codeAssignStatement through a ParseRecorder,
// because some existing ParseRecorder(e.g. PageInspector) may have hard dependency on the old codedom tree structure
if (BinaryCompatibility.Current.TargetsAtLeastFramework472) {
recorders.Add(new WebObjectActivatorParseRecorder());
}
ParseRecorderList list = new ParseRecorderList(recorders);
list.Initialize(parser);
return list;
}
/// <summary>
/// Called to initialize the listener.
/// </summary>
public virtual void Initialize(TemplateParser parser) {
}
/// <summary>
/// Called when the TemplateParser encounters a web control start tag
/// </summary>
public virtual void RecordBeginTag(ControlBuilder builder, Match tag) {
}
/// <summary>
/// Called when the TemplateParser encounters a web control end tag
/// </summary>
public virtual void RecordEndTag(ControlBuilder builder, Match tag) {
}
/// <summary>
/// Called when the TemplateParser encounters a web control empty tag
/// </summary>
public virtual void RecordEmptyTag(ControlBuilder builder, Match tag) {
}
/// <summary>
/// Called when the TemplateParser encounters a code block
/// </summary>
public virtual void RecordCodeBlock(ControlBuilder builder, Match codeBlock) {
}
/// <summary>
/// Called when the TemplateParser is finished parsing the file
/// </summary>
public virtual void ParseComplete(ControlBuilder root) {
}
/// <summary>
/// Enables the ParseRecorder to access the generated CodeDom and insert
/// and modify code
/// </summary>
public virtual void ProcessGeneratedCode(
ControlBuilder builder,
CodeCompileUnit codeCompileUnit,
CodeTypeDeclaration baseType,
CodeTypeDeclaration derivedType,
CodeMemberMethod buildMethod,
CodeMemberMethod dataBindingMethod) {
}
private sealed class NullParseRecorder : ParseRecorder {
}
private sealed class ParseRecorderList : ParseRecorder {
private readonly IEnumerable<ParseRecorder> _recorders;
internal ParseRecorderList(IEnumerable<ParseRecorder> recorders) {
_recorders = recorders;
}
public override void Initialize(TemplateParser parser) {
foreach (ParseRecorder recorder in _recorders) {
recorder.Initialize(parser);
}
}
public override void RecordBeginTag(ControlBuilder builder, Match tag) {
foreach (ParseRecorder recorder in _recorders) {
recorder.RecordBeginTag(builder, tag);
}
}
public override void RecordEndTag(ControlBuilder builder, Match tag) {
foreach (ParseRecorder recorder in _recorders) {
recorder.RecordEndTag(builder, tag);
}
}
public override void RecordEmptyTag(ControlBuilder builder, Match tag) {
foreach (ParseRecorder recorder in _recorders) {
recorder.RecordEmptyTag(builder, tag);
}
}
public override void RecordCodeBlock(ControlBuilder builder, Match codeBlock) {
foreach (ParseRecorder recorder in _recorders) {
recorder.RecordCodeBlock(builder, codeBlock);
}
}
public override void ParseComplete(ControlBuilder root) {
foreach (ParseRecorder recorder in _recorders) {
recorder.ParseComplete(root);
}
}
public override void ProcessGeneratedCode(ControlBuilder builder, CodeCompileUnit codeCompileUnit, CodeTypeDeclaration baseType, CodeTypeDeclaration derivedType, CodeMemberMethod buildMethod, CodeMemberMethod dataBindingMethod) {
foreach (ParseRecorder recorder in _recorders) {
recorder.ProcessGeneratedCode(builder, codeCompileUnit, baseType, derivedType, buildMethod, dataBindingMethod);
}
}
}
}
}
|