File: PropertyEmitterBase.cs

package info (click to toggle)
mono 4.6.2.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (105 lines) | stat: -rw-r--r-- 4,267 bytes parent folder | download
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
//---------------------------------------------------------------------
// <copyright file="PropertyEmitterBase.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//
// @owner       [....]
// @backupOwner [....]
//---------------------------------------------------------------------

using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Data.Metadata.Edm;
using System.Diagnostics;
using System.Data.Entity.Design.SsdlGenerator;
using System.Data.Entity.Design.Common;

namespace System.Data.EntityModel.Emitters
{
    internal abstract class PropertyEmitterBase : MetadataItemEmitter
    {
        private bool _declaringTypeUsesStandardBaseType;
        protected PropertyEmitterBase(ClientApiGenerator generator, MetadataItem item, bool declaringTypeUsesStandardBaseType)
            :base(generator, item)
        {
            Debug.Assert(item != null, "item is null");
            _declaringTypeUsesStandardBaseType = declaringTypeUsesStandardBaseType;
        }

        /// <summary>
        /// This is where the derived classes supply their emit logic.
        /// </summary>
        /// <param name="typeDecl">The CodeDom representation of the type that the property is being added to.</param>
        protected abstract void EmitProperty(CodeTypeDeclaration typeDecl);

        /// <summary>
        /// Validation logic specific to property emitters
        /// </summary>
        protected override void Validate()
        {
            VerifyGetterAndSetterAccessibilityCompatability();
            Generator.VerifyLanguageCaseSensitiveCompatibilityForProperty(Item as EdmMember);
        }

        /// <summary>
        /// The compiler ensures accessibility on a Setter/Getter is more restrictive than on the Property.
        /// However accessibility modifiers are not well ordered. Internal and Protected don't go well together 
        /// because neither is more restrictive than others.
        /// </summary>
        private void VerifyGetterAndSetterAccessibilityCompatability()
        {
            if (PropertyEmitter.GetGetterAccessibility(Item) == MemberAttributes.Assembly
                        && PropertyEmitter.GetSetterAccessibility(Item) == MemberAttributes.Family)
            {
                Generator.AddError(System.Data.Entity.Design.Strings.GeneratedPropertyAccessibilityConflict(Item.Name, "Internal", "Protected"),
                        ModelBuilderErrorCode.GeneratedPropertyAccessibilityConflict,
                        EdmSchemaErrorSeverity.Error, Item.DeclaringType.FullName, Item.Name);
            }
            else if (PropertyEmitter.GetGetterAccessibility(Item) == MemberAttributes.Family
                        && PropertyEmitter.GetSetterAccessibility(Item) == MemberAttributes.Assembly)
            {
                Generator.AddError(System.Data.Entity.Design.Strings.GeneratedPropertyAccessibilityConflict(Item.Name, "Protected", "Internal"),
                        ModelBuilderErrorCode.GeneratedPropertyAccessibilityConflict,
                        EdmSchemaErrorSeverity.Error, Item.DeclaringType.FullName, Item.Name);
            }
        }



        /// <summary>
        /// Main method for Emitting property code.
        /// </summary>
        /// <param name="typeDecl">The CodeDom representation of the type that the property is being added to.</param>
        public void Emit(CodeTypeDeclaration typeDecl)
        {
            Validate();
            EmitProperty(typeDecl);
        }

        protected bool AncestorClassDefinesName(string name)
        {
            if (_declaringTypeUsesStandardBaseType && Utils.DoesTypeReserveMemberName(Item.DeclaringType, name, Generator.LanguageAppropriateStringComparer))
            {
                return true;
            }
            
            StructuralType baseType = Item.DeclaringType.BaseType as StructuralType;
            if (baseType != null && baseType.Members.Contains(name))
            {
                return true;
            }

            return false;
        }

        public new EdmMember Item
        {
            get
            {
                return base.Item as EdmMember;
            }
        }

    }
}