Skip to content

Commit

Permalink
[lang] throw statement has side effect.
Browse files Browse the repository at this point in the history
close #929
Signed-off-by: Stéphane Galland <galland@arakhne.org>
  • Loading branch information
gallandarakhneorg committed Aug 26, 2019
1 parent 8bd69f6 commit f69552d
Show file tree
Hide file tree
Showing 3 changed files with 300 additions and 54 deletions.
Expand Up @@ -147,14 +147,21 @@ protected Boolean handleNoSuchMethod(Object... params) {
/** Replies if the given function is purable according to its modifiers and prototype.
*
* <p>Basically, an operation is purable if:<ul>
* <li></li>
* <li>not abstract,</li>
* <li>not a dispatch function,</li>
* <li>not native,</li>
* <li>with a body,</li>
* <li>not in a capacity definition.</li>
* </ul>
*
* <p>This function is called usually before testing the pattern of the function's name.
*
* @param operation the operation to test.
* @return {@code true} if the operation is not pure according to the prototype.
* @since 0.10
*/
@SuppressWarnings("static-method")
protected boolean isUnpureOperationPrototype(XtendFunction operation) {
protected boolean isPureStateForbidden(XtendFunction operation) {
if (operation == null
|| operation.isAbstract() || operation.isDispatch() || operation.isNative()
|| operation.getExpression() == null) {
Expand All @@ -164,6 +171,17 @@ protected boolean isUnpureOperationPrototype(XtendFunction operation) {
return declaringType instanceof SarlCapacity;
}

/** Replies if it is impossible to determine the pure state of the given function .
*
* @param operation the operation to test.
* @return {@code true} if the pure state of the operation cannot be determined.
* @since 0.10
*/
@SuppressWarnings("static-method")
protected boolean isPureStateAmbiguous(XtendFunction operation) {
return false;
}

@Override
public boolean isPurableOperation(XtendFunction operation) {
return isPurableOperation(operation, null);
Expand All @@ -176,7 +194,7 @@ public boolean isPurableOperation(XtendFunction operation) {
* @return {@code true} if the operation could be marked as pure.
*/
boolean isPurableOperation(XtendFunction operation, ISideEffectContext context) {
if (isUnpureOperationPrototype(operation)) {
if (isPureStateForbidden(operation)) {
return false;
}
if (this.nameValidator.isNamePatternForNotPureOperation(operation)) {
Expand All @@ -185,6 +203,10 @@ boolean isPurableOperation(XtendFunction operation, ISideEffectContext context)
if (this.nameValidator.isNamePatternForPureOperation(operation)) {
return true;
}
if (isPureStateAmbiguous(operation)) {
return false;
}
// Test the body
if (context == null) {
return !hasSideEffects(
getInferredPrototype(operation),
Expand Down Expand Up @@ -283,13 +305,16 @@ protected Boolean _hasSideEffects(XCastedExpression expression, ISideEffectConte
*/
protected boolean _hasSideEffects(XAbstractWhileExpression expression, ISideEffectContext context) {
context.open();
if (hasSideEffects(expression.getPredicate(), context)) {
return true;
}
if (hasSideEffects(expression.getBody(), context.branch())) {
return true;
try {
if (hasSideEffects(expression.getPredicate(), context)) {
return true;
}
if (hasSideEffects(expression.getBody(), context.branch())) {
return true;
}
} finally {
context.close();
}
context.close();
return false;
}

Expand All @@ -301,10 +326,13 @@ protected boolean _hasSideEffects(XAbstractWhileExpression expression, ISideEffe
*/
protected Boolean _hasSideEffects(XForLoopExpression expression, ISideEffectContext context) {
context.open();
if (hasSideEffects(expression.getForExpression(), context)) {
return true;
try {
if (hasSideEffects(expression.getForExpression(), context)) {
return true;
}
} finally {
context.close();
}
context.close();
return hasSideEffects(expression.getEachExpression(), context.branch());
}

Expand Down Expand Up @@ -346,8 +374,9 @@ protected Boolean _hasSideEffects(XReturnExpression expression, ISideEffectConte
* @param context the list of context expressions.
* @return {@code true} if the expression has side effects.
*/
@SuppressWarnings("static-method")
protected Boolean _hasSideEffects(XThrowExpression expression, ISideEffectContext context) {
return hasSideEffects(expression.getExpression(), context);
return true;
}

/** Test if the given expression has side effects.
Expand All @@ -365,12 +394,15 @@ protected Boolean _hasSideEffects(XTryCatchFinallyExpression expression, ISideEf
buffers.add(buffer);
for (final XCatchClause clause : expression.getCatchClauses()) {
context.open();
buffer = context.createVariableAssignmentBufferForBranch();
if (hasSideEffects(clause.getExpression(), context.branch(buffer))) {
return true;
try {
buffer = context.createVariableAssignmentBufferForBranch();
if (hasSideEffects(clause.getExpression(), context.branch(buffer))) {
return true;
}
buffers.add(buffer);
} finally {
context.close();
}
buffers.add(buffer);
context.close();
}
context.mergeBranchVariableAssignments(buffers);
if (hasSideEffects(expression.getFinallyExpression(), context)) {
Expand Down Expand Up @@ -401,23 +433,26 @@ protected Boolean _hasSideEffects(XVariableDeclaration expression, ISideEffectCo
*/
protected Boolean _hasSideEffects(XBasicForLoopExpression expression, ISideEffectContext context) {
context.open();
for (final XExpression ex : expression.getInitExpressions()) {
if (hasSideEffects(ex, context)) {
try {
for (final XExpression ex : expression.getInitExpressions()) {
if (hasSideEffects(ex, context)) {
return true;
}
}
if (hasSideEffects(expression.getEachExpression(), context)) {
return true;
}
}
if (hasSideEffects(expression.getEachExpression(), context)) {
return true;
}
for (final XExpression ex : expression.getUpdateExpressions()) {
if (hasSideEffects(ex, context.branch())) {
for (final XExpression ex : expression.getUpdateExpressions()) {
if (hasSideEffects(ex, context.branch())) {
return true;
}
}
if (hasSideEffects(expression.getExpression(), context.branch())) {
return true;
}
} finally {
context.close();
}
if (hasSideEffects(expression.getExpression(), context.branch())) {
return true;
}
context.close();
return false;
}

Expand All @@ -429,29 +464,35 @@ protected Boolean _hasSideEffects(XBasicForLoopExpression expression, ISideEffec
*/
protected Boolean _hasSideEffects(XSwitchExpression expression, ISideEffectContext context) {
context.open();
if (hasSideEffects(expression.getSwitch(), context)) {
return true;
}
final List<Map<String, List<XExpression>>> buffers = new ArrayList<>();
for (final XCasePart ex : expression.getCases()) {
context.open();
if (hasSideEffects(ex.getCase(), context)) {
try {
if (hasSideEffects(expression.getSwitch(), context)) {
return true;
}
final List<Map<String, List<XExpression>>> buffers = new ArrayList<>();
for (final XCasePart ex : expression.getCases()) {
context.open();
try {
if (hasSideEffects(ex.getCase(), context)) {
return true;
}
final Map<String, List<XExpression>> buffer = context.createVariableAssignmentBufferForBranch();
if (hasSideEffects(ex.getThen(), context.branch(buffer))) {
return true;
}
buffers.add(buffer);
} finally {
context.close();
}
}
final Map<String, List<XExpression>> buffer = context.createVariableAssignmentBufferForBranch();
if (hasSideEffects(ex.getThen(), context.branch(buffer))) {
if (hasSideEffects(expression.getDefault(), context.branch(buffer))) {
return true;
}
buffers.add(buffer);
context.mergeBranchVariableAssignments(buffers);
} finally {
context.close();
}
final Map<String, List<XExpression>> buffer = context.createVariableAssignmentBufferForBranch();
if (hasSideEffects(expression.getDefault(), context.branch(buffer))) {
return true;
}
buffers.add(buffer);
context.mergeBranchVariableAssignments(buffers);
context.close();
return false;
}

Expand All @@ -463,12 +504,15 @@ protected Boolean _hasSideEffects(XSwitchExpression expression, ISideEffectConte
*/
protected Boolean _hasSideEffects(XCollectionLiteral expression, ISideEffectContext context) {
context.open();
for (final XExpression ex : expression.getElements()) {
if (hasSideEffects(ex, context)) {
return true;
try {
for (final XExpression ex : expression.getElements()) {
if (hasSideEffects(ex, context)) {
return true;
}
}
} finally {
context.close();
}
context.close();
return false;
}

Expand Down Expand Up @@ -589,12 +633,15 @@ protected Boolean _hasSideEffects(XBlockExpression expression, ISideEffectContex
final List<XExpression> exprs = expression.getExpressions();
if (exprs != null && !exprs.isEmpty()) {
context.open();
for (final XExpression ex : exprs) {
if (hasSideEffects(ex, context)) {
return true;
try {
for (final XExpression ex : exprs) {
if (hasSideEffects(ex, context)) {
return true;
}
}
} finally {
context.close();
}
context.close();
}
return false;
}
Expand Down Expand Up @@ -679,6 +726,11 @@ private boolean internalHasOperationSideEffects(XAbstractFeatureCall expression,
// to influence the pure state of the operation.
return false;
}
// Test if the receiver has side effects
if (hasSideEffects(expression.getActualReceiver(), context)) {
return true;
}
// Test the feature call itself
final ISideEffectContext ctx = new SideEffectContext(
Iterables.concat(context.getCalledOperations(),
Collections.singleton(getInferredPrototype(operation))));
Expand Down
Expand Up @@ -3512,7 +3512,6 @@ public void compilingComplexLambda03() throws Exception {
" protected void f(final Scope<Address> s) {",
" }",
" ",
" @Pure",
" protected void f2(final Scope<Address> s) {",
" try {",
" UUID _randomUUID = UUID.randomUUID();",
Expand Down

0 comments on commit f69552d

Please sign in to comment.