Branch: Tag:

2003-08-18

2003-08-18 15:11:38 by Martin Stjernholm <mast@lysator.liu.se>

Backported an important fix from 7.5, along with testsuite cases:
Reworked the Foo::this implementation to work correctly with parent
pointers through inherits etc. It's now done through a special
identifier reference integer IDREF_MAGIC_THIS.

Rev: bin/mktestsuite:1.22
Rev: src/builtin_functions.c:1.461
Rev: src/docode.c:1.162
Rev: src/interpret.c:1.293
Rev: src/interpret_functions.h:1.125
Rev: src/las.c:1.321
Rev: src/object.c:1.220
Rev: src/program.c:1.474
Rev: src/program.h:1.176
Rev: src/testsuite.in:1.589

1: - test_true([["$Id: testsuite.in,v 1.588 2003/08/05 12:59:21 mast Exp $"]]); + test_true([["$Id: testsuite.in,v 1.589 2003/08/18 15:11:38 mast Exp $"]]);      // This triggered a bug only if run sufficiently early.   test_compile_any([[#pike 7.2]])
2172:    "int main() { trace(9); werror(\"%O\\n\","+acc+"()); }\n"    ;    -  mixed tmp; +  mixed tmp, x;    mixed err=catch {    tmp=compile_string(test)();    res=tmp->Q();    if(res != ans)    throw("Test failed"); -  +  res = "None";    tmp = decode_value(encode_value(tmp, Codec()), Codec());    res=tmp->Q();    if(res != ans)    throw("Test failed for encode/decode."); -  +  x=Program.inherit_list(object_program(tmp));    }; -  mixed x=Program.inherit_list(object_program(tmp)); +     if(err)    {    errors++;
8233:      // - this_object and this   test_true(objectp(this_object())) + test_true(objectp(this)) + test_true(objectp(global::this)) + test_true(this_object() == this) + test_true([[typeof(this) == typeof(this_object())]]) + test_true([[typeof(this) == typeof(global::this)]]) + test_true([[typeof(this_program) == typeof(object_program(this_object()))]]) + test_true([[typeof(this_program) == typeof(object_program(global::this))]])    - test_program([[ + test_program_eq([[    string _sprintf() {return "g";}    class A {    string _sprintf() {return "A";}
8246:    }    }    } -  int a() {return A()->B()->f() == "gABBB";} - ]]) +  string a() {return A()->B()->f();} + ]], "gABBB")    - test_program([[ + test_program_eq([[    string _sprintf() {return "g";}    class A {    string _sprintf() {return "A";}
8261:    }    }    } -  int a() {return A()->B()->f() == "gABB";} - ]]) +  string a() {return A()->B()->f();} + ]], "gABB")    - test_program([[ + test_program_eq([[    string _sprintf() {return "g";}    class A {    string _sprintf() {return "A";}
8277:    }    }    } -  int a() {return A()->B()->f() == "gAB";} - ]]) +  string a() {return A()->B()->f();} + ]], "gAB")    - test_program([[ + test_program_eq([[    string _sprintf() {return "g";}    class A {    string _sprintf() {return "A";}
8293:    }    constant this = 7;    } -  int a() {return A()->B()->f() == "g7BB7";} +  string a() {return A()->B()->f();} + ]], "g7BB7") +  + test_compile_error([[ +  this = 17;   ]])    -  + test_compile_error([[ +  class A { +  class B { +  void f() {A::this = 17;} +  } +  }; + ]]) +  + test_any([[ +  class A { +  class B { +  A parent() {return A::this;} +  } +  }; +  A a = A(); +  A.B b = a->B(); +  destruct (a); +  return zero_type (b->parent()); + ]], 2) +  + test_eval_error([[ +  class A { +  class B { +  class C { +  A grandparent() {return A::this;} +  } +  } +  }; +  A.B b = A()->B(); +  A.B.C c = b->C(); +  destruct (b); +  b->grandparent(); + ]], 2) +  + test_program_eq([[ +  string _sprintf() {return "g";} +  class A { +  string _sprintf() {return "A";} +  mixed f() { +  return sprintf ("%O%O", global::this, A::this); +  } +  } +  class B { +  string _sprintf() {return "B";} +  class C { +  inherit A; +  string _sprintf() {return "C";} +  mixed f() { +  return A::f() + sprintf ("%O%O%O%O", +  global::this, B::this, this_program::this, this); +  } +  } +  } +  string a() {return B()->C()->f();} + ]], "gCgBCC") +  + test_program_eq([[ +  string _sprintf() {return "g";} +  class A { +  string _sprintf() {return "A";} +  mixed f() { +  return sprintf ("%O%O%O%O", +  global::this, A::this, this_program::this, this); +  } +  } +  class B { +  string _sprintf() {return "B";} +  class C { +  inherit A; +  string _sprintf() {return "C";} +  mixed f() { +  return A::f() + "|" + +  sprintf ("%O%O%O%O%O", +  global::this, B::this, C::this, this_program::this, this); +  } +  } +  } +  string a() {return B()->C()->f();} + ]], "gCCC|gBCCC") +    test_program([[    class A {    class B {
8318:    int a() {return A()->B()->f();}   ]])    + test_program([[ +  class A { +  class B { +  mixed f() { +  return typeof (A::this_program) != typeof (B::this_program); +  } +  } +  } +  int a() {return A()->B()->f();} + ]]) +  + test_program_eq([[ +  object ao = compile_string(#" +  string id() {return \"A\";} +  class B { +  string id() {return \"B\";} +  string foo() +  { +  return this->id() + id() + local::id() + global::this->id() + global::id(); +  } +  }")(); +  +  class Handler +  { +  mixed resolv (string id, void|string file, void|object handler) +  { +  if (id == "B") return ao->B; +  return master()->resolv (id, file, handler); +  } +  } +  +  string a() +  { +  object c = compile_string(#" +  string id() {return \"C\";} +  class D { +  inherit B; +  string id() {return \"D\";} +  string foo() +  { +  return ::foo() + \"|\" + +  this->id() + id() + B::id() + global::this->id() + global::id(); +  } +  }", 0, Handler())(); +  +  return c->D()->foo(); +  } + ]], "DDBAA|DDBCC") +  + test_program_eq([[ +  class X +  { +  object parent() {return global::this;} +  } +  +  class Handler +  { +  mixed resolv (string id, void|string file, void|object handler) +  { +  if (id == "X") return X; +  return master()->resolv (id, file, handler); +  } +  } +  +  object a() +  { +  object o = compile_string ("inherit X;", 0, Handler())(); +  return o->parent(); +  } + ]], this_object()) +  +    // - throw   test_eq(20,catch(throw(a())))