/**
* generated by Xtext
*/
package de.unidue.ecg.dialogScript.validation;
import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import de.unidue.ecg.dialogScript.dialogScript.ChoiceDialog;
import de.unidue.ecg.dialogScript.dialogScript.ConditionDefinition;
import de.unidue.ecg.dialogScript.dialogScript.ConditionList;
import de.unidue.ecg.dialogScript.dialogScript.Conditional;
import de.unidue.ecg.dialogScript.dialogScript.ConditionalBody;
import de.unidue.ecg.dialogScript.dialogScript.ConditionalChoiceDialog;
import de.unidue.ecg.dialogScript.dialogScript.Defaults;
import de.unidue.ecg.dialogScript.dialogScript.DialogScriptPackage;
import de.unidue.ecg.dialogScript.dialogScript.Exit;
import de.unidue.ecg.dialogScript.dialogScript.FirstTime;
import de.unidue.ecg.dialogScript.dialogScript.Hub;
import de.unidue.ecg.dialogScript.dialogScript.HubFragment;
import de.unidue.ecg.dialogScript.dialogScript.Jump;
import de.unidue.ecg.dialogScript.dialogScript.Modifier;
import de.unidue.ecg.dialogScript.dialogScript.Otherwise;
import de.unidue.ecg.dialogScript.dialogScript.OtherwiseChoice;
import de.unidue.ecg.dialogScript.dialogScript.Scene;
import de.unidue.ecg.dialogScript.dialogScript.Script;
import de.unidue.ecg.dialogScript.dialogScript.Statement;
import de.unidue.ecg.dialogScript.dialogScript.SwitchDefinition;
import de.unidue.ecg.dialogScript.dialogScript.SwitchOff;
import de.unidue.ecg.dialogScript.dialogScript.SwitchOn;
import de.unidue.ecg.dialogScript.validation.AbstractDialogScriptValidator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.validation.Check;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
/**
* Custom validation rules.
*
* see http://www.eclipse.org/Xtext/documentation.html#validation
*/
@SuppressWarnings("all")
public class DialogScriptValidator extends AbstractDialogScriptValidator {
public final static String EMPTY_SCENE = "emptyScene";
public final static String COMMENT_IN_SCENE = "commentInScene";
public final static String CONDITION_UNKNOWN = "conditionUnknown";
public final static String UNREACHABLE_OTHERWISE_STATEMENT = "unreachableOtherwiseStatement";
public final static String UNREFERENCED_HUB = "unreferencedHub";
public final static String WILDCARD_IN_SCENE_NAME = "wildcardInSceneName";
public final static String WILDCARD_IN_HUB_NAME = "wildcardInHubName";
public final static String WILDCARD_IN_CHOICE_NAME = "wildcardInChoiceName";
public final static String UPPER_CASE_SWTICH_DEFINITION = "upperCaseSwitchDefinition";
public final static String LOWER_CASE_CONDITION_DEFINITION = "lowerCaseConditionDefinition";
public final static String HUB_WITHOUT_CHOICE = "hubWithoutChoice";
public final static String MISPLACED_EXIT_HUB = "misplacedExitHub";
public final static String EMPTY_CHOICE = "emptyChoice";
public final static String HUB_CANNOT_BE_LEFT = "hubCannotBeLeft";
public final static String DUPLICATED_MODIFIER = "duplicatedModifier";
public final static String WRONG_CONDTIONAL_USAGE = "wrongConditionalUsage";
public final static String UNRESOLVED_CHARACTER = "unresolvedCharacter";
public final static String EMPTY_BODY = "emptyBody";
@Check
public void checkHubCanBeLeft(final Hub hub) {
final TreeIterator<EObject> allContents = hub.eAllContents();
boolean _hasNext = allContents.hasNext();
boolean _while = _hasNext;
while (_while) {
EObject _next = allContents.next();
if ((_next instanceof Jump)) {
return;
}
boolean _hasNext_1 = allContents.hasNext();
_while = _hasNext_1;
}
this.warning(
"Its a trap! Hub cannot be left by the player. Add an \"exit- \" or \"enter\"-statement to avoid infinite loops.", hub, DialogScriptPackage.Literals.HUB__NAME, DialogScriptValidator.HUB_CANNOT_BE_LEFT);
}
@Check
public void checkForEmptyChoice(final ChoiceDialog choice) {
ConditionalBody _body = choice.getBody();
boolean _equals = Objects.equal(_body, null);
if (_equals) {
this.warning("Empty choices should be removed.", choice, DialogScriptPackage.Literals.CHOICE_DIALOG__NAME,
DialogScriptValidator.EMPTY_CHOICE);
}
}
@Check
public void checkForLowerCaseSwitches(final SwitchDefinition switchDefinition) {
String _name = switchDefinition.getName();
char _charAt = _name.charAt(0);
boolean _isUpperCase = Character.isUpperCase(_charAt);
if (_isUpperCase) {
this.warning("It is recommended to start switches with a lower case letter", switchDefinition,
DialogScriptPackage.Literals.SWITCH_DEFINITION__NAME, DialogScriptValidator.UPPER_CASE_SWTICH_DEFINITION);
}
}
@Check
public void checkForUpperCaseConditions(final ConditionDefinition conditionDefinition) {
String _name = conditionDefinition.getName();
char _charAt = _name.charAt(0);
boolean _isLowerCase = Character.isLowerCase(_charAt);
if (_isLowerCase) {
this.warning("It is recommended to start conditions with a upper case letter", conditionDefinition,
DialogScriptPackage.Literals.CONDITION_DEFINITION__NAME, DialogScriptValidator.LOWER_CASE_CONDITION_DEFINITION);
}
}
@Check
public void checkForUnreachableOtherwiseStatements(final Conditional conditional) {
EList<Otherwise> _otherwiseList = conditional.getOtherwiseList();
boolean _notEquals = (!Objects.equal(_otherwiseList, null));
if (_notEquals) {
EList<Otherwise> _otherwiseList_1 = conditional.getOtherwiseList();
final Iterator<Otherwise> iterator = _otherwiseList_1.iterator();
boolean _hasNext = iterator.hasNext();
boolean _while = _hasNext;
while (_while) {
{
final Otherwise next = iterator.next();
boolean _and = false;
ConditionList _conditionList = next.getConditionList();
boolean _equals = Objects.equal(_conditionList, null);
if (!_equals) {
_and = false;
} else {
boolean _hasNext_1 = iterator.hasNext();
_and = (_equals && _hasNext_1);
}
if (_and) {
final Otherwise issueElement = iterator.next();
EList<Otherwise> _otherwiseList_2 = conditional.getOtherwiseList();
int _indexOf = _otherwiseList_2.indexOf(issueElement);
this.warning("Unreachable area: Conditional dialog after an unconditional dialog cannot be reached", issueElement, DialogScriptPackage.Literals.OTHERWISE__BODY, _indexOf, DialogScriptValidator.UNREACHABLE_OTHERWISE_STATEMENT);
return;
}
}
boolean _hasNext_1 = iterator.hasNext();
_while = _hasNext_1;
}
}
}
@Check
public void checkForHubsWithoutChoice(final Hub hub) {
EList<HubFragment> _hubFragments = hub.getHubFragments();
final Iterable<ChoiceDialog> choices = Iterables.<ChoiceDialog>filter(_hubFragments, ChoiceDialog.class);
boolean _isEmpty = IterableExtensions.isEmpty(choices);
if (_isEmpty) {
EList<HubFragment> _hubFragments_1 = hub.getHubFragments();
final Iterable<ConditionalChoiceDialog> conditionalChoices = Iterables.<ConditionalChoiceDialog>filter(_hubFragments_1, ConditionalChoiceDialog.class);
boolean _isEmpty_1 = IterableExtensions.isEmpty(conditionalChoices);
if (_isEmpty_1) {
this.error("A hub has to contain at least one choice!", hub, DialogScriptPackage.Literals.HUB__NAME,
DialogScriptValidator.HUB_WITHOUT_CHOICE);
}
}
}
@Check
public void checkForMisplacedExitHubs(final Exit exit) {
boolean _isExitHub = exit.isExitHub();
if (_isExitHub) {
boolean _isInHub = this.isInHub(exit);
boolean _not = (!_isInHub);
if (_not) {
this.error("You are not in a hub, so this statement does not make sense!", exit,
DialogScriptPackage.Literals.EXIT__EXIT_HUB, DialogScriptValidator.MISPLACED_EXIT_HUB);
}
}
}
public boolean isInHub(final EObject element) {
boolean _xifexpression = false;
if ((element instanceof Hub)) {
_xifexpression = true;
} else {
boolean _xifexpression_1 = false;
EObject _eContainer = element.eContainer();
boolean _equals = Objects.equal(_eContainer, null);
if (_equals) {
_xifexpression_1 = false;
} else {
EObject _eContainer_1 = element.eContainer();
boolean _isInHub = this.isInHub(_eContainer_1);
_xifexpression_1 = _isInHub;
}
_xifexpression = _xifexpression_1;
}
return _xifexpression;
}
@Check
public void checkIfHiddenHubIsCalled(final Hub hub) {
boolean _isIsHidden = hub.isIsHidden();
if (_isIsHidden) {
final HashSet<Hub> set = CollectionLiterals.<Hub>newHashSet(hub);
final ArrayList<EObject> result = CollectionLiterals.<EObject>newArrayList();
Script _containerOfType = EcoreUtil2.<Script>getContainerOfType(hub, Script.class);
final EcoreUtil2.ElementReferenceAcceptor _function = new EcoreUtil2.ElementReferenceAcceptor() {
public void accept(final EObject referrer, final EObject referenced, final EReference reference, final int index) {
result.add(referrer);
}
};
EcoreUtil2.findCrossReferences(_containerOfType, set, _function);
boolean _isEmpty = result.isEmpty();
if (_isEmpty) {
String _name = hub.getName();
String _plus = ("Hidden hub " + _name);
String _plus_1 = (_plus +
" is never entered explicitly. As a consequence, its content won\'t be reachable during play. Delete the \'hidden\' modifier or enter the hub from another point in your scene.");
this.warning(_plus_1, hub, DialogScriptPackage.Literals.HUB__NAME, DialogScriptValidator.UNREFERENCED_HUB);
}
}
}
@Check
public void checkForWildcardsInNonDialogLines(final Scene ele) {
String _name = ele.getName();
int _indexOf = _name.indexOf("{");
boolean _greaterThan = (_indexOf > (-1));
if (_greaterThan) {
this.warning("Wildcards can not be processed in a scene name!", ele, DialogScriptPackage.Literals.SCENE__NAME,
DialogScriptValidator.WILDCARD_IN_SCENE_NAME);
}
}
@Check
public void checkForWildcardsInNonDialogLines(final Hub ele) {
String _name = ele.getName();
int _indexOf = _name.indexOf("{");
boolean _greaterThan = (_indexOf > (-1));
if (_greaterThan) {
this.warning("Wildcards can not be processed in a hub name!", ele, DialogScriptPackage.Literals.HUB__NAME,
DialogScriptValidator.WILDCARD_IN_HUB_NAME);
}
}
@Check
public void checkForWildcardsInNonDialogLines(final ChoiceDialog ele) {
String _name = ele.getName();
int _indexOf = _name.indexOf("{");
boolean _greaterThan = (_indexOf > (-1));
if (_greaterThan) {
this.warning("Wildcards can not be processed in a choice name!", ele,
DialogScriptPackage.Literals.CHOICE_DIALOG__NAME, DialogScriptValidator.WILDCARD_IN_CHOICE_NAME);
}
}
@Check
public void checkForModifierDuplicates(final Otherwise ele) {
EList<Modifier> _modifiers = ele.getModifiers();
this.checkForModifierDuplicates(_modifiers, ele, DialogScriptPackage.Literals.OTHERWISE__MODIFIERS);
}
@Check
public void checkForModifierDuplicates(final Conditional ele) {
EList<Modifier> _modifiers = ele.getModifiers();
this.checkForModifierDuplicates(_modifiers, ele, DialogScriptPackage.Literals.CONDITIONAL__MODIFIERS);
}
@Check
public void checkForModifierDuplicates(final ChoiceDialog ele) {
EList<Modifier> _modifiers = ele.getModifiers();
this.checkForModifierDuplicates(_modifiers, ele, DialogScriptPackage.Literals.CHOICE_DIALOG__MODIFIERS);
}
@Check
public void checkForModifierDuplicates(final OtherwiseChoice ele) {
EList<Modifier> _modifiers = ele.getModifiers();
this.checkForModifierDuplicates(_modifiers, ele, DialogScriptPackage.Literals.OTHERWISE_CHOICE__MODIFIERS);
}
@Check
public void checkForModifierDuplicates(final ConditionalChoiceDialog ele) {
EList<Modifier> _modifiers = ele.getModifiers();
this.checkForModifierDuplicates(_modifiers, ele, DialogScriptPackage.Literals.CONDITIONAL_CHOICE_DIALOG__MODIFIERS);
}
public void checkForModifierDuplicates(final List<Modifier> modifiers, final EObject obj, final EStructuralFeature feature) {
final Procedure1<Modifier> _function = new Procedure1<Modifier>() {
public void apply(final Modifier it) {
final int first = modifiers.indexOf(it);
final int last = modifiers.lastIndexOf(it);
if ((first != last)) {
DialogScriptValidator.this.error("You cannot use a modifier several times", obj, feature, last, DialogScriptValidator.DUPLICATED_MODIFIER);
}
}
};
IterableExtensions.<Modifier>forEach(modifiers, _function);
}
/**
* WHY!?
* @Check
* def checkForCorrectConditionalsInHub(Conditional ele) {
* if (ele.eContainer instanceof Hub) {
* val hub = ele.eContainer as Hub
* if (!ele.modifiers.contains(Modifier.SINGLE) &&
* (ele.body == null || ele.body != null && ele.body.jump == null)) {
* error(
* 'Inside a hub, conditionals have to be either declared as \'single\' or has to exit the hub explicitly using a \'exit\' or \'enter\' statement',
* hub, DialogScriptPackage.Literals.HUB__CHOICE_DIALOGS, hub.choiceDialogs.indexOf(ele),
* WRONG_CONDTIONAL_USAGE, hub.choiceDialogs.indexOf(ele).toString)
* }
* }
* }
*/
@Check
public void checkForEmptyElseBody(final Otherwise ele) {
boolean _or = false;
ConditionList _conditionList = ele.getConditionList();
boolean _equals = Objects.equal(_conditionList, null);
if (_equals) {
_or = true;
} else {
ConditionList _conditionList_1 = ele.getConditionList();
EList<ConditionDefinition> _conditions = _conditionList_1.getConditions();
boolean _isEmpty = _conditions.isEmpty();
_or = (_equals || _isEmpty);
}
if (_or) {
EObject _eContainer = ele.eContainer();
final Conditional conditional = ((Conditional) _eContainer);
final ConditionalBody body = ele.getBody();
boolean _isEmpty_1 = this.isEmpty(body);
if (_isEmpty_1) {
EList<Otherwise> _otherwiseList = conditional.getOtherwiseList();
int _indexOf = _otherwiseList.indexOf(ele);
EList<Otherwise> _otherwiseList_1 = conditional.getOtherwiseList();
int _indexOf_1 = _otherwiseList_1.indexOf(ele);
String _string = Integer.valueOf(_indexOf_1).toString();
this.warning("Empty else-path detected. Will be ignored!", conditional,
DialogScriptPackage.Literals.CONDITIONAL__OTHERWISE_LIST, _indexOf,
DialogScriptValidator.EMPTY_BODY, _string);
}
}
}
@Check
public void checkForEmptyDefaultsBody(final Defaults ele) {
final ConditionalBody body = ele.getBody();
boolean _isEmpty = this.isEmpty(body);
if (_isEmpty) {
EObject _eContainer = ele.eContainer();
this.warning("Empty body detected. Will be ignored!", _eContainer,
DialogScriptPackage.Literals.DIALOG__DEFAULTS, DialogScriptValidator.EMPTY_BODY);
}
}
@Check
public void checkForEmptyDefaultsBody(final FirstTime ele) {
final ConditionalBody body = ele.getBody();
boolean _isEmpty = this.isEmpty(body);
if (_isEmpty) {
EObject _eContainer = ele.eContainer();
this.warning("Empty body detected. Will be ignored!", _eContainer,
DialogScriptPackage.Literals.DIALOG__FIRST_TIME, DialogScriptValidator.EMPTY_BODY);
}
}
private boolean isEmpty(final ConditionalBody body) {
boolean _or = false;
boolean _equals = Objects.equal(body, null);
if (_equals) {
_or = true;
} else {
boolean _and = false;
boolean _and_1 = false;
boolean _and_2 = false;
EList<Statement> _statements = body.getStatements();
boolean _isEmpty = _statements.isEmpty();
if (!_isEmpty) {
_and_2 = false;
} else {
SwitchOn _switchOn = body.getSwitchOn();
boolean _equals_1 = Objects.equal(_switchOn, null);
_and_2 = (_isEmpty && _equals_1);
}
if (!_and_2) {
_and_1 = false;
} else {
SwitchOff _switchOff = body.getSwitchOff();
boolean _equals_2 = Objects.equal(_switchOff, null);
_and_1 = (_and_2 && _equals_2);
}
if (!_and_1) {
_and = false;
} else {
Jump _jump = body.getJump();
boolean _equals_3 = Objects.equal(_jump, null);
_and = (_and_1 && _equals_3);
}
_or = (_equals || _and);
}
if (_or) {
return true;
}
return false;
}
}