[svn] r7656: nemerle/trunk/ncc: generation/Typer3.n
testsuite/negative/bug-664.n testsuite/positive/before...
divan
svnadmin at nemerle.org
Sat May 5 15:34:59 CEST 2007
Log:
Add 'this' before 'base()' usage checks (fix 664).
Author: divan
Date: Sat May 5 15:34:55 2007
New Revision: 7656
Added:
nemerle/trunk/ncc/testsuite/negative/bug-664.n
nemerle/trunk/ncc/testsuite/positive/before-base.n
Modified:
nemerle/trunk/ncc/generation/Typer3.n
Modified: nemerle/trunk/ncc/generation/Typer3.n
==============================================================================
--- nemerle/trunk/ncc/generation/Typer3.n (original)
+++ nemerle/trunk/ncc/generation/Typer3.n Sat May 5 15:34:55 2007
@@ -1113,11 +1113,29 @@
IsBaseCtor (_ : TExpr) : bool
{
| TExpr.Base (mth) =>
- !CurrentType.GetConstructors (). Contains (mth)
+ ! mth.DeclaringType.Equals (CurrentType)
| TExpr.MacroEnvelope (_, _, e) => IsBaseCtor (e)
| _ => false
}
+ IsThis (_ : TExpr) : bool
+ {
+ | TExpr.This => true
+ | TExpr.LocalRef as e
+ => (e.decl.ValKind is LocalValue.Kind.ClosurisedThisPointer)
+ | _ => false;
+ }
+
+ IsBaseField (f : IField) : bool
+ {
+ ! f.DeclaringType.Equals (CurrentType)
+ }
+
+ IsBaseMethod (m : IMethod) : bool
+ {
+ ! m.DeclaringType.Equals (CurrentType)
+ }
+
//Return min*max ctor calls in expr
CtorCalls (e : TExpr) : int*int
{
@@ -1379,6 +1397,42 @@
| (_, y) =>
Message.Warning ($"Base constructor call can happen $y times");
}
+ //Check this usage before base()
+ //Allow this.*
+ //Deny base.*, this, base
+ def f (_) {
+ | TExpr.Call (e, p, _) when IsCtor (e)
+ => _ = List.Map (p, x => ctor_calls (x.expr));
+ Some (true)
+ | TExpr.FieldMember (e, f) as expr when IsThis (e)
+ => when (IsBaseField (f))
+ Message.Error (expr.loc,
+ "using base class field before base is constructed");
+ Some (false)
+ | TExpr.MethodRef (e, m, _, _) as expr when IsThis (e)
+ => when (IsBaseMethod (m))
+ Message.Error (expr.loc,
+ "using base class method before base is constructed");
+ Some (false)
+ | e when IsThis (e)
+ => Message.Error (e.loc,
+ "``this'' or ``base'' usage before base is constructed");
+ Some (false)
+ | _ => None ()
+ }
+ and ctor_calls (e) {
+ SimpleFlow (e, f, false, seq, fork)
+ }
+ and seq (_) {
+ | [] => false
+ | q :: _ when ctor_calls (q) => true
+ | _ :: w => seq (w)
+ }
+ and fork (l) {
+ List.Filter (l, seq) != []
+ }
+ _ = ctor_calls (e);
+
}
}
when (is_ctor && !CurrentType.IsValueType)
Added: nemerle/trunk/ncc/testsuite/negative/bug-664.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/negative/bug-664.n Sat May 5 15:34:55 2007
@@ -0,0 +1,50 @@
+class Base {
+ public this (_ : Base) {
+ }
+}
+
+class Inh : Base {
+ public this () {
+ base (this) // E: ``this'' or ``base'' usage before base is constructed
+ }
+}
+
+class A
+{
+ protected x : int;
+ protected y () : int {
+ 1
+ }
+ public this( x : int = 10 ) {
+ this.x = x;
+ }
+}
+
+class B : A
+{
+ new x : int;
+ new y () : int {
+ 1
+ }
+ public this()
+ {
+ this.x = 1;
+ _ = base; // E: ``this'' or ``base'' usage before base is constructed
+ _ = this; // E: ``this'' or ``base'' usage before base is constructed
+ _ = base.x; // E: using base class field before base is constructed
+ _ = this.x;
+ System.Console.WriteLine ($"base.x = $(base.x)"); // E: using base class field before base is constructed
+ _ = base.y (); // E: using base class method before base is constructed
+ _ = this.y ();
+
+ base (1);
+
+ _ = base;
+ _ = this;
+ _ = base.x;
+ _ = this.x;
+ System.Console.WriteLine ($"base.x = $(base.x)");
+ _ = base.y ();
+ _ = this.y ();
+ }
+}
Added: nemerle/trunk/ncc/testsuite/positive/before-base.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/positive/before-base.n Sat May 5 15:34:55 2007
@@ -0,0 +1,21 @@
+class A {
+ public this (x : int) {
+ System.Console.WriteLine (x)
+ }
+}
+
+class B : A {
+ x : int = 3;
+ public this () {
+ base (this.x)
+ }
+};
+
+_ = B ();
+
+
+/*
+BEGIN-OUTPUT
+3
+END-OUTPUT
+*/
\ No newline at end of file
More information about the svn
mailing list