+++ /dev/null
-// CS0573: `A.a': Structs cannot have instance field initializers
-// Line: 5
-
-partial struct A {
- int a = 1;
-}
+++ /dev/null
-// CS0573: `A.a': Structs cannot have instance field initializers
-// Line: 5
-struct A {
- int a = 1;
-}
-
-class D {
- static void Main ()
- {
- A [] a = new A [10];
-
- }
-}
+++ /dev/null
-// CS0840: `Test.Property.get' must have a body because it is not marked abstract or extern. The property can be automatically implemented when you define both accessors
-// Line: 7
-
-
-public abstract class Test
-{
- public string Property { get; }
-}
-// CS1644: Feature `automatically implemented properties' cannot be used because it is not part of the C# 2.0 language specification
+// CS1644: Feature `auto-implemented properties' cannot be used because it is not part of the C# 2.0 language specification
// Line: 7
// Compiler options: -langversion:ISO-2
--- /dev/null
+// CS1644: Feature `auto-implemented property initializer' cannot be used because it is not part of the C# 5.0 language specification
+// Line: 7
+// Compiler options: -langversion:5
+
+class C
+{
+ public static int P { get; } = 4;
+}
\ No newline at end of file
--- /dev/null
+// CS8050: `C.P': Only auto-implemented properties can have initializers
+// Line: 6
+
+abstract class C
+{
+ public abstract int P { get; } = 4;
+}
\ No newline at end of file
--- /dev/null
+// CS8051: Auto-implemented property `Test.Property' must have set accessor or initializer
+// Line: 6
+
+public abstract class Test
+{
+ public string Property { get; }
+}
--- /dev/null
+// CS8052: Auto-implemented property `V.P' must have get accessor
+// Line: 6
+
+class V
+{
+ public object P { set; } = 1;
+}
\ No newline at end of file
--- /dev/null
+// CS8053: `I.P': Properties inside interfaces cannot have initializers
+// Line: 6
+
+interface I
+{
+ int P { get; } = 4;
+}
\ No newline at end of file
--- /dev/null
+// CS0573: `A.a': Structs without explicit constructors cannot contain members with initializers
+// Line: 5
+
+partial struct A {
+ int a = 1;
+}
--- /dev/null
+// CS0573: `A.a': Structs without explicit constructors cannot contain members with initializers
+// Line: 5
+
+struct A {
+ int a = 1;
+}
--- /dev/null
+// CS8054: `S.P': Structs without explicit constructors cannot contain members with initializers
+// Line: 6
+
+struct S
+{
+ public decimal P { get; } = -3;
+}
\ No newline at end of file
base.Emit ();
}
+ bool HasExplicitConstructor ()
+ {
+ foreach (var m in Members) {
+ var c = m as Constructor;
+ if (c == null)
+ continue;
+
+ if (!c.ParameterInfo.IsEmpty)
+ return true;
+ }
+
+ return false;
+ }
+
public override bool IsUnmanagedType ()
{
if (has_unmanaged_check_done)
public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
{
- if ((field.ModFlags & Modifiers.STATIC) == 0) {
- Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
+ if ((field.ModFlags & Modifiers.STATIC) == 0 && !HasExplicitConstructor ()) {
+ Report.Error (8054, field.Location, "`{0}': Structs without explicit constructors cannot contain members with initializers",
field.GetSignatureForError ());
+
return;
}
+
base.RegisterFieldForInitialization (field, expression);
}
-
}
/// <summary>
report.Error (1669, GetLocation ($1), "__arglist is not valid in this context");
}
;
-
+
property_declaration
: opt_attributes
opt_modifiers
member_type
member_declaration_name
{
+ lexer.parsing_generic_declaration = false;
if (doc_support)
tmpComment = Lexer.consume_doc_comment ();
}
CLOSE_BRACE
{
lbag.AppendToMember (current_property, GetLocation ($10));
+ lexer.parsing_modifiers = true;
+ }
+ opt_property_initializer
+ {
current_property = null;
}
;
+opt_property_initializer
+ : /* empty */
+ | ASSIGN
+ {
+ ++lexer.parsing_block;
+ current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
+ start_block (GetLocation ($1));
+ }
+ expression SEMICOLON
+ {
+ --lexer.parsing_block;
+ ((Property)current_property).Initializer = (Expression) $3;
+ lbag.AppendToMember (current_property, GetLocation ($1), GetLocation ($4));
+ end_block (GetLocation ($4));
+ current_local_parameters = null;
+ }
+ ;
indexer_declaration
: opt_attributes opt_modifiers
var field = struct_info.Fields[i];
if (!fc.IsStructFieldDefinitelyAssigned (vi, field.Name)) {
- if (field.MemberDefinition is Property.BackingField) {
+ var bf = field.MemberDefinition as Property.BackingField;
+ if (bf != null) {
+ if (bf.Initializer != null)
+ continue;
+
fc.Report.Error (843, loc,
"An automatically implemented property `{0}' must be fully assigned before control leaves the constructor. Consider calling the default struct contructor from a constructor initializer",
field.GetSignatureForError ());
- } else {
- fc.Report.Error (171, loc,
- "Field `{0}' must be fully assigned before control leaves the constructor",
- field.GetSignatureForError ());
+
+ ok = false;
+ continue;
}
+
+ fc.Report.Error (171, loc,
+ "Field `{0}' must be fully assigned before control leaves the constructor",
+ field.GetSignatureForError ());
ok = false;
}
}
if (!fs.IsPublic && container.MemberDefinition.IsImported && (!fs.MemberType.IsArray && TypeSpec.IsReferenceType (fs.MemberType)))
continue;
+ //if ((fs.Modifiers & (Modifiers.BACKING_FIELD) != 0)
+ // continue;
+
if (fields == null)
fields = new List<FieldSpec> ();
{
readonly Property property;
- public BackingField (Property p)
+ public BackingField (Property p, bool readOnly)
: base (p.Parent, p.type_expr,
Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (p.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
new MemberName ("<" + p.GetFullName (p.MemberName) + ">k__BackingField", p.Location), null)
{
this.property = p;
+ if (readOnly)
+ ModFlags |= Modifiers.READONLY;
}
public Property OriginalProperty {
{
}
+ public Expression Initializer { get; set; }
+
public override void Accept (StructuralVisitor visitor)
{
visitor.Visit (this);
void CreateAutomaticProperty ()
{
// Create backing field
- backing_field = new BackingField (this);
+ backing_field = new BackingField (this, Initializer != null && Set == null);
if (!backing_field.Define ())
return;
+ if (Initializer != null) {
+ backing_field.Initializer = Initializer;
+ Parent.RegisterFieldForInitialization (backing_field, new FieldInitializer (backing_field, Initializer, Location));
+ backing_field.ModFlags |= Modifiers.READONLY;
+ }
+
Parent.PartialContainer.Members.Add (backing_field);
FieldExpr fe = new FieldExpr (backing_field, Location);
Get.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location.Null);
Return r = new Return (fe, Get.Location);
Get.Block.AddStatement (r);
+ Get.ModFlags |= Modifiers.COMPILER_GENERATED;
// Create set block
- Set.Block = new ToplevelBlock (Compiler, Set.ParameterInfo, Location.Null);
- Assign a = new SimpleAssign (fe, new SimpleName ("value", Location.Null), Location.Null);
- Set.Block.AddStatement (new StatementExpression (a, Set.Location));
+ if (Set != null) {
+ Set.Block = new ToplevelBlock (Compiler, Set.ParameterInfo, Location.Null);
+ Assign a = new SimpleAssign (fe, new SimpleName ("value", Location.Null), Location.Null);
+ Set.Block.AddStatement (new StatementExpression (a, Set.Location));
+ Set.ModFlags |= Modifiers.COMPILER_GENERATED;
+ }
}
public override bool Define ()
flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
- if (!IsInterface && (ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
- AccessorSecond != null && Get.Block == null && Set.Block == null) {
- if (Compiler.Settings.Version <= LanguageVersion.ISO_2)
- Report.FeatureIsNotAvailable (Compiler, Location, "automatically implemented properties");
+ bool auto = AccessorFirst.Block == null && (AccessorSecond == null || AccessorSecond.Block == null) &&
+ (ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0;
+
+ if (Initializer != null) {
+ if (!auto)
+ Report.Error (8050, Location, "`{0}': Only auto-implemented properties can have initializers",
+ GetSignatureForError ());
+
+ if (IsInterface)
+ Report.Error (8053, Location, "`{0}': Properties inside interfaces cannot have initializers",
+ GetSignatureForError ());
+
+ if (Compiler.Settings.Version < LanguageVersion.V_6)
+ Report.FeatureIsNotAvailable (Compiler, Location, "auto-implemented property initializer");
+ }
+
+ if (auto) {
+ if (Get == null) {
+ Report.Error (8052, Location, "Auto-implemented property `{0}' must have get accessor",
+ GetSignatureForError ());
+ return false;
+ }
+
+ if (Initializer == null && AccessorSecond == null) {
+ Report.Error (8051, Location, "Auto-implemented property `{0}' must have set accessor or initializer",
+ GetSignatureForError ());
+ }
+
+ if (Compiler.Settings.Version < LanguageVersion.V_3 && Initializer == null)
+ Report.FeatureIsNotAvailable (Compiler, Location, "auto-implemented properties");
- Get.ModFlags |= Modifiers.COMPILER_GENERATED;
- Set.ModFlags |= Modifiers.COMPILER_GENERATED;
CreateAutomaticProperty ();
}
--- /dev/null
+using System;
+
+struct S
+{
+ public static int P { get; } = 4;
+
+ public static int Main ()
+ {
+ if (P != 4)
+ return 1;
+
+ var c = new C ();
+ if (c.P != -3)
+ return 2;
+
+ if (c.P2 != 1)
+ return 3;
+
+ c.P2 = 9;
+ if (c.P2 != 9)
+ return 4;
+
+ var s = new S2 (null);
+ if (s.P != 4)
+ return 12;
+
+ if (s.P2 != 1)
+ return 13;
+
+ s.P2 = 9;
+ if (s.P2 != 9)
+ return 14;
+
+ return 0;
+ }
+}
+
+class C
+{
+ public decimal P { get; } = -3;
+ public int P2 { get; set; } = 1;
+}
+
+struct S2
+{
+ public int P { get; } = 4;
+ public int P2 { get; set; } = 1;
+
+ public S2 (object o)
+ {
+ }
+}
\ No newline at end of file
</method>\r
</type>\r
</test>\r
+ <test name="gtest-autoproperty-09.cs">\r
+ <type name="S">\r
+ <method name="Int32 get_P()" attrs="2198">\r
+ <size>13</size>\r
+ </method>\r
+ <method name="Int32 Main()" attrs="150">\r
+ <size>192</size>\r
+ </method>\r
+ <method name="Void .cctor()" attrs="6289">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="C">\r
+ <method name="System.Decimal get_P()" attrs="2182">\r
+ <size>14</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>27</size>\r
+ </method>\r
+ </type>\r
+ <type name="S2">\r
+ <method name="Int32 get_P()" attrs="2182">\r
+ <size>14</size>\r
+ </method>\r
+ <method name="Void .ctor(Object)" attrs="6278">\r
+ <size>16</size>\r
+ </method>\r
+ </type>\r
+ <type name="C">\r
+ <method name="Int32 get_P2()" attrs="2182">\r
+ <size>14</size>\r
+ </method>\r
+ <method name="Void set_P2(Int32)" attrs="2182">\r
+ <size>8</size>\r
+ </method>\r
+ </type>\r
+ <type name="S2">\r
+ <method name="Int32 get_P2()" attrs="2182">\r
+ <size>14</size>\r
+ </method>\r
+ <method name="Void set_P2(Int32)" attrs="2182">\r
+ <size>8</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
<test name="gtest-collectioninit-01.cs">\r
<type name="Test">\r
<method name="Void TestList(System.Collections.Generic.List`1[System.Int32], Int32)" attrs="145">\r