[svn] r7588: nemerle/trunk: macros/Internals.n
ncc/generation/Typer3.n ncc/hierarchy/TypeBuilder.n ncc/tes...
divan
svnadmin at nemerle.org
Tue Apr 10 21:24:40 CEST 2007
Log:
1) Move instance field init before base() call.
2) Improve instance field init, fix 778.
Author: divan
Date: Tue Apr 10 21:24:36 2007
New Revision: 7588
Added:
nemerle/trunk/ncc/testsuite/positive/bug-778.n
Modified:
nemerle/trunk/macros/Internals.n
nemerle/trunk/ncc/generation/Typer3.n
nemerle/trunk/ncc/hierarchy/TypeBuilder.n
nemerle/trunk/ncc/typing/Typer.n
nemerle/trunk/ncc/typing/Typer2.n
Modified: nemerle/trunk/macros/Internals.n
==============================================================================
--- nemerle/trunk/macros/Internals.n (original)
+++ nemerle/trunk/macros/Internals.n Tue Apr 10 21:24:36 2007
@@ -128,6 +128,8 @@
else
<[ this.$(f.Name : dyn) = $val ]>;
+ when (!is_static)
+ t.init_list ::= init;
// given existing constructor, insert call to base constructor
// at its beginning
def inject (ctor) {
@@ -163,24 +165,21 @@
ctor.Body = nbody
};
- if (!is_static && t.IsValueType)
+ when (!is_static && t.IsValueType)
Message.Error (val.Location, "instance field initalizers are not allowed in structs"
" (they wouldn't work for null initialized instances)");
- else
match (mems) {
| [] =>
def loc = t.Location;
def loc1 = Location(loc.FileIndex, loc.Line, loc.Column);
Util.locate(loc1,
- if (is_static)
+ when (is_static)
t.Define (<[ decl: static public this () { Nemerle.InternalMacros.initializer ($init); } ]>)
- else
- t.Define (<[ decl: public this () { Nemerle.InternalMacros.initializer ($init); } ]>)
);
- // inject intializers into all ctors
- | _ => mems.Iter (inject)
+ // inject intializers into static ctor
+ | _ => when (is_static) mems.Iter (inject)
}
}
}
Modified: nemerle/trunk/ncc/generation/Typer3.n
==============================================================================
--- nemerle/trunk/ncc/generation/Typer3.n (original)
+++ nemerle/trunk/ncc/generation/Typer3.n Tue Apr 10 21:24:36 2007
@@ -1382,7 +1382,15 @@
}
when (is_ctor && !CurrentType.IsValueType)
{
- def ini = null;
+ def ini =
+ match (CurrentType.init_list) {
+ | [q]
+ => match (q) {
+ | PT.PExpr.Typed (e) => e
+ | _ => Util.ice ("bad field initializers");
+ }
+ | _ => null
+ };
when (e == null)
e = match (current_local_fun.body) {
| FunBody.Typed (e) => e
Modified: nemerle/trunk/ncc/hierarchy/TypeBuilder.n
==============================================================================
--- nemerle/trunk/ncc/hierarchy/TypeBuilder.n (original)
+++ nemerle/trunk/ncc/hierarchy/TypeBuilder.n Tue Apr 10 21:24:36 2007
@@ -62,6 +62,9 @@
mutable constant_object : IField;
mutable underlying_enum_type : MType.Class;
+ //list of instance field initializers
+ public mutable init_list : list [PT.PExpr] = [];
+
[Accessor]
mutable tenv : TyVarEnv;
Added: nemerle/trunk/ncc/testsuite/positive/bug-778.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/positive/bug-778.n Tue Apr 10 21:24:36 2007
@@ -0,0 +1,41 @@
+using Nemerle.Collections;
+
+[Record(Exclude = [VisitedObjects])]
+public class RelocationInfo
+{
+ public VisitedObjects : Hashtable[object, byte] = Hashtable();
+ public FileIndex : int;
+ public Line : int;
+ public Char : int;
+ public LineOffset : int;
+ public CharOffset : int;
+}
+
+//and one test, mentioned in comments to n664
+abstract class A {
+ protected this (x : string) {
+ assert (x != null);
+ System.Console.WriteLine (x);
+ }
+}
+
+class B : A {
+ mutable a : string = "asa";
+ public this () {
+ base (a);
+ }
+ static Main () : void {
+ def info = RelocationInfo(1, 2, 3, 4, 5);
+ when (info.VisitedObjects != null)
+ System.Console.WriteLine ("OK");
+
+ _ = B();
+ }
+}
+
+/*
+BEGIN-OUTPUT
+OK
+asa
+END-OUTPUT
+*/
Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n (original)
+++ nemerle/trunk/ncc/typing/Typer.n Tue Apr 10 21:24:36 2007
@@ -79,6 +79,7 @@
public partial class Typer : TyperBase
{
is_instance_ctor : bool;
+ mutable field_inits_typed : bool = false;
is_method : bool;
env : GlobalEnv;
tenv : TyVarEnv;
@@ -339,6 +340,17 @@
protected virtual RunSecondPass (meth : MethodBuilder) : void
{
+ when (current_type.init_list != [] && is_instance_ctor
+ && !field_inits_typed)
+ {
+ current_type.init_list = List.Rev (current_type.init_list);
+ current_type.init_list =
+ PT.PExpr.Typed (
+ TypeExpr (PT.PExpr.Sequence (current_type.init_list))
+ ) :: [];
+ field_inits_typed = true;
+ }
+
def t2 = Typer2 (current_type, meth);
t2.Run ();
Modified: nemerle/trunk/ncc/typing/Typer2.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer2.n (original)
+++ nemerle/trunk/ncc/typing/Typer2.n Tue Apr 10 21:24:36 2007
@@ -30,6 +30,7 @@
using Nemerle.Utility;
using Nemerle.Compiler;
+using PT = Nemerle.Compiler.Parsetree;
using Nemerle.Compiler.Typedtree;
using Nemerle.Compiler.SolverMacros;
@@ -41,6 +42,15 @@
top_level_fun : MethodBuilder;
mutable this_ptr_decl : LocalValue;
mutable current_fun : Fun_header;
+
+ mutable field_inits_typed : bool = false;
+ IsCurrentFunInstanceCtor () : bool
+ {
+ top_level_fun.MemberKind == MemberKinds.Constructor &&
+ !top_level_fun.IsStatic &&
+ 0 == top_fun.CompareTo (current_fun);
+ }
+
top_fun : Fun_header;
current_type : TypeBuilder;
messenger : Messenger;
@@ -93,6 +103,20 @@
foreach (parm in current_fun.parms)
parm.decl.Register ();
+ when (IsCurrentFunInstanceCtor () && !field_inits_typed)
+ match (current_type.init_list) {
+ | [q] =>
+ match (q) {
+ | PT.PExpr.Typed (e) =>
+ current_type.init_list
+ = PT.PExpr.Typed (Walk (Context.TopLevel, e)) :: [];
+ field_inits_typed = true
+ | _ => Util.ice ("bad field initializers");
+ }
+ | [] => ()
+ | _ => Util.ice ("bad field initializers");
+ }
+
match (current_fun.body) {
| FunBody.Typed (expr) =>
current_fun.body = FunBody.Typed (Walk (Context.TopLevel, expr));
More information about the svn
mailing list