|
@@ -6,7 +6,7 @@
|
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
|
* Contributors:
|
|
|
* rbeckmann - initial API and implementation
|
|
|
- *
|
|
|
+ *
|
|
|
*/
|
|
|
package org.yakindu.sct.model.stext.validation;
|
|
|
|
|
@@ -31,12 +31,15 @@ import org.eclipse.xtext.validation.ValidationMessageAcceptor;
|
|
|
* @author rbeckmann
|
|
|
*
|
|
|
*/
|
|
|
-public class STextNamesAreUniqueValidationHelper extends NamesAreUniqueValidationHelper implements INamesAreUniqueValidationHelper {
|
|
|
+public class STextNamesAreUniqueValidationHelper extends NamesAreUniqueValidationHelper
|
|
|
+ implements
|
|
|
+ INamesAreUniqueValidationHelper {
|
|
|
protected OperationCanceledManager operationCanceledManager = new OperationCanceledManager();
|
|
|
|
|
|
protected Map<QualifiedName, IEObjectDescription> nameMap;
|
|
|
protected Map<QualifiedName, IEObjectDescription> caseInsensitiveMap;
|
|
|
-
|
|
|
+ protected Map<String, IEObjectDescription> lastElementMap;
|
|
|
+
|
|
|
@Override
|
|
|
public void checkUniqueNames(Iterable<IEObjectDescription> descriptions, ValidationMessageAcceptor acceptor) {
|
|
|
checkUniqueNames(descriptions, null, acceptor);
|
|
@@ -55,6 +58,7 @@ public class STextNamesAreUniqueValidationHelper extends NamesAreUniqueValidatio
|
|
|
Iterator<IEObjectDescription> iter = descriptions.iterator();
|
|
|
this.nameMap = new HashMap<>();
|
|
|
this.caseInsensitiveMap = new HashMap<>();
|
|
|
+ this.lastElementMap = new HashMap<>();
|
|
|
if (!iter.hasNext())
|
|
|
return;
|
|
|
while (iter.hasNext()) {
|
|
@@ -69,74 +73,88 @@ public class STextNamesAreUniqueValidationHelper extends NamesAreUniqueValidatio
|
|
|
QualifiedName qName = description.getName();
|
|
|
IEObjectDescription put = nameMap.put(qName, description);
|
|
|
IEObjectDescription lowerCasePut = caseInsensitiveMap.put(qName.toLowerCase(), description);
|
|
|
- if(put != null) {
|
|
|
+ IEObjectDescription lastElementPut = lastElementMap.put(qName.getLastSegment(), description);
|
|
|
+ if (put != null) {
|
|
|
EClass common = checkForCommonSuperClass(put, description);
|
|
|
- if(common != null) {
|
|
|
- createDuplicateNameError(description, common, acceptor);
|
|
|
- createDuplicateNameError(put, common, acceptor);
|
|
|
+ if (common != null) {
|
|
|
+ duplicateFQN(description, put, common, acceptor);
|
|
|
}
|
|
|
- } else if(lowerCasePut != null) {
|
|
|
- if(lowerCasePut.getEClass().equals(description.getEClass())) {
|
|
|
- createDuplicateNameWarning(description, description.getEClass(), acceptor);
|
|
|
- createDuplicateNameWarning(lowerCasePut, description.getEClass(), acceptor);
|
|
|
+ } else if (lowerCasePut != null) {
|
|
|
+ if (lowerCasePut.getEClass().equals(description.getEClass())) {
|
|
|
+ duplicateCaseInsensitiveFQN(description, lowerCasePut, acceptor);
|
|
|
}
|
|
|
}
|
|
|
+ if (lastElementPut != null) {
|
|
|
+ duplicateLastElement(description, lastElementPut, acceptor);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void duplicateLastElement(IEObjectDescription description, IEObjectDescription lastElementPut,
|
|
|
+ ValidationMessageAcceptor acceptor) {
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void duplicateCaseInsensitiveFQN(IEObjectDescription description, IEObjectDescription lowerCasePut,
|
|
|
+ ValidationMessageAcceptor acceptor) {
|
|
|
+ createDuplicateNameWarning(description, description.getEClass(), acceptor);
|
|
|
+ createDuplicateNameWarning(lowerCasePut, description.getEClass(), acceptor);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void duplicateFQN(IEObjectDescription description, IEObjectDescription old, EClass common,
|
|
|
+ ValidationMessageAcceptor acceptor) {
|
|
|
+ createDuplicateNameError(description, common, acceptor);
|
|
|
+ createDuplicateNameError(old, common, acceptor);
|
|
|
}
|
|
|
|
|
|
protected void createDuplicateNameWarning(IEObjectDescription description, EClass eClass,
|
|
|
ValidationMessageAcceptor acceptor) {
|
|
|
EObject object = description.getEObjectOrProxy();
|
|
|
EStructuralFeature feature = getNameFeature(object);
|
|
|
- acceptor.acceptWarning(
|
|
|
- getDuplicateNameWarningMessage(description, eClass, feature),
|
|
|
- object,
|
|
|
- feature,
|
|
|
- ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
|
|
|
- getErrorCode());
|
|
|
+ acceptor.acceptWarning(getDuplicateNameWarningMessage(description, eClass, feature), object, feature,
|
|
|
+ ValidationMessageAcceptor.INSIGNIFICANT_INDEX, getErrorCode());
|
|
|
}
|
|
|
|
|
|
protected String getDuplicateNameWarningMessage(IEObjectDescription description, EClass eClass,
|
|
|
EStructuralFeature feature) {
|
|
|
- return getDuplicateNameErrorMessage(description, eClass, feature) + ". Names differ only in case, which can lead to compilation problems.";
|
|
|
+ return getDuplicateNameErrorMessage(description, eClass, feature)
|
|
|
+ + ". Names differ only in case, which can lead to compilation problems.";
|
|
|
}
|
|
|
|
|
|
protected EClass checkForCommonSuperClass(IEObjectDescription one, IEObjectDescription two) {
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
List<EClass> flatOne = buildSuperClassList(one.getEClass());
|
|
|
List<EClass> flatTwo = buildSuperClassList(two.getEClass());
|
|
|
-
|
|
|
- for(EClass eC : flatOne) {
|
|
|
- if(flatTwo.contains(eC))
|
|
|
+
|
|
|
+ for (EClass eC : flatOne) {
|
|
|
+ if (flatTwo.contains(eC))
|
|
|
return eC;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return null;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
protected List<EClass> buildSuperClassList(EClass eClass) {
|
|
|
List<List<EClass>> superClasses = new ArrayList<>();
|
|
|
-
|
|
|
+
|
|
|
buildSuperClassList(superClasses, eClass, 0);
|
|
|
-
|
|
|
+
|
|
|
List<EClass> result = new ArrayList<>();
|
|
|
- for(List<EClass> list : superClasses) {
|
|
|
+ for (List<EClass> list : superClasses) {
|
|
|
result.addAll(list);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return result;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
protected void buildSuperClassList(List<List<EClass>> superClasses, EClass eClass, int depth) {
|
|
|
- if(superClasses.size() <= depth) {
|
|
|
+ if (superClasses.size() <= depth) {
|
|
|
superClasses.add(depth, new ArrayList<>());
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
List<EClass> superTypes = eClass.getESuperTypes();
|
|
|
|
|
|
superClasses.get(depth).add(eClass);
|
|
|
-
|
|
|
- for(EClass superType : superTypes) {
|
|
|
+
|
|
|
+ for (EClass superType : superTypes) {
|
|
|
buildSuperClassList(superClasses, superType, depth + 1);
|
|
|
}
|
|
|
}
|