Skip to content

Commit

Permalink
Merge pull request #197 from LorenzoBettini/task_195-Error_recovery_i…
Browse files Browse the repository at this point in the history
…n_the_interpreter

Task 195 error recovery in the interpreter
  • Loading branch information
LorenzoBettini committed Jun 11, 2020
2 parents 6e65c81 + 32908bf commit 9d51c90
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 14 deletions.
Expand Up @@ -101,21 +101,48 @@ class EdeltaInterpreterTest extends EdeltaAbstractTest {
.hasCauseExactlyInstanceOf(MyCustomException)
}

@Test
def void testThrowNullPointerException() {
assertThatThrownBy['''
import org.eclipse.emf.ecore.EClass
import edelta.tests.additional.MyCustomException
metamodel "foo"
def op(EClass c) : void {
throw new NullPointerException
}
modifyEcore aTest epackage foo {
addNewEClass("NewClass") [
op(it)
]
}
'''.assertAfterInterpretationOfEdeltaModifyEcoreOperation [
// never gets here
]
].isInstanceOf(EdeltaInterpreterWrapperException)
.hasCauseExactlyInstanceOf(NullPointerException)
}


@Test
def void testCreateEClassAndCallOperationFromUseAsReferringToUnknownType() {
assertThatThrownBy[
'''
metamodel "foo"
use NonExistant as my
modifyEcore aTest epackage foo {
val c = addNewEClass("NewClass")
my.createANewEAttribute(c)
my.createANewEAttribute(c) // this won't break the interpreter
addNewEClass("AnotherNewClass")
}
'''.assertAfterInterpretationOfEdeltaModifyEcoreOperation(false) [ /* will not get here */ ]
].isInstanceOf(IllegalStateException)
.hasMessageContaining("Cannot resolve proxy")
'''.assertAfterInterpretationOfEdeltaModifyEcoreOperation(false) [derivedEPackage |
derivedEPackage.lastEClass => [
assertEquals("AnotherNewClass", name)
]
]
}
@Test
Expand Down Expand Up @@ -341,6 +368,27 @@ class EdeltaInterpreterTest extends EdeltaAbstractTest {
]
}
@Test
def void testUnresolvedEcoreReferenceMethodCall2() {
val input = '''
import org.eclipse.emf.ecore.EClass

metamodel "foo"

modifyEcore aTest epackage foo {
ecoreref(nonexist).ESuperTypes += ecoreref(MyClass) // this won't break the interpreter
addNewEClass("NewClass1")
ecoreref(NewClass1).abstract = true
}
'''
input.assertAfterInterpretationOfEdeltaModifyEcoreOperation(false) [ derivedEPackage |
derivedEPackage.lastEClass => [
assertEquals("NewClass1", name)
assertThat(isAbstract).isTrue
]
]
}
@Test
def void testUnresolvedEcoreReferenceQualified() {
val input = '''
Expand Down
Expand Up @@ -87,7 +87,7 @@ class EdeltaSafeInterpreterTest extends EdeltaAbstractTest {
@Test
def void testCreateEClassAndCallOperationFromUseAsReferringToUnknownType() {
// differently from EdeltaInterpreterTest,
// IllegalArgumentException is swallowed
// IllegalStateException is swallowed
'''
metamodel "foo"
Expand Down Expand Up @@ -127,7 +127,7 @@ class EdeltaSafeInterpreterTest extends EdeltaAbstractTest {
]
}

@Test // remove expected exception which the safe interpreter swallows
@Test
def void testCreateEClassAndCallOperationThatThrows() {
// differently from EdeltaInterpreterTest,
// MyCustomException is swallowed
Expand All @@ -153,6 +153,32 @@ class EdeltaSafeInterpreterTest extends EdeltaAbstractTest {
]
}

@Test
def void testThrowNullPointerException() {
// differently from EdeltaInterpreterTest,
// NullPointerException is swallowed
'''
import org.eclipse.emf.ecore.EClass
import edelta.tests.additional.MyCustomException
metamodel "foo"
def op(EClass c) : void {
throw new NullPointerException
}
modifyEcore aTest epackage foo {
addNewEClass("NewClass") [
op(it)
]
}
'''
.parseWithTestEcore
.assertAfterInterpretationOfEdeltaModifyEcoreOperation [
// never gets here
]
}

def private assertAfterInterpretationOfEdeltaModifyEcoreOperation(
EdeltaProgram program,
(EPackage)=>void testExecutor
Expand Down
Expand Up @@ -145,30 +145,75 @@ public void testCreateEClassAndCallOperationThatThrows() {
}

@Test
public void testCreateEClassAndCallOperationFromUseAsReferringToUnknownType() {
public void testThrowNullPointerException() {
final ThrowableAssert.ThrowingCallable _function = () -> {
StringConcatenation _builder = new StringConcatenation();
_builder.append("import org.eclipse.emf.ecore.EClass");
_builder.newLine();
_builder.append("import edelta.tests.additional.MyCustomException");
_builder.newLine();
_builder.newLine();
_builder.append("metamodel \"foo\"");
_builder.newLine();
_builder.newLine();
_builder.append("use NonExistant as my");
_builder.append("def op(EClass c) : void {");
_builder.newLine();
_builder.append("\t");
_builder.append("throw new NullPointerException");
_builder.newLine();
_builder.append("}");
_builder.newLine();
_builder.newLine();
_builder.append("modifyEcore aTest epackage foo {");
_builder.newLine();
_builder.append("\t");
_builder.append("val c = addNewEClass(\"NewClass\")");
_builder.append("addNewEClass(\"NewClass\") [");
_builder.newLine();
_builder.append("\t\t");
_builder.append("op(it)");
_builder.newLine();
_builder.append("\t");
_builder.append("my.createANewEAttribute(c)");
_builder.append("]");
_builder.newLine();
_builder.append("}");
_builder.newLine();
final Procedure1<EPackage> _function_1 = (EPackage it) -> {
};
this.assertAfterInterpretationOfEdeltaModifyEcoreOperation(_builder, false, _function_1);
this.assertAfterInterpretationOfEdeltaModifyEcoreOperation(_builder, _function_1);
};
Assertions.assertThatThrownBy(_function).isInstanceOf(EdeltaInterpreterWrapperException.class).hasCauseExactlyInstanceOf(NullPointerException.class);
}

@Test
public void testCreateEClassAndCallOperationFromUseAsReferringToUnknownType() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("metamodel \"foo\"");
_builder.newLine();
_builder.newLine();
_builder.append("use NonExistant as my");
_builder.newLine();
_builder.newLine();
_builder.append("modifyEcore aTest epackage foo {");
_builder.newLine();
_builder.append("\t");
_builder.append("val c = addNewEClass(\"NewClass\")");
_builder.newLine();
_builder.append("\t");
_builder.append("my.createANewEAttribute(c) // this won\'t break the interpreter");
_builder.newLine();
_builder.append("\t");
_builder.append("addNewEClass(\"AnotherNewClass\")");
_builder.newLine();
_builder.append("}");
_builder.newLine();
final Procedure1<EPackage> _function = (EPackage derivedEPackage) -> {
EClass _lastEClass = this.getLastEClass(derivedEPackage);
final Procedure1<EClass> _function_1 = (EClass it) -> {
Assert.assertEquals("AnotherNewClass", it.getName());
};
ObjectExtensions.<EClass>operator_doubleArrow(_lastEClass, _function_1);
};
Assertions.assertThatThrownBy(_function).isInstanceOf(IllegalStateException.class).hasMessageContaining("Cannot resolve proxy");
this.assertAfterInterpretationOfEdeltaModifyEcoreOperation(_builder, false, _function);
}

@Test
Expand Down Expand Up @@ -501,6 +546,40 @@ public void testUnresolvedEcoreReferenceMethodCall() {
this.assertAfterInterpretationOfEdeltaModifyEcoreOperation(input, false, _function);
}

@Test
public void testUnresolvedEcoreReferenceMethodCall2() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("import org.eclipse.emf.ecore.EClass");
_builder.newLine();
_builder.newLine();
_builder.append("metamodel \"foo\"");
_builder.newLine();
_builder.newLine();
_builder.append("modifyEcore aTest epackage foo {");
_builder.newLine();
_builder.append("\t");
_builder.append("ecoreref(nonexist).ESuperTypes += ecoreref(MyClass) // this won\'t break the interpreter");
_builder.newLine();
_builder.append("\t");
_builder.append("addNewEClass(\"NewClass1\")");
_builder.newLine();
_builder.append("\t");
_builder.append("ecoreref(NewClass1).abstract = true");
_builder.newLine();
_builder.append("}");
_builder.newLine();
final String input = _builder.toString();
final Procedure1<EPackage> _function = (EPackage derivedEPackage) -> {
EClass _lastEClass = this.getLastEClass(derivedEPackage);
final Procedure1<EClass> _function_1 = (EClass it) -> {
Assert.assertEquals("NewClass1", it.getName());
Assertions.assertThat(it.isAbstract()).isTrue();
};
ObjectExtensions.<EClass>operator_doubleArrow(_lastEClass, _function_1);
};
this.assertAfterInterpretationOfEdeltaModifyEcoreOperation(input, false, _function);
}

@Test
public void testUnresolvedEcoreReferenceQualified() {
StringConcatenation _builder = new StringConcatenation();
Expand Down
Expand Up @@ -198,6 +198,43 @@ public void testCreateEClassAndCallOperationThatThrows() {
this.assertAfterInterpretationOfEdeltaModifyEcoreOperation(this.parseWithTestEcore(_builder), _function);
}

@Test
public void testThrowNullPointerException() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("import org.eclipse.emf.ecore.EClass");
_builder.newLine();
_builder.append("import edelta.tests.additional.MyCustomException");
_builder.newLine();
_builder.newLine();
_builder.append("metamodel \"foo\"");
_builder.newLine();
_builder.newLine();
_builder.append("def op(EClass c) : void {");
_builder.newLine();
_builder.append("\t");
_builder.append("throw new NullPointerException");
_builder.newLine();
_builder.append("}");
_builder.newLine();
_builder.newLine();
_builder.append("modifyEcore aTest epackage foo {");
_builder.newLine();
_builder.append("\t");
_builder.append("addNewEClass(\"NewClass\") [");
_builder.newLine();
_builder.append("\t\t");
_builder.append("op(it)");
_builder.newLine();
_builder.append("\t");
_builder.append("]");
_builder.newLine();
_builder.append("}");
_builder.newLine();
final Procedure1<EPackage> _function = (EPackage it) -> {
};
this.assertAfterInterpretationOfEdeltaModifyEcoreOperation(this.parseWithTestEcore(_builder), _function);
}

private void assertAfterInterpretationOfEdeltaModifyEcoreOperation(final EdeltaProgram program, final Procedure1<? super EPackage> testExecutor) {
final EdeltaModifyEcoreOperation it = this.lastModifyEcoreOperation(program);
final Function1<EPackage, String> _function = (EPackage it_1) -> {
Expand Down
Expand Up @@ -226,7 +226,7 @@ protected Object doEvaluate(final XExpression expression, final IEvaluationConte
updateListenerCurrentExpression(expression);
try {
return super.doEvaluate(expression, context, indicator);
} catch (IllegalArgumentException e) {
} catch (IllegalArgumentException | IllegalStateException e) {
// we let the interpreter go on as much as possible
return new DefaultEvaluationResult(null, null);
}
Expand Down

0 comments on commit 9d51c90

Please sign in to comment.