...
 
Commits (4)
......@@ -1103,23 +1103,22 @@ Rvalue* Parser::P_Simple_Object()
if (TokenType() == Lexer::OpHat)
{
LineColumn hatpos = lexer.GetPosition();
NextToken();
LineColumn namepos = lexer.GetPosition();
NextToken();
std::string colname = "^" + P_Column_Name();
Symbol* symbol = context.symboltable->ResolveSymbol(hatpos, ":THIS", NULL, false);
Symbol* symbol = context.symboltable->ResolveSymbol(namepos, ":THIS", NULL, false);
if (!symbol)
{
lexer.AddErrorAt(hatpos, Error::ThisOnlyInMemberFunctions);
lexer.AddErrorAt(namepos, Error::ThisOnlyInMemberFunctions);
return coder->ImConstant(pos, 0); // Do NOT return 0. // ADDME: variant error node?
}
else
{
if (within_base_constructor_call)
lexer.AddErrorAt(hatpos, Error::ThisNotAllowedInBaseConstructorParameters);
lexer.AddErrorAt(namepos, Error::ThisNotAllowedInBaseConstructorParameters);
}
Rvalue *expr = coder->ImVariable(hatpos, symbol);
Rvalue *expr = coder->ImVariable(namepos, symbol);
if (!TryParse(Lexer::OpenParenthesis))
{
......
This diff is collapsed.
......@@ -511,7 +511,7 @@ PUBLIC STATIC OBJECTTYPE TreeBase
PUBLIC MACRO TrimToSubTree(STRING ARRAY path)
{
this->root := this->GetObjectByPath(path);
this->pvt_root := this->GetObjectByPath(path);
}
PUBLIC STRING FUNCTION ShortDump(INTEGER indent DEFAULTSTO 0)
......
......@@ -439,7 +439,7 @@ STRING FUNCTION GetAnnotatedResults(STRING test, RECORD ARRAY messages)
res := res || rec.linetext || "\n";
FOREVERY (RECORD msg FROM relevant_messages)
res := res || (msg.col < 3 ? Left(" ", msg.col - 1) || "// <-" : "//" || RepeatText(" ", msg.col - 3) || "^ ") ||
`${msg.iserror ? "E" : "W"}:${msg.code} ${EncodeParam(msg.param1, msg.param2 != "")}${EncodeParam(msg.param1, FALSE)}# ${msg.message}\n`;
`${msg.iserror ? "E" : "W"}:${msg.code} ${EncodeParam(msg.param1, msg.param2 != "")}${EncodeParam(msg.param2, FALSE)}# ${msg.message}\n`;
}
}
......
......@@ -532,7 +532,7 @@ PUBLIC STATIC OBJECTTYPE SMTPConnection
RECORD resp := this->SendCommand("STARTTLS");
IF(resp.code != 220)
{
this->lasterror := resp;
this->pvt_lasterror := resp;
THROW NEW Exception("StartTLS failed: " || resp.code || " " || resp.message);
}
IF(NOT this->socket->StartSSL(TRUE))
......
......@@ -577,29 +577,18 @@ PUBLIC STATIC OBJECTTYPE TolliumWebController EXTEND TolliumControllerBase
MACRO OnReflect(VARIANT val, RECORD reflectoptions)
{
BOOLEAN killuser;
TRY
{
IF(NOT ObjectExists(this->tolliumuser))
{
killuser:=TRUE;
this->tolliumuser := NEW TolliumUser(DEFAULT OBJECT, DEFAULT OBJECT, 0, "<anonymous>");
}
OBJECT dialog := this->LoadScreen( "mod::tollium/screens/debugging.xml#reflectdialog"
, [ data := val
, tree := TRUE
, settings := [ stacktrace := ArraySlice(GetStackTrace(),1) ]
, reflectoptions := reflectoptions
]);
IF(dialog->RunModal() = "") //the user disconnected
TerminateScript(); //then STOP ourselves too - users do not expect 'Reflect(); DoSomething();' to actually do something if they abort during Reflect
}
FINALLY
{
IF(killuser)
this->tolliumuser := DEFAULT OBJECT;
}
RECORD contexts;
IF (NOT ObjectExists(this->tolliumuser))
contexts := [ user := NEW TolliumUser(DEFAULT OBJECT, DEFAULT OBJECT, 0, "<anonymous>") ];
OBJECT dialog := this->LoadScreen( "mod::tollium/screens/debugging.xml#reflectdialog"
, [ data := val
, tree := TRUE
, settings := [ stacktrace := ArraySlice(GetStackTrace(),1) ]
, reflectoptions := reflectoptions
], CELL[ contexts ]);
IF(dialog->RunModal() = "") //the user disconnected
TerminateScript(); //then STOP ourselves too - users do not expect 'Reflect(); DoSomething();' to actually do something if they abort during Reflect
}
>;
......@@ -1534,6 +1534,74 @@ MACRO TestWeakObjects()
TestEQ(FALSE, ObjectExists(OBJECT(stack_weakobj)));
}
MACRO TestReadWriteOnlyProperties()
{
TestAnnotatedCompile(`<?wh
OBJECTTYPE x
< FUNCTION PTR a;
RECORD b;
PROPERTY ra(a, -);
PROPERTY rb(this->b.c, -);
PROPERTY wa(-, a);
PROPERTY wb(-, this->b.c);
MACRO ok_write() { this->wa := DEFAULT FUNCTION PTR; }
MACRO fail_write() { this->ra := DEFAULT FUNCTION PTR; }
// ^ E:151 RA # Write readonly property
VARIANT FUNCTION ok_read() { RETURN this->ra; }
VARIANT FUNCTION fail_read() { RETURN this->wa; }
// ^ E:150 WA # Read writeonly property
VARIANT FUNCTION ok_call() { RETURN this->ra(); }
VARIANT FUNCTION fail_call() { RETURN this->wa(); }
// ^ E:150 WA # Read writeonly property
MACRO fail_deepwrite_r() { this->rb.a := 6; }
// ^ E:151 RB # Write readonly property
MACRO fail_deepwrite_w() { this->wb.a := 6; }
// ^ E:150 WB # Read writeonly property
INTEGER FUNCTION fail_deepread_w() { RETURN this->wb.a; }
// ^ E:150 WB # Read writeonly property
MACRO fail_deepinsert_r() { INSERT 1 INTO this->rb.b AT END; }
// ^ E:151 RB # Write readonly property
MACRO fail_deepinsert_w() { INSERT 1 INTO this->wb.b AT END; }
// ^ E:150 WB # Read writeonly property
MACRO fail_deepdelete_r() { DELETE FROM this->rb.b AT 0; }
// ^ E:151 RB # Write readonly property
MACRO fail_deepdelete_w() { DELETE FROM this->wb.b AT 0; }
// ^ E:150 WB # Read writeonly property
>;
OBJECTTYPE writeonlyhat
< RECORD b;
PROPERTY ^(-,this->b.c);
MACRO ok_write() { this->wa := DEFAULT FUNCTION PTR; }
VARIANT FUNCTION fail_read() { RETURN ^test; }
// ^ E:150 ^TEST # Read writeonly property
VARIANT FUNCTION fail_call() { RETURN ^test(); }
// ^ E:150 ^TEST # Read writeonly property
MACRO fail_deepwrite_w() { ^test.a := 6; }
// ^ E:150 ^TEST # Read writeonly property
INTEGER FUNCTION fail_deepread_w() { RETURN ^test.a; }
// ^ E:150 ^TEST # Read writeonly property
MACRO fail_deepinsert_w() { INSERT 1 INTO ^test.b AT END; }
// ^ E:150 ^TEST # Read writeonly property
MACRO fail_deepdelete_w() { DELETE FROM ^test.b AT 0; }
// ^ E:150 ^TEST # Read writeonly property
>;
OBJECTTYPE readonlyhat
< RECORD b;
PROPERTY ^(this->b.c,-);
MACRO fail_write() { ^test := DEFAULT FUNCTION PTR; }
// ^ E:151 ^TEST # Write readonly property
VARIANT FUNCTION ok_read() { RETURN ^test; }
VARIANT FUNCTION ok_call() { RETURN ^test(); }
MACRO fail_deepwrite_r() { ^test.a := 6; }
// ^ E:151 ^TEST # Write readonly property
MACRO fail_deepinsert_r() { INSERT 1 INTO ^test.b AT END; }
// ^ E:151 ^TEST # Write readonly property
MACRO fail_deepdelete_r() { DELETE FROM ^test.b AT 0; }
// ^ E:151 ^TEST # Write readonly property
>;
`);
}
PRINT("\n === Running TestObjects\n");
BaseTest();
InsertMemberTest();
......@@ -1557,3 +1625,4 @@ StaticObjectTypesTest();
RegressionsTest();
TestHat();
TestWeakObjects();
TestReadWriteOnlyProperties();