~halega/+junk/sharpdevelop

« back to all changes in this revision

Viewing changes to src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/CompoundClass.cs

  • Committer: sk
  • Date: 2011-09-10 05:17:57 UTC
  • Revision ID: halega@halega.com-20110910051757-qfouz1llya9m6boy
4.1.0.7915 Release Candidate 1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
 
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
 
3
 
 
4
using System;
 
5
using System.Collections.Generic;
 
6
using System.Collections.ObjectModel;
 
7
using System.Linq;
 
8
using System.Diagnostics;
 
9
 
 
10
namespace ICSharpCode.SharpDevelop.Dom
 
11
{
 
12
        /// <summary>
 
13
        /// A class made up of multiple partial classes.
 
14
        /// 
 
15
        /// CompoundClass is immutable, it freezes the underlying DefaultClass in the constructor.
 
16
        /// The constructor also freezes all parts to ensure that the methods/properties/fields/events of a
 
17
        /// CompoundClass never change.
 
18
        /// When you want to build add or remove parts from a CompoundClass, you need to create a new
 
19
        /// CompoundClass instance with the new parts.
 
20
        /// </summary>
 
21
        public sealed class CompoundClass : DefaultClass
 
22
        {
 
23
                /// <summary>
 
24
                /// The parts this class is based on.
 
25
                /// </summary>
 
26
                readonly ReadOnlyCollection<IClass> parts;
 
27
                
 
28
                /// <summary>
 
29
                /// Gets the parts this class is based on.
 
30
                /// </summary>
 
31
                public ReadOnlyCollection<IClass> Parts {
 
32
                        get {
 
33
                                return parts;
 
34
                        }
 
35
                }
 
36
                
 
37
                /// <summary>
 
38
                /// Creates a new CompoundClass with the specified parts.
 
39
                /// </summary>
 
40
                public static CompoundClass Create(IEnumerable<IClass> parts)
 
41
                {
 
42
                        // Ensure that the list of parts does not change.
 
43
                        var p = parts.ToList();
 
44
                        foreach (IClass c in p) {
 
45
                                c.Freeze();
 
46
                        }
 
47
                        return new CompoundClass(p);
 
48
                }
 
49
                
 
50
                private CompoundClass(List<IClass> parts) : base(new DefaultCompilationUnit(parts[0].ProjectContent), parts[0].FullyQualifiedName)
 
51
                {
 
52
                        this.CompilationUnit.Classes.Add(this);
 
53
                        
 
54
                        this.parts = parts.AsReadOnly();
 
55
                        
 
56
                        UpdateInformationFromParts();
 
57
                        this.CompilationUnit.Freeze();
 
58
                        Debug.Assert(this.IsFrozen);
 
59
                }
 
60
                
 
61
                /// <summary>
 
62
                /// Calculate information from class parts (Modifier, Base classes, Type parameters etc.)
 
63
                /// </summary>
 
64
                void UpdateInformationFromParts()
 
65
                {
 
66
                        // Common for all parts:
 
67
                        this.ClassType = parts[0].ClassType;
 
68
                        
 
69
                        ModifierEnum modifier = ModifierEnum.None;
 
70
                        const ModifierEnum defaultClassVisibility = ModifierEnum.Internal;
 
71
                        
 
72
                        this.BaseTypes.Clear();
 
73
                        this.InnerClasses.Clear();
 
74
                        this.Attributes.Clear();
 
75
                        this.Methods.Clear();
 
76
                        this.Properties.Clear();
 
77
                        this.Events.Clear();
 
78
                        this.Fields.Clear();
 
79
                        
 
80
                        string shortestFileName = null;
 
81
                        
 
82
                        foreach (IClass part in parts) {
 
83
                                if (!string.IsNullOrEmpty(part.CompilationUnit.FileName)) {
 
84
                                        if (shortestFileName == null || part.CompilationUnit.FileName.Length < shortestFileName.Length) {
 
85
                                                shortestFileName = part.CompilationUnit.FileName;
 
86
                                                this.Region = part.Region;
 
87
                                        }
 
88
                                }
 
89
                                
 
90
                                if ((part.Modifiers & ModifierEnum.VisibilityMask) != defaultClassVisibility) {
 
91
                                        modifier |= part.Modifiers;
 
92
                                } else {
 
93
                                        modifier |= part.Modifiers &~ ModifierEnum.VisibilityMask;
 
94
                                }
 
95
                                foreach (IReturnType rt in part.BaseTypes) {
 
96
                                        if (!rt.IsDefaultReturnType || rt.FullyQualifiedName != "System.Object") {
 
97
                                                this.BaseTypes.Add(rt);
 
98
                                        }
 
99
                                }
 
100
                                this.InnerClasses.AddRange(part.InnerClasses);
 
101
                                this.Attributes.AddRange(part.Attributes);
 
102
                                this.Methods.AddRange(part.Methods);
 
103
                                this.Properties.AddRange(part.Properties);
 
104
                                this.Events.AddRange(part.Events);
 
105
                                this.Fields.AddRange(part.Fields);
 
106
                                
 
107
                                this.AddDefaultConstructorIfRequired |= part.AddDefaultConstructorIfRequired;
 
108
                        }
 
109
                        this.CompilationUnit.FileName = shortestFileName;
 
110
                        if ((modifier & ModifierEnum.VisibilityMask) == ModifierEnum.None) {
 
111
                                modifier |= defaultClassVisibility;
 
112
                        }
 
113
                        this.Modifiers = modifier;
 
114
                }
 
115
                
 
116
                /// <summary>
 
117
                /// Type parameters are the same on all parts.
 
118
                /// </summary>
 
119
                public override IList<ITypeParameter> TypeParameters {
 
120
                        get {
 
121
                                // Locking for the time of getting the reference to the sub-list is sufficient:
 
122
                                // Classes used for parts never change, instead the whole part is replaced with
 
123
                                // a new IClass instance.
 
124
                                return parts[0].TypeParameters;
 
125
                        }
 
126
                        set {
 
127
                                throw new NotSupportedException();
 
128
                        }
 
129
                }
 
130
        }
 
131
}