56
58
return proj.GetCodebehindTypeName (file.Name);
59
public static System.CodeDom.CodeCompileUnit GenerateCodeBehind (
60
AspNetAppProject aspProject, AspNetParsedDocument parsedDocument, List<CodeBehindWarning> errors)
62
string className = parsedDocument.PageInfo.InheritedClass;
64
//initialising this list may generate more errors so we do it here
65
MemberListVisitor memberList = null;
66
if (!string.IsNullOrEmpty (className))
67
memberList = parsedDocument.Document.MemberList;
70
if (parsedDocument.Document.ParseErrors.Count > 0) {
71
foreach (Exception e in parsedDocument.Document.ParseErrors) {
72
CodeBehindWarning cbw;
73
ErrorInFileException eife = e as ErrorInFileException;
75
cbw = new CodeBehindWarning (eife);
77
cbw = new CodeBehindWarning (
78
GettextCatalog.GetString ("Parser failed with error {0}. CodeBehind members for this file will not be added.", e.ToString ()),
79
parsedDocument.FileName);
61
static void AddFail (List<CodeBehindWarning> errors, AspNetParsedDocument document, Error err)
63
errors.Add (new CodeBehindWarning (GettextCatalog.GetString (
64
"Parser failed with error {0}. CodeBehind members for this file will not be added.", err.Message),
65
document.FileName, err.Region.Start.Line, err.Region.Start.Column));
68
public static System.CodeDom.CodeCompileUnit GenerateCodeBehind (AspNetAppProject project,
70
AspNetParsedDocument document,
71
List<CodeBehindWarning> errors)
73
string className = document.Info.InheritedClass;
75
if (document.HasErrors) {
76
AddFail (errors, document, document.Errors.Where (x => x.ErrorType == ErrorType.Error).First ());
84
80
if (string.IsNullOrEmpty (className))
83
var refman = new DocumentReferenceManager (project) { Doc = document };
84
var memberList = new MemberListVisitor (document, refman);
85
document.RootNode.AcceptVisit (memberList);
87
var err = memberList.Errors.Where (x => x.ErrorType == ErrorType.Error).FirstOrDefault ();
89
AddFail (errors, document, err);
87
93
//initialise the generated type
88
System.CodeDom.CodeCompileUnit ccu = new System.CodeDom.CodeCompileUnit ();
89
System.CodeDom.CodeNamespace namespac = new System.CodeDom.CodeNamespace ();
94
var ccu = new CodeCompileUnit ();
95
var namespac = new CodeNamespace ();
90
96
ccu.Namespaces.Add (namespac);
91
System.CodeDom.CodeTypeDeclaration typeDecl = new System.CodeDom.CodeTypeDeclaration ();
92
typeDecl.IsClass = true;
93
typeDecl.IsPartial = true;
97
var typeDecl = new System.CodeDom.CodeTypeDeclaration () {
94
101
namespac.Types.Add (typeDecl);
96
103
//name the class and namespace
97
104
int namespaceSplit = className.LastIndexOf ('.');
98
105
string namespaceName = null;
99
106
if (namespaceSplit > -1) {
100
namespac.Name = aspProject.StripImplicitNamespace (className.Substring (0, namespaceSplit));
107
namespac.Name = project.StripImplicitNamespace (className.Substring (0, namespaceSplit));
101
108
typeDecl.Name = className.Substring (namespaceSplit + 1);
103
110
typeDecl.Name = className;
106
113
string masterTypeName = null;
107
if (!String.IsNullOrEmpty (parsedDocument.PageInfo.MasterPageTypeName)) {
108
masterTypeName = parsedDocument.PageInfo.MasterPageTypeName;
109
} else if (!String.IsNullOrEmpty (parsedDocument.PageInfo.MasterPageTypeVPath)) {
114
if (!String.IsNullOrEmpty (document.Info.MasterPageTypeName)) {
115
masterTypeName = document.Info.MasterPageTypeName;
116
} else if (!String.IsNullOrEmpty (document.Info.MasterPageTypeVPath)) {
111
ProjectFile resolvedMaster = aspProject.ResolveVirtualPath (parsedDocument.PageInfo.MasterPageTypeVPath, parsedDocument.FileName);
118
ProjectFile resolvedMaster = project.ResolveVirtualPath (document.Info.MasterPageTypeVPath, document.FileName);
112
119
AspNetParsedDocument masterParsedDocument = null;
113
120
if (resolvedMaster != null)
114
masterParsedDocument = ProjectDomService.Parse (aspProject, resolvedMaster.FilePath, null) as AspNetParsedDocument;
115
if (masterParsedDocument != null && !String.IsNullOrEmpty (masterParsedDocument.PageInfo.InheritedClass)) {
116
masterTypeName = masterParsedDocument.PageInfo.InheritedClass;
121
masterParsedDocument = ProjectDomService.Parse (project, resolvedMaster.FilePath, null) as AspNetParsedDocument;
122
if (masterParsedDocument != null && !String.IsNullOrEmpty (masterParsedDocument.Info.InheritedClass)) {
123
masterTypeName = masterParsedDocument.Info.InheritedClass;
118
125
errors.Add (new CodeBehindWarning (String.Format ("Could not find type for master '{0}'",
119
parsedDocument.PageInfo.MasterPageTypeVPath),
120
parsedDocument.FileName));
126
document.Info.MasterPageTypeVPath),
122
129
} catch (Exception ex) {
123
130
errors.Add (new CodeBehindWarning (String.Format ("Could not find type for master '{0}'",
124
parsedDocument.PageInfo.MasterPageTypeVPath),
125
parsedDocument.FileName));
131
document.Info.MasterPageTypeVPath),
126
133
LoggingService.LogWarning ("Error resolving master page type", ex);
130
137
if (masterTypeName != null) {
131
System.CodeDom.CodeMemberProperty masterProp = new System.CodeDom.CodeMemberProperty ();
132
masterProp.Name = "Master";
133
masterProp.Type = new System.CodeDom.CodeTypeReference (masterTypeName);
134
masterProp.HasGet = true;
135
masterProp.HasSet = false;
136
masterProp.Attributes = System.CodeDom.MemberAttributes.Public | System.CodeDom.MemberAttributes.New
137
| System.CodeDom.MemberAttributes.Final;
138
var masterProp = new CodeMemberProperty () {
140
Type = new CodeTypeReference (masterTypeName),
143
Attributes = System.CodeDom.MemberAttributes.Public | System.CodeDom.MemberAttributes.New
144
| System.CodeDom.MemberAttributes.Final,
138
146
masterProp.GetStatements.Add (new System.CodeDom.CodeMethodReturnStatement (
139
147
new System.CodeDom.CodeCastExpression (masterTypeName,
140
148
new System.CodeDom.CodePropertyReferenceExpression (
142
150
typeDecl.Members.Add (masterProp);
153
//shortcut building the existing members type map
154
if (memberList.Members.Count == 0)
157
var dom = refman.TypeCtx.ProjectDom;
158
var cls = dom.GetType (className);
159
var members = GetDesignerMembers (memberList.Members.Values, cls, filename, dom, dom);
145
161
//add fields for each control in the page
146
foreach (System.CodeDom.CodeMemberField member in memberList.Members.Values)
147
typeDecl.Members.Add (member);
163
foreach (var member in members) {
164
var type = new CodeTypeReference (member.Type.FullName);
165
typeDecl.Members.Add (new CodeMemberField (type, member.Name) { Attributes = MemberAttributes.Family });
170
/// <summary>Filters out members whose names conflict with existing accessible members</summary>
171
/// <param name="members">Full list of CodeBehind members</param>
172
/// <param name="cls">The class to which these members' partial class will be added.</param>
173
/// <param name="designerFile">Members in this file will be ignored.</param>
174
/// <param name="resolveDom">The ProjectDom to use for resolving base types.</param>
175
/// <param name="internalDom">The ProjectDom to use for checking whether members are accessible as internal.</param>
176
/// <returns>The filtered list of non-conflicting members.</returns>
177
// TODO: check compatibilty with existing members
178
public static IEnumerable<CodeBehindMember> GetDesignerMembers (
179
IEnumerable<CodeBehindMember> members, IType cls, string designerFile, ProjectDom resolveDom,
180
ProjectDom internalDom)
182
var existingMembers = new HashSet<string> ();
183
while (cls != null) {
184
foreach (var member in cls.Members) {
185
if (member.IsPrivate || (member.IsInternal && member.DeclaringType.SourceProjectDom != internalDom))
187
if (member.DeclaringType.CompilationUnit.FileName == designerFile)
189
existingMembers.Add (member.Name);
191
if (cls.BaseType == null)
193
cls = resolveDom.GetType (cls.BaseType);
195
return members.Where (m => !existingMembers.Contains (m.Name));