[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