[svn] r6237: nemerle/trunk/ncc: generation/Typer3.n
testsuite/negative/base-calls.n testsuite/positive/bas...
nazgul
svnadmin at nemerle.org
Sun May 7 13:09:02 CEST 2006
Log:
Support placing ctor calls in the middle of constructor sequence
Author: nazgul
Date: Sun May 7 13:08:22 2006
New Revision: 6237
Added:
nemerle/trunk/ncc/testsuite/negative/base-calls.n
Modified:
nemerle/trunk/ncc/generation/Typer3.n
nemerle/trunk/ncc/testsuite/positive/base-calls.n
nemerle/trunk/ncc/typing/Typer.n
Modified: nemerle/trunk/ncc/generation/Typer3.n
==============================================================================
--- nemerle/trunk/ncc/generation/Typer3.n (original)
+++ nemerle/trunk/ncc/generation/Typer3.n Sun May 7 13:08:22 2006
@@ -990,7 +990,7 @@
when (need_cast)
parm.SetType (InternalType.Object); // modify its type
- // Message.Debug ($"handle fp $parm $(parm.Id) $(parm.Type)");
+ //Message.Debug ($"handle fp $parm $(parm.Type)");
when (parm.InClosure) {
def expr =
if (need_cast)
@@ -1022,9 +1022,8 @@
current_local_fun.body = FunBody.Typed (BuildRevSequence ([]));
Some (Walk (basecall))
- | FunBody.Typed (body) =>
- Message.Warning (body.loc, body.ToString ());
- assert (false)
+ // ctor call is (if not, it's a bug) placed somewhere inside, but this case disallows using 'this' in closures
+ | FunBody.Typed (_) => Some (null)
| _ => assert (false)
}
@@ -1053,7 +1052,9 @@
initializers = LoadParameters () + initializers;
+ mutable base_call_missing = false;
match (GetBaseCall ()) {
+ | Some (null) => base_call_missing = true;
| Some (call) =>
initializers = call :: initializers;
| None => {}
@@ -1063,6 +1064,8 @@
foreach (d in current_local_fun.closure_vars)
when (d.InClosure &&
d.ValKind is LocalValue.Kind.ClosurisedThisPointer) {
+ when (base_call_missing)
+ Message.Error ("closure utilizing 'this' reference is not allowed when base ctor call is not placed at the beginning of current ctor");
def ini =
TExpr.Assign (InternalType.Void,
LocalRef (d, for_store = true),
Added: nemerle/trunk/ncc/testsuite/negative/base-calls.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/negative/base-calls.n Sun May 7 13:08:22 2006
@@ -0,0 +1,15 @@
+using Nemerle.IO;
+
+class Closurising {
+ myfun : void -> void;
+ fld : int;
+
+ public this (_x : int) { // E: closure utilizing 'this' reference is not allowed when base ctor call is not placed at the beginning of current ctor
+ fld = 1;
+ myfun = fun () { print ("fun $fld\n") }
+ myfun ();
+ base ();
+ fld = 7;
+ myfun ();
+ }
+}
\ No newline at end of file
Modified: nemerle/trunk/ncc/testsuite/positive/base-calls.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/base-calls.n (original)
+++ nemerle/trunk/ncc/testsuite/positive/base-calls.n Sun May 7 13:08:22 2006
@@ -47,6 +47,38 @@
def b = B ();
b.m ();
b.Prop += 3;
+ def _ = Inherit(1);
+ _ = Closurising (5);
+ }
+}
+
+class Base
+{
+ public this(_ : int) { print("A()\n"); }
+}
+
+class Inherit : Base
+{
+ public this(_ : int)
+ {
+ print("B()\n");
+ base(2);
+ }
+}
+
+class Closurising : Base {
+ myfun : void -> void;
+ fld : int;
+
+ public this (x : int) {
+ mutable str = "aaa";
+ fld = 1;
+ myfun = () => print ("fun $x and $str and no fld\n"); // we do not use 'fld', so closure can be created safely
+ myfun ();
+ base (x);
+ str = "bbb";
+ fld = 7;
+ myfun ();
}
}
@@ -58,5 +90,10 @@
A.Prop
A.Prop set
B.Prop set
+B()
+A()
+fun 5 and aaa and no fld
+A()
+fun 5 and bbb and no fld
END-OUTPUT
*/
Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n (original)
+++ nemerle/trunk/ncc/typing/Typer.n Sun May 7 13:08:22 2006
@@ -230,16 +230,19 @@
{
when (is_instance_ctor && !m.DeclaringType.IsValueType)
match (current_fun.body) {
- | FunBody.Parsed (expr) =>
- match (expr) {
- | PT.PExpr.Sequence (<[ base (.. $_) ]> :: _) => ()
- | PT.PExpr.Sequence (<[ this (.. $_) ]> :: _) => ()
- | PT.PExpr.Sequence =>
- Util.locate (expr.loc,
- current_fun.body = FunBody.Parsed (<[ { base (); $expr } ]>)
- )
- | _ => assert (false)
+ | FunBody.Parsed (Sequence (exprs) as seq) =>
+ def exists_ctor_call (_) {
+ | [] => false
+ | <[ base (.. $_) ]> :: _
+ | <[ this (.. $_) ]> :: _ => true
+ | _ :: xs => exists_ctor_call (xs)
}
+ if (exists_ctor_call (exprs))
+ ()
+ else
+ Util.locate (seq.loc,
+ current_fun.body = FunBody.Parsed (<[ { ..$(<[ base (); ]> :: exprs) } ]>)
+ )
| _ => ()
}
}
@@ -1675,6 +1678,7 @@
parms = parms,
tenv = tenv,
loc = fn.header.loc);
+
def parm_types = List.Map (parms, fun (p : Fun_parm) { p.ty });
def fun_type = ConstructFunctionType (parm_types, header.ret_type);
def parents = current_fun :: current_fun.GetParents ();
More information about the svn
mailing list