blob: bfbf15151fa861c2b35329f1054f26efe194c4b0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2019 Willink Transformations and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* E.D.Willink - initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.examples.test.xtext;
import java.io.IOException;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.examples.pivot.tests.TestOCL;
import org.eclipse.ocl.examples.xtext.tests.XtextTestCase;
import org.eclipse.ocl.pivot.Constraint;
import org.eclipse.ocl.pivot.IfExp;
import org.eclipse.ocl.pivot.IteratorExp;
import org.eclipse.ocl.pivot.LetExp;
import org.eclipse.ocl.pivot.Model;
import org.eclipse.ocl.pivot.NullLiteralExp;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.PropertyCallExp;
import org.eclipse.ocl.pivot.VariableExp;
import org.eclipse.ocl.pivot.internal.manager.FlowAnalysis;
import org.eclipse.ocl.pivot.internal.manager.MetamodelManagerInternal;
import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal.EnvironmentFactoryInternalExtension;
import org.eclipse.ocl.pivot.resource.ASResource;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.NameUtil;
import org.eclipse.ocl.pivot.utilities.OCL;
import org.eclipse.ocl.pivot.utilities.ParserException;
import org.eclipse.ocl.pivot.utilities.PivotConstants;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.pivot.utilities.XMIUtil;
import org.eclipse.ocl.xtext.base.cs2as.CS2AS;
import org.eclipse.ocl.xtext.base.utilities.BaseCSResource;
import org.eclipse.ocl.xtext.oclstdlib.scoping.JavaClassScope;
/**
* Tests the isNull/isNotNull/isNotKnown results of the FlowAnalysis.
*/
@SuppressWarnings("null")
public class FlowAnalysisTests extends XtextTestCase
{
public class MyOCL extends TestOCL
{
public MyOCL() {
super(getTestFileSystem(), "FlowAnalysisTests", getName(), OCL.NO_PROJECTS, null);
}
public void assertIsNonNull(@NonNull OCLExpression asExpression) {
FlowAnalysis flowAnalysis = getFlowAnalysis(asExpression);
assertFalse("Expected not-isNull for '" + asExpression + "'",
flowAnalysis.isNull(asExpression));
assertTrue("Expected isNonNull for '" + asExpression + "'",
flowAnalysis.isNonNull(asExpression));
}
public void assertIsNotKnown(@NonNull OCLExpression asExpression) {
FlowAnalysis flowAnalysis = getFlowAnalysis(asExpression);
assertFalse("Expected not-isNull for '" + asExpression + "'",
flowAnalysis.isNull(asExpression));
assertFalse("Expected not-isNonNull for '" + asExpression + "'",
flowAnalysis.isNonNull(asExpression));
}
public void assertIsNull(@NonNull OCLExpression asExpression) {
FlowAnalysis flowAnalysis = getFlowAnalysis(asExpression);
assertTrue("Expected isNull for '" + asExpression + "'",
flowAnalysis.isNull(asExpression));
assertFalse("Expected not-isNonNull for '" + asExpression + "'",
flowAnalysis.isNonNull(asExpression));
}
protected @NonNull OCLExpression createTestModel(@NonNull String invariantName, @NonNull String invariantBody) throws IOException, ParserException {
String testContext =
"package deductions : ded = 'http://deductions'\n" +
"{\n" +
" class Deductions\n" +
" {\n" +
" property dummy : Dummy[?];\n" +
" property x : Integer[?];\n" +
" invariant " + invariantName + ": " + invariantBody + ";\n" +
" }\n" +
" class Dummy\n" +
" {\n" +
" property dummy : Dummy[?];\n" +
" operation func(i : Integer, j : Integer) : Dummy[?];\n" +
" }\n" +
"}";
String fileName = "FlowAnalysis_" + invariantName;
createOCLinEcoreFile(fileName + ".oclinecore", testContext);
Resource asResource = doLoad_Concrete(fileName, "oclinecore");
Model model = PivotUtil.getModel(asResource);
org.eclipse.ocl.pivot.Package deductionsPackage = ClassUtil.nonNullState(NameUtil.getNameable(model.getOwnedPackages(), "deductions"));
org.eclipse.ocl.pivot.Class deductionsClass = ClassUtil.nonNullState(NameUtil.getNameable(deductionsPackage.getOwnedClasses(), "Deductions"));
Constraint asInvariant = ClassUtil.nonNullState(NameUtil.getNameable(deductionsClass.getOwnedInvariants(), invariantName));
return ((EnvironmentFactoryInternalExtension)environmentFactory).parseSpecification(asInvariant.getOwnedSpecification()).getOwnedBody();
}
public Resource doLoad_Concrete(@NonNull String stem, @NonNull String extension) throws IOException {
String inputName = stem + "." + extension;
String pivotName = inputName + PivotConstants.DOT_OCL_AS_FILE_EXTENSION;
URI inputURI = getTestFileURI(inputName);
URI pivotURI = getTestFileURI(pivotName);
BaseCSResource xtextResource = (BaseCSResource) getResourceSet().createResource(inputURI);
xtextResource.setProjectManager(getProjectMap());
JavaClassScope.getAdapter(xtextResource, getClass().getClassLoader());
getEnvironmentFactory().adapt(xtextResource);
xtextResource.load(null);
assertNoResourceErrors("Load failed", xtextResource);
CS2AS cs2as = xtextResource.findCS2AS();
if (cs2as != null) {
ASResource asResource = cs2as.getASResource();
assertNoValidationErrors("Loaded pivot", asResource);
}
Resource asResource = xtextResource.getASResource();
assertNoUnresolvedProxies("Unresolved proxies", xtextResource);
assertNoResourceErrors("Save failed", xtextResource);
asResource.setURI(pivotURI);
assertNoValidationErrors("Pivot validation errors", asResource.getContents().get(0));
asResource.save(XMIUtil.createSaveOptions());
return asResource;
}
protected FlowAnalysis getFlowAnalysis(@NonNull OCLExpression asExpression) {
MetamodelManagerInternal metamodelManager = getMetamodelManager();
return ((MetamodelManagerInternal.MetamodelManagerInternalExtension2)metamodelManager).getFlowAnalysis(asExpression);
}
}
public void testFlowAnalysis_SimpleProperty() throws Exception {
MyOCL ocl = new MyOCL();
OperationCallExp asBody = (OperationCallExp) ocl.createTestModel("SimpleProperty",
"x <> null");
PropertyCallExp asPropertyCallExp = (PropertyCallExp) PivotUtil.getOwnedSource(asBody);
NullLiteralExp asNullLiteralExp = (NullLiteralExp) PivotUtil.getOwnedArgument(asBody, 0);
ocl.assertIsNotKnown(asPropertyCallExp);
ocl.assertIsNull(asNullLiteralExp);
ocl.dispose();
}
public void testFlowAnalysis_SimpleNonNullVariable() throws Exception {
MyOCL ocl = new MyOCL();
LetExp asLetExp = (LetExp) ocl.createTestModel("SimpleNonNullVariable",
"let v : Integer[1] = 1 in v <> null");
OperationCallExp asIn = (OperationCallExp) PivotUtil.getOwnedIn(asLetExp);
VariableExp asVariableExp = (VariableExp) PivotUtil.getOwnedSource(asIn);
NullLiteralExp asNullLiteralExp = (NullLiteralExp) PivotUtil.getOwnedArgument(asIn, 0);
ocl.assertIsNonNull(asVariableExp);
ocl.assertIsNull(asNullLiteralExp);
ocl.dispose();
}
public void testFlowAnalysis_SimpleNullVariable() throws Exception {
MyOCL ocl = new MyOCL();
LetExp asLetExp = (LetExp) ocl.createTestModel("SimpleNullVariable",
"let v : Integer[?] = null in v <> null");
OperationCallExp asIn = (OperationCallExp) PivotUtil.getOwnedIn(asLetExp);
VariableExp asVariableExp = (VariableExp) PivotUtil.getOwnedSource(asIn);
NullLiteralExp asNullLiteralExp = (NullLiteralExp) PivotUtil.getOwnedArgument(asIn, 0);
ocl.assertIsNull(asVariableExp);
ocl.assertIsNull(asNullLiteralExp);
ocl.dispose();
}
public void testFlowAnalysis_SimpleNotKnownVariable() throws Exception {
MyOCL ocl = new MyOCL();
LetExp asLetExp = (LetExp) ocl.createTestModel("SimpleNotKnownVariable",
"let v : Integer[?] = x in v <> null");
OperationCallExp asIn = (OperationCallExp) PivotUtil.getOwnedIn(asLetExp);
VariableExp asVariableExp = (VariableExp) PivotUtil.getOwnedSource(asIn);
NullLiteralExp asNullLiteralExp = (NullLiteralExp) PivotUtil.getOwnedArgument(asIn, 0);
ocl.assertIsNotKnown(asVariableExp);
ocl.assertIsNull(asNullLiteralExp);
ocl.dispose();
}
public void testFlowAnalysis_SimpleIfGuard() throws Exception {
MyOCL ocl = new MyOCL();
LetExp asLetExp = (LetExp) ocl.createTestModel("SimpleIfGuard",
"let v : Integer[?] = x in if v <> null then v.toString() else v.toString() endif <> null");
OperationCallExp asIn = (OperationCallExp) PivotUtil.getOwnedIn(asLetExp);
IfExp asExpression = (IfExp) PivotUtil.getOwnedSource(asIn);
OperationCallExp asCondition = (OperationCallExp) PivotUtil.getOwnedCondition(asExpression);
OperationCallExp asThen = (OperationCallExp) PivotUtil.getOwnedThen(asExpression);
OperationCallExp asElse = (OperationCallExp) PivotUtil.getOwnedElse(asExpression);
VariableExp asConditionVariableExp = (VariableExp) PivotUtil.getOwnedSource(asCondition);
VariableExp asThenVariableExp = (VariableExp) PivotUtil.getOwnedSource(asThen);
VariableExp asElseVariableExp = (VariableExp) PivotUtil.getOwnedSource(asElse);
ocl.assertIsNotKnown(asConditionVariableExp);
ocl.assertIsNonNull(asThenVariableExp);
ocl.assertIsNull(asElseVariableExp);
ocl.dispose();
}
public void testFlowAnalysis_ImpliesPropertyGuard() throws Exception {
MyOCL ocl = new MyOCL();
OperationCallExp asImplies = (OperationCallExp) ocl.createTestModel("ImpliesVariableGuard",
"x <> null implies x.toString() <> null");
OperationCallExp asSource = (OperationCallExp) PivotUtil.getOwnedSource(asImplies);
OperationCallExp asArgument1 = (OperationCallExp) PivotUtil.getOwnedArgument(asImplies, 0);
OperationCallExp asArgument2 = (OperationCallExp) PivotUtil.getOwnedSource(asArgument1);
PropertyCallExp asSourcePropertyCallExp = (PropertyCallExp) PivotUtil.getOwnedSource(asSource);
PropertyCallExp asArgumentPropertyCallExp = (PropertyCallExp) PivotUtil.getOwnedSource(asArgument2);
ocl.assertIsNotKnown(asSourcePropertyCallExp);
ocl.assertIsNonNull(asArgumentPropertyCallExp);
ocl.dispose();
}
public void testFlowAnalysis_ImpliesVariableGuard() throws Exception {
MyOCL ocl = new MyOCL();
LetExp asLetExp = (LetExp) ocl.createTestModel("ImpliesGuard",
"let v : Integer[?] = x in v <> null implies v.toString() <> null");
OperationCallExp asImplies = (OperationCallExp) PivotUtil.getOwnedIn(asLetExp);
OperationCallExp asSource = (OperationCallExp) PivotUtil.getOwnedSource(asImplies);
OperationCallExp asArgument1 = (OperationCallExp) PivotUtil.getOwnedArgument(asImplies, 0);
OperationCallExp asArgument2 = (OperationCallExp) PivotUtil.getOwnedSource(asArgument1);
VariableExp asSourceVariableExp = (VariableExp) PivotUtil.getOwnedSource(asSource);
VariableExp asArgumentVariableExp = (VariableExp) PivotUtil.getOwnedSource(asArgument2);
ocl.assertIsNotKnown(asSourceVariableExp);
ocl.assertIsNonNull(asArgumentVariableExp);
ocl.dispose();
}
public void testFlowAnalysis_DoubleIfGuard() throws Exception {
MyOCL ocl = new MyOCL();
LetExp asLetExp = (LetExp) ocl.createTestModel("DoubleIfGuard",
"let v : Integer[?] = x in if v <> null and x <> null then v.toString() else v.toString() endif <> null");
OperationCallExp asIn = (OperationCallExp) PivotUtil.getOwnedIn(asLetExp);
IfExp asExpression = (IfExp) PivotUtil.getOwnedSource(asIn);
OperationCallExp asCondition1 = (OperationCallExp) PivotUtil.getOwnedCondition(asExpression);
OperationCallExp asCondition1left = (OperationCallExp) PivotUtil.getOwnedSource(asCondition1);
OperationCallExp asThen = (OperationCallExp) PivotUtil.getOwnedThen(asExpression);
OperationCallExp asElse = (OperationCallExp) PivotUtil.getOwnedElse(asExpression);
VariableExp asConditionVariableExp = (VariableExp) PivotUtil.getOwnedSource(asCondition1left);
VariableExp asThenVariableExp = (VariableExp) PivotUtil.getOwnedSource(asThen);
VariableExp asElseVariableExp = (VariableExp) PivotUtil.getOwnedSource(asElse);
ocl.assertIsNotKnown(asConditionVariableExp);
ocl.assertIsNonNull(asThenVariableExp);
ocl.assertIsNotKnown(asElseVariableExp);
ocl.dispose();
}
public void testFlowAnalysis_DoubleImpliesPropertyGuard() throws Exception {
MyOCL ocl = new MyOCL();
OperationCallExp asImplies = (OperationCallExp) ocl.createTestModel("DoubleImpliesVariableGuard",
"dummy <> null and dummy.dummy <> null implies dummy <> null xor dummy.dummy <> null xor dummy.dummy.dummy <> null");
OperationCallExp asAnd12 = (OperationCallExp) PivotUtil.getOwnedSource(asImplies);
OperationCallExp asGuard1 = (OperationCallExp) PivotUtil.getOwnedSource(asAnd12);
PropertyCallExp asRef1 = (PropertyCallExp) PivotUtil.getOwnedSource(asGuard1);
OperationCallExp asGuard2 = (OperationCallExp) PivotUtil.getOwnedArgument(asAnd12, 0);
PropertyCallExp asRef2 = (PropertyCallExp) PivotUtil.getOwnedSource(asGuard2);
OperationCallExp asOr123 = (OperationCallExp) PivotUtil.getOwnedArgument(asImplies, 0);
OperationCallExp asOr12 = (OperationCallExp) PivotUtil.getOwnedSource(asOr123);
OperationCallExp asOr3 = (OperationCallExp) PivotUtil.getOwnedArgument(asOr123, 0);
OperationCallExp asOr1 = (OperationCallExp) PivotUtil.getOwnedSource(asOr12);
OperationCallExp asOr2 = (OperationCallExp) PivotUtil.getOwnedArgument(asOr12, 0);
PropertyCallExp asUse1 = (PropertyCallExp) PivotUtil.getOwnedSource(asOr1);
PropertyCallExp asUse2 = (PropertyCallExp) PivotUtil.getOwnedSource(asOr2);
PropertyCallExp asUse3 = (PropertyCallExp) PivotUtil.getOwnedSource(asOr3);
ocl.assertIsNotKnown(asRef1);
ocl.assertIsNotKnown(asRef2);
ocl.assertIsNonNull(asUse1);
ocl.assertIsNonNull(asUse2);
ocl.assertIsNotKnown(asUse3);
ocl.dispose();
}
public void testFlowAnalysis_DoubleBiImpliesPropertyGuard() throws Exception {
MyOCL ocl = new MyOCL();
OperationCallExp asImplies = (OperationCallExp) ocl.createTestModel("DoubleBiImpliesVariableGuard",
"dummy <> null and dummy.dummy <> null implies dummy <> null or dummy.dummy <> null or dummy.dummy.dummy <> null");
OperationCallExp asAnd12 = (OperationCallExp) PivotUtil.getOwnedSource(asImplies);
OperationCallExp asGuard1 = (OperationCallExp) PivotUtil.getOwnedSource(asAnd12);
PropertyCallExp asRef1 = (PropertyCallExp) PivotUtil.getOwnedSource(asGuard1);
OperationCallExp asGuard2 = (OperationCallExp) PivotUtil.getOwnedArgument(asAnd12, 0);
PropertyCallExp asRef2 = (PropertyCallExp) PivotUtil.getOwnedSource(asGuard2);
OperationCallExp asOr123 = (OperationCallExp) PivotUtil.getOwnedArgument(asImplies, 0);
OperationCallExp asOr12 = (OperationCallExp) PivotUtil.getOwnedSource(asOr123);
OperationCallExp asOr3 = (OperationCallExp) PivotUtil.getOwnedArgument(asOr123, 0);
OperationCallExp asOr1 = (OperationCallExp) PivotUtil.getOwnedSource(asOr12);
OperationCallExp asOr2 = (OperationCallExp) PivotUtil.getOwnedArgument(asOr12, 0);
PropertyCallExp asUse1 = (PropertyCallExp) PivotUtil.getOwnedSource(asOr1);
PropertyCallExp asUse2 = (PropertyCallExp) PivotUtil.getOwnedSource(asOr2);
PropertyCallExp asUse3 = (PropertyCallExp) PivotUtil.getOwnedSource(asOr3);
ocl.assertIsNull(asRef1);
ocl.assertIsNull(asRef2);
ocl.assertIsNonNull(asUse1);
ocl.assertIsNonNull(asUse2);
ocl.assertIsNotKnown(asUse3);
ocl.dispose();
}
public void testFlowAnalysis_IterationExpressionGuard() throws Exception {
MyOCL ocl = new MyOCL();
OperationCallExp asImplies = (OperationCallExp) ocl.createTestModel("IterationExpressionGuard",
"dummy->select(s | s <> null) <> null implies dummy->select(s | s <> null) = null");
OperationCallExp asStartsWith = (OperationCallExp) PivotUtil.getOwnedArgument(asImplies, 0);
IteratorExp asCompare = (IteratorExp) PivotUtil.getOwnedSource(asStartsWith);
OperationCallExp asSource = (OperationCallExp) PivotUtil.getOwnedSource(asCompare);
ocl.assertIsNonNull(asSource);
ocl.dispose();
}
public void testFlowAnalysis_LetExpressionGuard() throws Exception {
MyOCL ocl = new MyOCL();
OperationCallExp asImplies = (OperationCallExp) ocl.createTestModel("LetExpressionGuard",
"dummy.func(4, let q : Integer = 7 in q) <> null implies dummy.func(4, let y : Integer = 7 in y) = null");
OperationCallExp asStartsWith = (OperationCallExp) PivotUtil.getOwnedArgument(asImplies, 0);
OperationCallExp asCompare = (OperationCallExp) PivotUtil.getOwnedSource(asStartsWith);
ocl.assertIsNonNull(asCompare);
ocl.dispose();
}
public void testFlowAnalysis_OperationExpressionGuard() throws Exception {
MyOCL ocl = new MyOCL();
OperationCallExp asImplies = (OperationCallExp) ocl.createTestModel("OperationExpressionGuard",
"dummy.func(2,5) <> null implies dummy.func(2,5).func(1,5) = null");
OperationCallExp asStartsWith = (OperationCallExp) PivotUtil.getOwnedArgument(asImplies, 0);
OperationCallExp asCompare = (OperationCallExp) PivotUtil.getOwnedSource(asStartsWith);
OperationCallExp asSource = (OperationCallExp) PivotUtil.getOwnedSource(asCompare);
ocl.assertIsNonNull(asSource);
ocl.dispose();
}
}