~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/addins/AspNet/MonoDevelop.AspNet/MonoDevelop.AspNet/CodeBehind.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2010-07-05 13:00:05 UTC
  • mfrom: (1.2.8 upstream) (1.3.9 experimental)
  • Revision ID: james.westby@ubuntu.com-20100705130005-d6hp4k5gcn1xkj8c
Tags: 2.4+dfsg-1ubuntu1
* debian/patches/remove_support_for_moonlight.patch,
  debian/patches/dont_add_moonlight_to_core_addins.patch,
  debian/control:
  + Enable support for Moonlight
* debian/rules:
  + Ensure Moonlight addin isn't shipped in main MonoDevelop package by
    mistake

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
//
31
31
 
32
32
using System;
 
33
using System.Linq;
33
34
using System.IO;
34
35
using System.Collections;
35
36
using System.Collections.Generic;
41
42
using MonoDevelop.DesignerSupport;
42
43
 
43
44
using MonoDevelop.AspNet.Parser;
 
45
using System.CodeDom;
44
46
 
45
47
namespace MonoDevelop.AspNet
46
48
{
56
58
                        return proj.GetCodebehindTypeName (file.Name);
57
59
                }
58
60
                
59
 
                public static System.CodeDom.CodeCompileUnit GenerateCodeBehind (
60
 
                        AspNetAppProject aspProject, AspNetParsedDocument parsedDocument, List<CodeBehindWarning> errors)
61
 
                {
62
 
                        string className = parsedDocument.PageInfo.InheritedClass;
63
 
                        
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;
68
 
                        
69
 
                        //log errors
70
 
                        if (parsedDocument.Document.ParseErrors.Count > 0) {
71
 
                                foreach (Exception e in parsedDocument.Document.ParseErrors) {
72
 
                                        CodeBehindWarning cbw;
73
 
                                        ErrorInFileException eife = e as ErrorInFileException;
74
 
                                        if (eife != null)
75
 
                                                cbw = new CodeBehindWarning (eife);
76
 
                                        else
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);
80
 
                                        errors.Add (cbw);
81
 
                                }
 
61
                static void AddFail (List<CodeBehindWarning> errors, AspNetParsedDocument document, Error err)
 
62
                {
 
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));
 
66
                }
 
67
                
 
68
                public static System.CodeDom.CodeCompileUnit GenerateCodeBehind (AspNetAppProject project,
 
69
                                                                                 string filename,
 
70
                                                                                 AspNetParsedDocument document, 
 
71
                                                                                 List<CodeBehindWarning> errors)
 
72
                {
 
73
                        string className = document.Info.InheritedClass;
 
74
                        
 
75
                        if (document.HasErrors) {
 
76
                                AddFail (errors, document, document.Errors.Where (x => x.ErrorType == ErrorType.Error).First ());
 
77
                                return null;
82
78
                        }
83
79
                        
84
80
                        if (string.IsNullOrEmpty (className))
85
81
                                return null;
86
82
                        
 
83
                        var refman = new DocumentReferenceManager (project) { Doc = document };
 
84
                        var memberList = new MemberListVisitor (document, refman);
 
85
                        document.RootNode.AcceptVisit (memberList);
 
86
                        
 
87
                        var err = memberList.Errors.Where (x => x.ErrorType == ErrorType.Error).FirstOrDefault ();
 
88
                        if (err != null) {
 
89
                                AddFail (errors, document, err);
 
90
                                return null;
 
91
                        }
 
92
                        
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 () {
 
98
                                IsClass = true,
 
99
                                IsPartial = true,
 
100
                        };
94
101
                        namespac.Types.Add (typeDecl);
95
102
                        
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);
102
109
                        } else {
103
110
                                typeDecl.Name = className;
104
111
                        }
105
112
                        
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)) {
110
117
                                try {
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;
117
124
                                        } else {
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),
 
127
                                                                                   document.FileName));
121
128
                                        }
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),
 
132
                                                                           document.FileName));
126
133
                                        LoggingService.LogWarning ("Error resolving master page type", ex);
127
134
                                }
128
135
                        }
129
136
                        
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 () {
 
139
                                        Name = "Master",
 
140
                                        Type = new CodeTypeReference (masterTypeName),
 
141
                                        HasGet = true,
 
142
                                        HasSet = false,
 
143
                                        Attributes = System.CodeDom.MemberAttributes.Public | System.CodeDom.MemberAttributes.New 
 
144
                                                | System.CodeDom.MemberAttributes.Final,
 
145
                                };
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);
143
151
                        }
144
152
                        
 
153
                        //shortcut building the existing members type map
 
154
                        if (memberList.Members.Count == 0)
 
155
                                return ccu;
 
156
                        
 
157
                        var dom = refman.TypeCtx.ProjectDom;
 
158
                        var cls = dom.GetType (className);
 
159
                        var members = GetDesignerMembers (memberList.Members.Values, cls, filename, dom, dom);
 
160
                        
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);
148
162
                        
 
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 });
 
166
                        }
149
167
                        return ccu;
150
168
                }
 
169
                
 
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)
 
181
                {
 
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))
 
186
                                            continue;
 
187
                                        if (member.DeclaringType.CompilationUnit.FileName == designerFile)
 
188
                                                continue;
 
189
                                        existingMembers.Add (member.Name);
 
190
                                }
 
191
                                if (cls.BaseType == null)
 
192
                                        break;
 
193
                                cls = resolveDom.GetType (cls.BaseType);
 
194
                        }
 
195
                        return members.Where (m => !existingMembers.Contains (m.Name));
 
196
                }
151
197
        }
152
198
}