[svn] r6432: nemerle/trunk: boot/Nemerle.Compiler.dll boot/Nemerle.MSBuild.Tasks.dll boot/Nemerle.Macros.d...

nazgul svnadmin at nemerle.org
Thu Jul 6 23:08:24 CEST 2006


Log:
Mark immutable fields with initonly. Mark error on assignment to immutable field, whose access is delegated to external function

Author: nazgul
Date: Thu Jul  6 23:07:11 2006
New Revision: 6432

Modified:
   nemerle/trunk/boot/Nemerle.Compiler.dll
   nemerle/trunk/boot/Nemerle.MSBuild.Tasks.dll
   nemerle/trunk/boot/Nemerle.Macros.dll
   nemerle/trunk/boot/Nemerle.dll
   nemerle/trunk/boot/ncc.exe
   nemerle/trunk/lib/list.n
   nemerle/trunk/macros/core.n
   nemerle/trunk/ncc/external/LibrariesLoader.n
   nemerle/trunk/ncc/generation/HierarchyEmitter.n
   nemerle/trunk/ncc/generation/Typer4.n
   nemerle/trunk/ncc/parsing/AST.n
   nemerle/trunk/ncc/testsuite/negative/immutable-field.n
   nemerle/trunk/ncc/typing/Typer.n

Modified: nemerle/trunk/boot/Nemerle.Compiler.dll
==============================================================================
Binary files. No diff available.

Modified: nemerle/trunk/boot/Nemerle.MSBuild.Tasks.dll
==============================================================================
Binary files. No diff available.

Modified: nemerle/trunk/boot/Nemerle.Macros.dll
==============================================================================
Binary files. No diff available.

Modified: nemerle/trunk/boot/Nemerle.dll
==============================================================================
Binary files. No diff available.

Modified: nemerle/trunk/boot/ncc.exe
==============================================================================
Binary files. No diff available.

Modified: nemerle/trunk/lib/list.n
==============================================================================
--- nemerle/trunk/lib/list.n	(original)
+++ nemerle/trunk/lib/list.n	Thu Jul  6 23:07:11 2006
@@ -48,7 +48,9 @@
   public variant list ['a] : SCG.IEnumerable ['a]
   {
     [System.Serializable]
-    | Cons { hd : 'a; tl : list ['a]; }
+    | Cons { hd : 'a;
+      [Nemerle.Extensions.CompilerMutable]
+      tl : list ['a]; }
 
     [System.Serializable]      
     | Nil { public override ToString () : string { "[]" } }

Modified: nemerle/trunk/macros/core.n
==============================================================================
--- nemerle/trunk/macros/core.n	(original)
+++ nemerle/trunk/macros/core.n	Thu Jul  6 23:07:11 2006
@@ -1014,6 +1014,12 @@
     def tty = Macros.ImplicitCTX().MonoBindType (ty);
     <[ $(Macros.DefaultValueOfType (tty)) : $ty ]>
   }
+
+  [Nemerle.MacroUsage (Nemerle.MacroPhase.BeforeInheritance,
+                       Nemerle.MacroTargets.Field)]
+  macro CompilerMutable (_ : TypeBuilder, fld : ParsedField) {
+    fld.Attributes = fld.Attributes | NemerleAttributes.CompilerMutable;
+  }
 } // end ns
 
 namespace Nemerle.Diagnostics {

Modified: nemerle/trunk/ncc/external/LibrariesLoader.n
==============================================================================
--- nemerle/trunk/ncc/external/LibrariesLoader.n	(original)
+++ nemerle/trunk/ncc/external/LibrariesLoader.n	Thu Jul  6 23:07:11 2006
@@ -1396,6 +1396,8 @@
         when (handle.IsAssembly) attributes |= NemerleAttributes.Internal;
         when (handle.IsFamilyAndAssembly) attributes |=
           NemerleAttributes.Internal %| NemerleAttributes.Protected;
+        when (!handle.IsInitOnly && handle.IsDefined (typeof (Nemerle.Internal.ImmutableAttribute), false))
+          attributes |= NemerleAttributes.CompilerMutable;
       }
 
       public DeclaringType : TypeInfo
@@ -1519,7 +1521,6 @@
       {
         get
         {
-          // shouldn't we use InternalType here?
           !handle.IsInitOnly && 
           !handle.IsDefined (typeof (Nemerle.Internal.ImmutableAttribute), false)
         }

Modified: nemerle/trunk/ncc/generation/HierarchyEmitter.n
==============================================================================
--- nemerle/trunk/ncc/generation/HierarchyEmitter.n	(original)
+++ nemerle/trunk/ncc/generation/HierarchyEmitter.n	Thu Jul  6 23:07:11 2006
@@ -1040,13 +1040,18 @@
         when (attrs %&& NemerleAttributes.SpecialName) result |= FieldAttributes.SpecialName %|
             FieldAttributes.RTSpecialName;
 
+        unless (attrs %&& (NemerleAttributes.Mutable | NemerleAttributes.CompilerMutable))
+          result |= FieldAttributes.InitOnly;
+        
         result
       }
       
       mutable attrs = make_field_attributes (Attributes);
       
