Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.Entity.Design / System / Data / EntityModel / Emitters / PropertyEmitterBase.cs
1 //---------------------------------------------------------------------
2 // <copyright file="PropertyEmitterBase.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner       Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9
10 using System;
11 using System.CodeDom;
12 using System.Collections.Generic;
13 using System.Data.Metadata.Edm;
14 using System.Diagnostics;
15 using System.Data.Entity.Design.SsdlGenerator;
16 using System.Data.Entity.Design.Common;
17
18 namespace System.Data.EntityModel.Emitters
19 {
20     internal abstract class PropertyEmitterBase : MetadataItemEmitter
21     {
22         private bool _declaringTypeUsesStandardBaseType;
23         protected PropertyEmitterBase(ClientApiGenerator generator, MetadataItem item, bool declaringTypeUsesStandardBaseType)
24             :base(generator, item)
25         {
26             Debug.Assert(item != null, "item is null");
27             _declaringTypeUsesStandardBaseType = declaringTypeUsesStandardBaseType;
28         }
29
30         /// <summary>
31         /// This is where the derived classes supply their emit logic.
32         /// </summary>
33         /// <param name="typeDecl">The CodeDom representation of the type that the property is being added to.</param>
34         protected abstract void EmitProperty(CodeTypeDeclaration typeDecl);
35
36         /// <summary>
37         /// Validation logic specific to property emitters
38         /// </summary>
39         protected override void Validate()
40         {
41             VerifyGetterAndSetterAccessibilityCompatability();
42             Generator.VerifyLanguageCaseSensitiveCompatibilityForProperty(Item as EdmMember);
43         }
44
45         /// <summary>
46         /// The compiler ensures accessibility on a Setter/Getter is more restrictive than on the Property.
47         /// However accessibility modifiers are not well ordered. Internal and Protected don't go well together 
48         /// because neither is more restrictive than others.
49         /// </summary>
50         private void VerifyGetterAndSetterAccessibilityCompatability()
51         {
52             if (PropertyEmitter.GetGetterAccessibility(Item) == MemberAttributes.Assembly
53                         && PropertyEmitter.GetSetterAccessibility(Item) == MemberAttributes.Family)
54             {
55                 Generator.AddError(System.Data.Entity.Design.Strings.GeneratedPropertyAccessibilityConflict(Item.Name, "Internal", "Protected"),
56                         ModelBuilderErrorCode.GeneratedPropertyAccessibilityConflict,
57                         EdmSchemaErrorSeverity.Error, Item.DeclaringType.FullName, Item.Name);
58             }
59             else if (PropertyEmitter.GetGetterAccessibility(Item) == MemberAttributes.Family
60                         && PropertyEmitter.GetSetterAccessibility(Item) == MemberAttributes.Assembly)
61             {
62                 Generator.AddError(System.Data.Entity.Design.Strings.GeneratedPropertyAccessibilityConflict(Item.Name, "Protected", "Internal"),
63                         ModelBuilderErrorCode.GeneratedPropertyAccessibilityConflict,
64                         EdmSchemaErrorSeverity.Error, Item.DeclaringType.FullName, Item.Name);
65             }
66         }
67
68
69
70         /// <summary>
71         /// Main method for Emitting property code.
72         /// </summary>
73         /// <param name="typeDecl">The CodeDom representation of the type that the property is being added to.</param>
74         public void Emit(CodeTypeDeclaration typeDecl)
75         {
76             Validate();
77             EmitProperty(typeDecl);
78         }
79
80         protected bool AncestorClassDefinesName(string name)
81         {
82             if (_declaringTypeUsesStandardBaseType && Utils.DoesTypeReserveMemberName(Item.DeclaringType, name, Generator.LanguageAppropriateStringComparer))
83             {
84                 return true;
85             }
86             
87             StructuralType baseType = Item.DeclaringType.BaseType as StructuralType;
88             if (baseType != null && baseType.Members.Contains(name))
89             {
90                 return true;
91             }
92
93             return false;
94         }
95
96         public new EdmMember Item
97         {
98             get
99             {
100                 return base.Item as EdmMember;
101             }
102         }
103
104     }
105 }