-
Notifications
You must be signed in to change notification settings - Fork 365
/
MemberIDFixUpPlugIn.cs
153 lines (131 loc) · 6.68 KB
/
MemberIDFixUpPlugIn.cs
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
//===============================================================================================================
// System : Sandcastle Help File Builder Plug-Ins
// File : MemberIdFixUpPlugIn.cs
// Author : Eric Woodruff (Eric@EWoodruff.us)
// Updated : 05/16/2021
// Note : Copyright 2014-2021, Eric Woodruff, All rights reserved
//
// This file contains a plug-in that is used to fix up member IDs in the XML comments files due to quirks in
// the various compilers that cause a mismatch between the member IDs in the XML comments and the reflection
// data.
//
// This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be
// distributed with the code and can be found at the project website: https://GitHub.com/EWSoftware/SHFB. This
// notice, the author's name, and all copyright notices must remain intact in all applications, documentation,
// and source files.
//
// Date Who Comments
// =====================================================================================================
// 11/14/2014 EFW Created the code
//===============================================================================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using SandcastleBuilder.Utils;
using SandcastleBuilder.Utils.BuildComponent;
using SandcastleBuilder.Utils.BuildEngine;
namespace SandcastleBuilder.PlugIns
{
/// <summary>
/// This plug-in class is used to fix up member IDs in the XML comments files due to quirks in the various
/// compilers that cause a mismatch between the member IDs in the XML comments and the reflection data.
/// </summary>
[HelpFileBuilderPlugInExport("Member ID Fix-Ups", RunsInPartialBuild = true,
Version = AssemblyInfo.ProductVersion, Copyright = AssemblyInfo.Copyright,
Description = "This plug-in is used to fix up member IDs in the XML comments files due to quirks in " +
"the various compilers that cause a mismatch between the member IDs in the XML comments and the " +
"reflection data.")]
public sealed class MemberIdFixUpPlugIn : IPlugIn
{
#region Private data members
//=====================================================================
private List<ExecutionPoint> executionPoints;
private BuildProcess builder;
private List<MemberIdMatchExpression> expressions;
#endregion
#region IPlugIn implementation
//=====================================================================
/// <summary>
/// This read-only property returns a collection of execution points that define when the plug-in should
/// be invoked during the build process.
/// </summary>
public IEnumerable<ExecutionPoint> ExecutionPoints
{
get
{
if(executionPoints == null)
executionPoints = new List<ExecutionPoint>
{
// This one has a lower priority as it fixes stuff that the other plug-ins might add
new ExecutionPoint(BuildStep.ValidatingDocumentationSources, ExecutionBehaviors.After, 100)
};
return executionPoints;
}
}
/// <summary>
/// This method is used to initialize the plug-in at the start of the build process
/// </summary>
/// <param name="buildProcess">A reference to the current build process</param>
/// <param name="configuration">The configuration data that the plug-in should use to initialize itself</param>
public void Initialize(BuildProcess buildProcess, XElement configuration)
{
if(configuration == null)
throw new ArgumentNullException(nameof(configuration));
builder = buildProcess;
var metadata = (HelpFileBuilderPlugInExportAttribute)this.GetType().GetCustomAttributes(
typeof(HelpFileBuilderPlugInExportAttribute), false).First();
builder.ReportProgress("{0} Version {1}\r\n{2}", metadata.Id, metadata.Version, metadata.Copyright);
expressions = new List<MemberIdMatchExpression>();
foreach(var expr in configuration.Descendants("expression"))
expressions.Add(new MemberIdMatchExpression
{
MatchExpression = expr.Attribute("matchExpression").Value,
ReplacementValue = expr.Attribute("replacementValue").Value,
MatchAsRegEx = (bool)expr.Attribute("matchAsRegEx")
});
if(expressions.Count == 0)
{
throw new BuilderException("MNF0001", "No fix-up expressions have been defined for the Member " +
"Name Fix-Up plug-in");
}
}
/// <summary>
/// This method is used to execute the plug-in during the build process
/// </summary>
/// <param name="context">The current execution context</param>
public void Execute(ExecutionContext context)
{
builder.ReportProgress("Fixing up member IDs in comments...");
foreach(var commentsFile in builder.CommentsFiles)
{
// Use the instance to get the comments in case changes were made elsewhere and not save yet
string content = commentsFile.Comments.OuterXml;
foreach(var matchExpr in expressions)
if(matchExpr.MatchAsRegEx)
content = matchExpr.RegularExpression.Replace(content, matchExpr.ReplacementValue);
else
content = content.Replace(matchExpr.MatchExpression, matchExpr.ReplacementValue);
using(StreamWriter sw = new StreamWriter(commentsFile.SourcePath, false, commentsFile.Encoding))
{
sw.Write(content);
}
// Force a reload so that any further references to the content get our updated content
commentsFile.ForceReload();
}
}
#endregion
#region IDisposable implementation
//=====================================================================
/// <summary>
/// This implements the Dispose() interface to properly dispose of the plug-in object
/// </summary>
public void Dispose()
{
// Nothing to dispose of in this one
GC.SuppressFinalize(this);
}
#endregion
}
}