-      when (IsLiteral)
+      when (IsLiteral) {
         attrs |= FieldAttributes.Literal;
+        attrs &= ~FieldAttributes.InitOnly;
+      }
 
       // prevent verification failure
       when (Name != "value__")
@@ -1080,7 +1085,8 @@
         field_builder.SetCustomAttribute (volatile_attr)
       }
 
-      unless (IsMutable || IsLiteral) {
+      when (!IsMutable && attributes %&& NemerleAttributes.CompilerMutable)
+      {
         def imm_attr = Manager.AttributeCompiler.MakeEmittedAttribute (SystemTypeCache.ImmutableAttribute);
         field_builder.SetCustomAttribute (imm_attr)
       }

Modified: nemerle/trunk/ncc/generation/Typer4.n
==============================================================================
--- nemerle/trunk/ncc/generation/Typer4.n	(original)
+++ nemerle/trunk/ncc/generation/Typer4.n	Thu Jul  6 23:07:11 2006
@@ -487,8 +487,18 @@
                 | LocalRef (decl) => decl.Type.Fix ()
                 | ArrayIndexer
                 | This
-                | FieldMember
                 | StaticRef => e1.Type.Fix ()
+                | FieldMember (obj, fld) =>
+                  // this is a rare case when compiler decided to assign to field though it is immutable
+                  // (like when the field had to be closurised inside the constructor)
+                  unless (fld.IsMutable ||
+                          fld.Attributes %&& NemerleAttributes.CompilerMutable ||
+                          obj is TExpr.This && the_method.GetFunKind () is FunKind.Constructor)
+                    Message.Error ("assignment to immutable field is allowed only inside code,"
+                                   " which is executed inside constructor, but this field access"
+                                   " is done through closure");
+                  e1.Type.Fix ()
+                  
                 | _ => Util.ice ($ "wrong assignment target $e1")
               }
             def e1 = Walk (e1);

Modified: nemerle/trunk/ncc/parsing/AST.n
==============================================================================
--- nemerle/trunk/ncc/parsing/AST.n	(original)
+++ nemerle/trunk/ncc/parsing/AST.n	Thu Jul  6 23:07:11 2006
@@ -241,6 +241,7 @@
     | SpecialName = 0x08000
     | Partial     = 0x10000
     | Extern      = 0x20000            
+    | CompilerMutable = 0x40000 // field is immutable, but compiler overrides it and can assign something
 
     | AccessModifiers = Public %| Private %| Protected %| Internal
   }                 

Modified: nemerle/trunk/ncc/testsuite/negative/immutable-field.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/negative/immutable-field.n	(original)
+++ nemerle/trunk/ncc/testsuite/negative/immutable-field.n	Thu Jul  6 23:07:11 2006
@@ -1,2 +1,38 @@
-def x = 1 :: [];
-x.tl = [2]; // E: needed a writable location for assignment target, got a reference to field `tl', which is read-only
+
+
+class A {
+  foo : int;
+
+  public this () {
+    def bar (x) {
+      foo = x; // E: assignment to immutable field
+    }
+    if (1 == 1)
+      bar (1);
+    else
+      bar (2);
+  }
+}
+
+class B {
+  foo : int;
+  meth : int -> void;
+
+  public this () {
+    def bar (x) {
+      foo = x;  // E: assignment to immutable field
+    }
+    if (1 == 1)
+      bar (1);
+    else
+      bar (2);
+    meth = bar;
+  }
+}
+
+class C {
+  foo () : void {
+    def x = 1 :: [];
+    x.tl = [2]; // E: needed a writable location for assignment target, got a reference to field `tl', which is read-only
+  }
+}

Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n	(original)
+++ nemerle/trunk/ncc/typing/Typer.n	Thu Jul  6 23:07:11 2006
@@ -610,7 +610,12 @@
           }
         | TExpr.StaticPropertyRef (_, p) when !need_ref => p.IsMutable
         | TExpr.FieldMember (TExpr.This, _) when is_instance_ctor => true
-        | TExpr.FieldMember (_, mem) => mem.IsMutable || e.SkipWriteCheck
+        | TExpr.FieldMember (_, mem) =>
+          if (mem.IsMutable)
+            true
+          else
+            e.SkipWriteCheck && mem.Attributes %&& NemerleAttributes.CompilerMutable
+          
         | TExpr.PropertyMember (_, p) when !need_ref => p.IsMutable
         | TExpr.Call (TExpr.PropertyMember (_, p), _, _) when !need_ref => p.IsMutable
         | TExpr.Call (TExpr.Delayed (dt), _, _) when !need_ref => dt.IsMutableIndexer



More information about the svn mailing list