Commit 30804441 authored by Miklos Magyari's avatar Miklos Magyari
Browse files

OOP: semantic check - return statement cannot be used in destructor (issue #427)


Signed-off-by: Miklos Magyari's avatarMiklos Magyari <miklos.magyari@sigmatechnology.se>
parent acbc9aad
......@@ -183,6 +183,13 @@ type class @trait FinallyClass2 {
log(this.m_const);
}
// finally blocks canot have a return clause
type class FinallyClass3 {
public function f_pub() { }
} finally {
return;
}
// bad combination of class modifiers
type class @final @abstract BadClass1 { }
type class @final @trait BadClass3 { }
......
......@@ -45,6 +45,7 @@ public final class Return_Statement extends Statement {
private static final String UNEXPETEDRETURNSTATEMENT = "Return statement cannot be used in a {0}. It is allowed only in functions and altsteps";
private static final String ALTSTEPRETURNINGVALUE = "An altstep cannot return a value";
private static final String USAGEINCONTROLPART = "Return statement cannot be used in the control part. It is alowed only in functions and altsteps";
private static final String RETURNINDESTRUCTOR = "Return statement cannot be used in a class destructor";
private static final String FULLNAMEPART = ".returnexpression";
private static final String STATEMENT_NAME = "return";
......@@ -117,6 +118,10 @@ public final class Return_Statement extends Statement {
genRestrictionCheck = false;
final Definition definition = myStatementBlock.getMyDefinition();
if (myStatementBlock.hasDestructor()) {
location.reportSemanticError(RETURNINDESTRUCTOR);
return;
}
if (definition == null) {
location.reportSemanticError(USAGEINCONTROLPART);
return;
......
......@@ -113,6 +113,9 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
/** Indicates if it is a statement block of a loop. */
private boolean ownerIsLoop;
/** Indicates it is a statement block of a class destructor */
private boolean ownerIsDestructor;
/**
* Indicates if it is a statement block of an AltGuard (in alt,
......@@ -140,6 +143,7 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
statements = new ArrayList<Statement>();
ownerIsLoop = false;
ownerIsAltguard = false;
ownerIsDestructor = false;
}
@Override
......@@ -228,6 +232,13 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
public void setOwnerIsAltguard() {
ownerIsAltguard = true;
}
/**
* Sets indication that it is a statement block of a class destructor.
**/
public void setOwnerIsDestructor() {
ownerIsDestructor = true;
}
/**
* Adds a statement to the list of statements stored in this statement
......@@ -708,6 +719,13 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
public boolean hasEnclosingLoopOrAltguard() {
return ownerIsLoop || ownerIsAltguard || (myStatementBlock != null && myStatementBlock.hasEnclosingLoopOrAltguard());
}
/**
* @return indication if the statement block is enclosed in a class destructor
*/
public boolean hasDestructor() {
return ownerIsDestructor || (myStatementBlock != null && myStatementBlock.hasDestructor());
}
@Override
/** {@inheritDoc} */
......
......@@ -75,6 +75,7 @@ public final class Class_Type extends Type implements ITypeWithComponents {
}
if (finallyBlock != null) {
finallyBlock.setFullNameParent(this);
finallyBlock.setOwnerIsDestructor();
}
}
......@@ -187,6 +188,10 @@ public final class Class_Type extends Type implements ITypeWithComponents {
if (classBody != null) {
classBody.check(timestamp);
}
if (finallyBlock != null) {
finallyBlock.check(timestamp);
}
lastTimeChecked = timestamp;
}
......
......@@ -117,7 +117,7 @@ public class OOP_Semantic_tests {
private ArrayList<MarkerToCheck> oopNegative_ttcn_initializer() {
//oopNegativeSemanticTest.ttcn
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(71);
ArrayList<MarkerToCheck> markersToCheck = new ArrayList<MarkerToCheck>(72);
int lineNum = 28;
markersToCheck.add(new MarkerToCheck("class type expected", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 10;
......@@ -187,7 +187,9 @@ public class OOP_Semantic_tests {
lineNum += 7;
markersToCheck.add(new MarkerToCheck("Trait classes can only declare abstract methods", lineNum, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("A trait class should not define a finally block", ++lineNum, IMarker.SEVERITY_ERROR));
lineNum += 5;
lineNum += 8;
markersToCheck.add(new MarkerToCheck("Return statement cannot be used in a class destructor", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 4;
markersToCheck.add(new MarkerToCheck("An absract class cannot be final", lineNum, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("A trait class cannot be final", ++lineNum, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("A class cannot be both abstract and trait", ++lineNum, IMarker.SEVERITY_ERROR));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment