Skip to content

Commit 0251242

Browse files
committed
Remove isCompatible and add new unit tests
1 parent bc4986f commit 0251242

File tree

7 files changed

+41
-84
lines changed

7 files changed

+41
-84
lines changed

plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/staticanalyser/EolStaticAnalyser.java

Lines changed: 19 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public void visit(AssignmentStatement assignmentStatement) {
162162
if (valueType instanceof EolModelElementType && ((EolModelElementType) valueType).getMetaClass() != null)
163163
valueType = new EolModelElementType(((EolModelElementType) valueType).getMetaClass());
164164

165-
if (!(isCompatible(targetType, valueType))) {
165+
if (!targetType.isAncestorOf(valueType)) {
166166
if (canBeCompatible(targetType, valueType)) {
167167
createTypeCompatibilityWarning(targetExpression, valueExpression);
168168
}
@@ -739,29 +739,31 @@ public void visit(OperationCallExpression operationCallExpression) {
739739
for (IStaticOperation op : resolvedOperations) {
740740
resolvedOperationContextTypes.add(op.getContextType());
741741
}
742-
742+
743+
// If the contextType is a UnionType all containedTypes must be handled
743744
if (contextType instanceof EolUnionType) {
744-
if (resolvedOperationContextTypes.containsAll(((EolUnionType)contextType).containedTypes)){
745-
return;
746-
}
747-
}
748-
else {
749-
if (resolvedOperationContextTypes.contains(contextType)) {
750-
return;
751-
}
752-
}
753-
754-
// TODO: get descendants?
755-
for (EolType t : contextType.getChildrenTypes()) {
756-
if (!resolvedOperationContextTypes.contains(t)) {
745+
outerLoop: for (EolType t : ((EolUnionType) contextType).containedTypes) {
746+
for (EolType a : t.getAncestors()) {
747+
if (resolvedOperationContextTypes.contains(a)) {
748+
continue outerLoop;
749+
}
750+
}
757751
warnings.add(
758752
new ModuleMarker(
759753
operationCallExpression, "Operation " + nameExpression.getName()
760754
+ " is undefined for subtype " + t.getName() + " of " + contextType.getName(),
761755
Severity.Warning));
762756
}
757+
} else {
758+
for (EolType a : contextType.getAncestors()) {
759+
if (resolvedOperationContextTypes.contains(a)) {
760+
return;
761+
}
762+
}
763+
warnings.add(new ModuleMarker(operationCallExpression,
764+
"Operation " + nameExpression.getName() + " is undefined for type " + contextType.getName(),
765+
Severity.Warning));
763766
}
764-
765767
}
766768

767769
@Override
@@ -936,7 +938,7 @@ public void visit(ReturnStatement returnStatement) {
936938
setReturnFlag(((Operation) parent), true);
937939
EolType requiredReturnType = (EolType) parent.getData().get("returnType");
938940

939-
if (!(isCompatible(requiredReturnType, providedReturnType))) {
941+
if (!requiredReturnType.isAncestorOf(providedReturnType)) {
940942
if (canBeCompatible(requiredReturnType, providedReturnType))
941943
warnings.add(new ModuleMarker(returnedExpression, "Return type might be " + requiredReturnType
942944
+ " instead of " + getResolvedType(returnedExpression), Severity.Warning));
@@ -1277,73 +1279,6 @@ public void createTypeCompatibilityError(Expression requiredExpression, Expressi
12771279
Severity.Error));
12781280
}
12791281

1280-
public boolean isCompatible(EolType targetType, EolType valueType) {
1281-
1282-
if (targetType.equals(EolNoType.Instance) || valueType.equals(EolNoType.Instance)) {
1283-
return false;
1284-
}
1285-
1286-
if (valueType instanceof EolUnionType) {
1287-
for (EolType t : ((EolUnionType)valueType).containedTypes) {
1288-
while(true) {
1289-
if (t instanceof EolAnyType) {
1290-
return false;
1291-
}
1292-
if (!t.equals(targetType)) {
1293-
t = getParentType(t);
1294-
} else {
1295-
break;
1296-
}
1297-
}
1298-
}
1299-
return true;
1300-
}
1301-
1302-
while (true) {
1303-
if (!(targetType.equals(valueType)) && !(targetType instanceof EolAnyType)) {
1304-
1305-
if (valueType instanceof EolAnyType) {
1306-
return false;
1307-
}
1308-
1309-
valueType = getParentType(valueType);
1310-
1311-
} else if (targetType instanceof EolAnyType) {
1312-
return true;
1313-
} else if (valueType instanceof EolCollectionType
1314-
&& !((((EolCollectionType) targetType).getContentType()) instanceof EolAnyType)) {
1315-
1316-
EolType valueContentType = ((EolCollectionType) valueType).getContentType();
1317-
EolType targetContentType = ((EolCollectionType) targetType).getContentType();
1318-
1319-
while (targetContentType instanceof EolCollectionType
1320-
&& valueContentType instanceof EolCollectionType) {
1321-
if (targetContentType.equals(valueContentType)) {
1322-
return isCompatible(((EolCollectionType) targetContentType).getContentType(),
1323-
((EolCollectionType) valueContentType).getContentType());
1324-
} else {
1325-
valueContentType = getParentType(valueContentType);
1326-
return isCompatible(targetContentType, valueContentType);
1327-
1328-
}
1329-
}
1330-
while (true) {
1331-
if (valueContentType instanceof EolAnyType) {
1332-
return false;
1333-
}
1334-
if (!valueContentType.equals(targetContentType)) {
1335-
valueContentType = getParentType(valueContentType);
1336-
} else {
1337-
return true;
1338-
}
1339-
}
1340-
}else {
1341-
return true;
1342-
}
1343-
1344-
}
1345-
}
1346-
13471282
public boolean canBeCompatible(EolType targetType, EolType valueType) {
13481283

13491284
if (targetType == null || valueType == null) {

plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/staticanalyser/types/EolUnionType.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ public String toString() {
3131
return containedTypes.stream().map(t -> t.toString()).collect(Collectors.joining("|"));
3232
}
3333

34+
@Override
35+
public List<EolType> getParentTypes(){
36+
return new ArrayList<EolType>(containedTypes);
37+
}
38+
3439
@Override
3540
public List<EolType> getChildrenTypes(){
3641
List<EolType> children = new ArrayList<EolType>();

tests/org.eclipse.epsilon.eol.staticanalyser.tests/src/org/eclipse/epsilon/eol/staticanalyser/tests/meta1.ecore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
</eClassifiers>
1212
<eClassifiers xsi:type="ecore:EClass" name="B" eSuperTypes="#//A"/>
1313
<eClassifiers xsi:type="ecore:EClass" name="C" eSuperTypes="#//A"/>
14+
<eClassifiers xsi:type="ecore:EClass" name="D" eSuperTypes="#//B"/>
1415
</ecore:EPackage>

tests/org.eclipse.epsilon.eol.staticanalyser.tests/src/org/eclipse/epsilon/eol/staticanalyser/tests/meta1.emf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ class B extends A {
1515
class C extends A {
1616
}
1717

18+
class D extends B{
19+
}
20+
1821

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
model M driver EMF {nsuri='sa'};
2+
3+
var v1:B;
4+
v1.foo();
5+
6+
operation A foo() : A {return self;}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//!Sequence<Integer> cannot be assigned to Sequence<A>
2+
model M driver EMF {nsuri='sa'};
3+
4+
var v:Sequence<A> = Sequence{1,2,3};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
model M driver EMF {nsuri='sa'};
2+
3+
var v:Sequence<A> = new Sequence<B>;

0 commit comments

Comments
 (0)