35
35
// This includes properties, indexers, and events
36
36
public abstract class PropertyBasedMember : InterfaceMemberBase
38
public PropertyBasedMember (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
38
protected PropertyBasedMember (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
39
39
: base (parent, type, mod, allowed_mod, name, attrs)
206
208
method_data = new MethodData (method, ModFlags, flags, this);
208
if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
211
method_data.DefineMethodBuilder (parent.PartialContainer, ParameterInfo);
213
return method_data.MethodBuilder;
210
method_data.Define (parent.PartialContainer, method.GetFullName (MemberName));
216
213
public override TypeSpec ReturnType {
273
270
method_data = new MethodData (method, ModFlags, flags, this);
275
if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
278
method_data.DefineMethodBuilder (parent.PartialContainer, ParameterInfo);
280
return method_data.MethodBuilder;
272
method_data.Define (parent.PartialContainer, method.GetFullName (MemberName));
283
275
public override TypeSpec ReturnType {
408
398
PropertyMethod get, set, first;
409
399
PropertyBuilder PropertyBuilder;
411
public PropertyBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, Modifiers allowed_mod, MemberName name, Attributes attrs)
401
protected PropertyBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, Modifiers allowed_mod, MemberName name, Attributes attrs)
412
402
: base (parent, type, mod_flags, allowed_mod, name, attrs)
522
512
// Check base property accessors conflict
524
514
var base_prop = (PropertySpec) base_member;
516
if ((ModFlags & Modifiers.SEALED) != 0 && base_prop.HasGet && !base_prop.Get.IsAccessible (this)) {
517
// TODO: Should be different error code but csc uses for some reason same
518
Report.SymbolRelatedToPreviousError (base_prop);
519
Report.Error (545, Location,
520
"`{0}': cannot override because `{1}' does not have accessible get accessor",
521
GetSignatureForError (), base_prop.GetSignatureForError ());
526
525
if (!base_prop.HasGet) {
528
527
Report.SymbolRelatedToPreviousError (base_prop);
542
if ((ModFlags & Modifiers.SEALED) != 0 && base_prop.HasSet && !base_prop.Set.IsAccessible (this)) {
543
// TODO: Should be different error code but csc uses for some reason same
544
Report.SymbolRelatedToPreviousError (base_prop);
545
Report.Error (546, Location,
546
"`{0}': cannot override because `{1}' does not have accessible set accessor",
547
GetSignatureForError (), base_prop.GetSignatureForError ());
543
551
if (!base_prop.HasSet) {
545
553
Report.SymbolRelatedToPreviousError (base_prop);
625
633
if (Get != null) {
626
634
spec.Get = Get.Spec;
628
var method = Get.Spec.GetMetaInfo () as MethodBuilder;
629
if (method != null) {
630
PropertyBuilder.SetGetMethod (method);
631
Parent.MemberCache.AddMember (this, method.Name, Get.Spec);
635
Parent.MemberCache.AddMember (this, Get.Spec.Name, Get.Spec);
634
637
CheckMissingAccessor (kind, parameters, true);
637
640
if (Set != null) {
638
641
spec.Set = Set.Spec;
640
var method = Set.Spec.GetMetaInfo () as MethodBuilder;
641
if (method != null) {
642
PropertyBuilder.SetSetMethod (method);
643
Parent.MemberCache.AddMember (this, method.Name, Set.Spec);
642
Parent.MemberCache.AddMember (this, Set.Spec.Name, Set.Spec);
646
644
CheckMissingAccessor (kind, parameters, false);
682
public override void PrepareEmit ()
684
AccessorFirst.PrepareEmit ();
685
if (AccessorSecond != null)
686
AccessorSecond.PrepareEmit ();
689
var method = Get.Spec.GetMetaInfo () as MethodBuilder;
691
PropertyBuilder.SetGetMethod (method);
695
var method = Set.Spec.GetMetaInfo () as MethodBuilder;
697
PropertyBuilder.SetSetMethod (method);
684
701
protected override void SetMemberName (MemberName new_name)
686
703
base.SetMemberName (new_name);
714
731
public sealed class BackingField : Field
716
733
readonly Property property;
734
const Modifiers DefaultModifiers = Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | Modifiers.DEBUGGER_HIDDEN;
718
public BackingField (Property p)
719
: base (p.Parent, p.type_expr,
720
Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (p.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
736
public BackingField (Property p, bool readOnly)
737
: base (p.Parent, p.type_expr, DefaultModifiers | (p.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
721
738
new MemberName ("<" + p.GetFullName (p.MemberName) + ">k__BackingField", p.Location), null)
723
740
this.property = p;
742
ModFlags |= Modifiers.READONLY;
726
745
public Property OriginalProperty {
757
static readonly string[] attribute_target_auto = new string[] { "property", "field" };
738
761
public Property (TypeDefinition parent, FullNamedExpression type, Modifiers mod,
739
762
MemberName name, Attributes attrs)
740
763
: base (parent, type, mod,
771
public Expression Initializer { get; set; }
748
773
public override void Accept (StructuralVisitor visitor)
750
775
visitor.Visit (this);
778
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
780
if (a.Target == AttributeTargets.Field) {
781
backing_field.ApplyAttributeBuilder (a, ctor, cdata, pa);
785
base.ApplyAttributeBuilder (a, ctor, cdata, pa);
754
788
void CreateAutomaticProperty ()
756
790
// Create backing field
757
Field field = new BackingField (this);
758
if (!field.Define ())
791
backing_field = new BackingField (this, Initializer != null && Set == null);
792
if (!backing_field.Define ())
761
Parent.PartialContainer.Members.Add (field);
763
FieldExpr fe = new FieldExpr (field, Location);
764
if ((field.ModFlags & Modifiers.STATIC) == 0)
795
if (Initializer != null) {
796
backing_field.Initializer = Initializer;
797
Parent.RegisterFieldForInitialization (backing_field, new FieldInitializer (backing_field, Initializer, Location));
798
backing_field.ModFlags |= Modifiers.READONLY;
801
Parent.PartialContainer.Members.Add (backing_field);
803
FieldExpr fe = new FieldExpr (backing_field, Location);
804
if ((backing_field.ModFlags & Modifiers.STATIC) == 0)
765
805
fe.InstanceExpression = new CompilerGeneratedThis (Parent.CurrentType, Location);
772
812
Get.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location.Null);
773
813
Return r = new Return (fe, Get.Location);
774
814
Get.Block.AddStatement (r);
815
Get.ModFlags |= Modifiers.COMPILER_GENERATED;
776
817
// Create set block
777
Set.Block = new ToplevelBlock (Compiler, Set.ParameterInfo, Location.Null);
778
Assign a = new SimpleAssign (fe, new SimpleName ("value", Location.Null), Location.Null);
779
Set.Block.AddStatement (new StatementExpression (a, Set.Location));
782
public override bool Define ()
787
flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
789
if (!IsInterface && (ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
790
AccessorSecond != null && Get.Block == null && Set.Block == null) {
791
if (Compiler.Settings.Version <= LanguageVersion.ISO_2)
792
Report.FeatureIsNotAvailable (Compiler, Location, "automatically implemented properties");
794
Get.ModFlags |= Modifiers.COMPILER_GENERATED;
819
Set.Block = new ToplevelBlock (Compiler, Set.ParameterInfo, Location.Null);
820
Assign a = new SimpleAssign (fe, new SimpleName ("value", Location.Null), Location.Null);
821
Set.Block.AddStatement (new StatementExpression (a, Set.Location));
795
822
Set.ModFlags |= Modifiers.COMPILER_GENERATED;
826
public override bool Define ()
831
flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
833
bool auto = AccessorFirst.Block == null && (AccessorSecond == null || AccessorSecond.Block == null) &&
834
(ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0;
836
if (Initializer != null) {
838
Report.Error (8050, Location, "`{0}': Only auto-implemented properties can have initializers",
839
GetSignatureForError ());
842
Report.Error (8053, Location, "`{0}': Properties inside interfaces cannot have initializers",
843
GetSignatureForError ());
845
if (Compiler.Settings.Version < LanguageVersion.V_6)
846
Report.FeatureIsNotAvailable (Compiler, Location, "auto-implemented property initializer");
851
Report.Error (8052, Location, "Auto-implemented property `{0}' must have get accessor",
852
GetSignatureForError ());
856
if (Initializer == null && AccessorSecond == null) {
857
Report.Error (8051, Location, "Auto-implemented property `{0}' must have set accessor or initializer",
858
GetSignatureForError ());
861
if (Compiler.Settings.Version < LanguageVersion.V_3 && Initializer == null)
862
Report.FeatureIsNotAvailable (Compiler, Location, "auto-implemented properties");
796
864
CreateAutomaticProperty ();
966
1041
args.Add (new Argument (new LocalVariableReference (obj1, Location)));
968
var cas = Module.PredefinedMembers.InterlockedCompareExchange_T.Resolve (Location);
972
body.AddStatement (new StatementExpression (new SimpleAssign (
973
new LocalVariableReference (obj1, Location),
974
new Invocation (MethodGroupExpr.CreatePredefined (cas, cas.DeclaringType, Location), args))));
1043
var cas = Module.PredefinedMembers.InterlockedCompareExchange_T.Get ();
1045
if (Module.PredefinedMembers.MonitorEnter_v4.Get () != null || Module.PredefinedMembers.MonitorEnter.Get () != null) {
1046
// Workaround for cripled (e.g. microframework) mscorlib without CompareExchange
1047
body.AddStatement (new Lock (
1048
block.GetParameterReference (0, Location),
1049
new StatementExpression (new SimpleAssign (
1050
f_expr, args [1].Expr, Location), Location), Location));
1052
Module.PredefinedMembers.InterlockedCompareExchange_T.Resolve (Location);
1055
body.AddStatement (new StatementExpression (new SimpleAssign (
1056
new LocalVariableReference (obj1, Location),
1057
new Invocation (MethodGroupExpr.CreatePredefined (cas, cas.DeclaringType, Location), args))));
1091
1175
if (declarators != null) {
1092
if ((mod_flags_src & Modifiers.DEFAULT_ACCESS_MODIFER) != 0)
1093
mod_flags_src &= ~(Modifiers.AccessibilityMask | Modifiers.DEFAULT_ACCESS_MODIFER);
1176
if ((mod_flags_src & Modifiers.DEFAULT_ACCESS_MODIFIER) != 0)
1177
mod_flags_src &= ~(Modifiers.AccessibilityMask | Modifiers.DEFAULT_ACCESS_MODIFIER);
1095
1179
var t = new TypeExpression (MemberType, TypeExpression.Location);
1096
1180
foreach (var d in declarators) {
1196
1277
method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
1198
1279
if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
1201
method_data.DefineMethodBuilder (parent.PartialContainer, ParameterInfo);
1203
1282
if (Compiler.Settings.WriteMetadataOnly)
1206
1285
Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, method.ModFlags);
1207
1286
Spec.IsAccessor = true;
1209
return method_data.MethodBuilder;
1212
1289
public override TypeSpec ReturnType {
1319
1402
// Now define the accessors
1321
var AddBuilder = Add.Define (Parent);
1322
if (AddBuilder == null)
1325
var RemoveBuilder = remove.Define (Parent);
1326
if (RemoveBuilder == null)
1404
add.Define (Parent);
1405
remove.Define (Parent);
1329
1407
EventBuilder = Parent.TypeBuilder.DefineEvent (GetFullName (MemberName), EventAttributes.None, MemberType.GetMetaInfo ());
1330
EventBuilder.SetAddOnMethod (AddBuilder);
1331
EventBuilder.SetRemoveOnMethod (RemoveBuilder);
1333
1409
spec = new EventSpec (Parent.Definition, this, MemberType, ModFlags, Add.Spec, remove.Spec);
1335
1411
Parent.MemberCache.AddMember (this, GetFullName (MemberName), spec);
1336
Parent.MemberCache.AddMember (this, AddBuilder.Name, Add.Spec);
1337
Parent.MemberCache.AddMember (this, RemoveBuilder.Name, remove.Spec);
1412
Parent.MemberCache.AddMember (this, Add.Spec.Name, Add.Spec);
1413
Parent.MemberCache.AddMember (this, Remove.Spec.Name, remove.Spec);
1704
public override List<TypeSpec> ResolveMissingDependencies ()
1789
public override List<MissingTypeSpecReference> ResolveMissingDependencies (MemberSpec caller)
1706
var missing = base.ResolveMissingDependencies ();
1791
var missing = base.ResolveMissingDependencies (caller);
1707
1793
foreach (var pt in parameters.Types) {
1708
var m = pt.GetMissingDependencies ();
1794
var m = pt.GetMissingDependencies (caller);
1712
1798
if (missing == null)
1713
missing = new List<TypeSpec> ();
1799
missing = new List<MissingTypeSpecReference> ();
1715
1801
missing.AddRange (m);