/**
* generated by Xtext
*/
package org.example.smalljava.validation;
import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.validation.Check;
import org.eclipse.xtext.validation.CheckType;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.example.smalljava.scoping.SmallJavaIndex;
import org.example.smalljava.smallJava.SJAccessLevel;
import org.example.smalljava.smallJava.SJBlock;
import org.example.smalljava.smallJava.SJClass;
import org.example.smalljava.smallJava.SJExpression;
import org.example.smalljava.smallJava.SJField;
import org.example.smalljava.smallJava.SJMember;
import org.example.smalljava.smallJava.SJMemberSelection;
import org.example.smalljava.smallJava.SJMethod;
import org.example.smalljava.smallJava.SJMethodBody;
import org.example.smalljava.smallJava.SJParameter;
import org.example.smalljava.smallJava.SJProgram;
import org.example.smalljava.smallJava.SJReturn;
import org.example.smalljava.smallJava.SJStatement;
import org.example.smalljava.smallJava.SJSuper;
import org.example.smalljava.smallJava.SJVariableDeclaration;
import org.example.smalljava.smallJava.SmallJavaPackage;
import org.example.smalljava.typing.SmallJavaTypeConformance;
import org.example.smalljava.typing.SmallJavaTypeProvider;
import org.example.smalljava.util.SmallJavaModelUtil;
import org.example.smalljava.validation.AbstractSmallJavaValidator;
import org.example.smalljava.validation.SmallJavaAccessibility;
/**
* Custom validation rules.
*
* see http://www.eclipse.org/Xtext/documentation.html#validation
*/
@SuppressWarnings("all")
public class SmallJavaValidator extends AbstractSmallJavaValidator {
@Inject
@Extension
private SmallJavaIndex _smallJavaIndex;
@Inject
@Extension
private SmallJavaTypeProvider _smallJavaTypeProvider;
@Inject
@Extension
private SmallJavaTypeConformance _smallJavaTypeConformance;
@Inject
@Extension
private SmallJavaAccessibility _smallJavaAccessibility;
@Inject
@Extension
private IQualifiedNameProvider _iQualifiedNameProvider;
public final static String HIERARCHY_CYCLE = "org.example.smalljava.HierarchyCycle";
public final static String DUPLICATE_CLASS = "org.example.smalljava.DuplicateClass";
public final static String MEMBER_NOT_ACCESSIBLE = "org.example.smalljava.MemberNotAccessible";
public final static String METHOD_INVOCATION_ON_FIELD = "org.example.smalljava.MethodInvocationOnField";
public final static String FIELD_SELECTION_ON_METHOD = "org.example.smalljava.FieldSelectionOnMethod";
public final static String INCOMPATIBLE_TYPES = "org.example.smalljava.IncompatibleTypes";
public final static String DUPLICATE_ELEMENT = "org.example.smalljava.DuplicateElement";
public final static String UNREACHABLE_CODE = "org.example.smalljava.UnreachableCode";
public final static String MISSING_FINAL_RETURN = "org.example.smalljava.MissingFinalReturn";
public final static String INVALID_ARGS = "org.example.smalljava.InvalidArgs";
public final static String WRONG_METHOD_OVERRIDE = "org.example.smalljava.WrongMethodOverride";
public final static String WRONG_SUPER_USAGE = "org.example.smalljava.WrongSuperUsage";
@Check
public void checkClassHierarchy(final SJClass c) {
ArrayList<SJClass> _classHierarchy = SmallJavaModelUtil.classHierarchy(c);
boolean _contains = _classHierarchy.contains(c);
if (_contains) {
String _name = c.getName();
String _plus = ("cycle in hierarchy of class \'" + _name);
String _plus_1 = (_plus + "\'");
EReference _sJClass_Superclass = SmallJavaPackage.eINSTANCE.getSJClass_Superclass();
SJClass _superclass = c.getSuperclass();
String _name_1 = _superclass.getName();
this.error(_plus_1, _sJClass_Superclass,
SmallJavaValidator.HIERARCHY_CYCLE, _name_1);
}
}
@Check(CheckType.NORMAL)
public void checkDuplicateClassesInFiles(final SJClass c) {
final QualifiedName className = this._iQualifiedNameProvider.getFullyQualifiedName(c);
Iterable<IEObjectDescription> _visibleClassesDescriptions = this._smallJavaIndex.getVisibleClassesDescriptions(c);
final Procedure1<IEObjectDescription> _function = new Procedure1<IEObjectDescription>() {
@Override
public void apply(final IEObjectDescription desc) {
boolean _and = false;
boolean _and_1 = false;
QualifiedName _qualifiedName = desc.getQualifiedName();
boolean _equals = Objects.equal(_qualifiedName, className);
if (!_equals) {
_and_1 = false;
} else {
EObject _eObjectOrProxy = desc.getEObjectOrProxy();
boolean _notEquals = (!Objects.equal(_eObjectOrProxy, c));
_and_1 = _notEquals;
}
if (!_and_1) {
_and = false;
} else {
URI _eObjectURI = desc.getEObjectURI();
URI _trimFragment = _eObjectURI.trimFragment();
Resource _eResource = c.eResource();
URI _uRI = _eResource.getURI();
boolean _notEquals_1 = (!Objects.equal(_trimFragment, _uRI));
_and = _notEquals_1;
}
if (_and) {
String _name = c.getName();
String _plus = ("The type " + _name);
String _plus_1 = (_plus + " is already defined");
EAttribute _sJClass_Name = SmallJavaPackage.eINSTANCE.getSJClass_Name();
SmallJavaValidator.this.error(_plus_1, _sJClass_Name,
SmallJavaValidator.DUPLICATE_CLASS);
return;
}
}
};
IterableExtensions.<IEObjectDescription>forEach(_visibleClassesDescriptions, _function);
}
@Check
public void checkAccessibility(final SJMemberSelection sel) {
final SJMember member = sel.getMember();
boolean _and = false;
boolean _and_1 = false;
boolean _notEquals = (!Objects.equal(member, null));
if (!_notEquals) {
_and_1 = false;
} else {
boolean _isAccessibleFrom = this._smallJavaAccessibility.isAccessibleFrom(member, sel);
boolean _not = (!_isAccessibleFrom);
_and_1 = _not;
}
if (!_and_1) {
_and = false;
} else {
String _name = member.getName();
boolean _notEquals_1 = (!Objects.equal(_name, null));
_and = _notEquals_1;
}
if (_and) {
StringConcatenation _builder = new StringConcatenation();
_builder.append("The ");
SJAccessLevel _access = member.getAccess();
_builder.append(_access, "");
_builder.append(" member ");
String _name_1 = member.getName();
_builder.append(_name_1, "");
_builder.append(" is not accessible here");
EReference _sJMemberSelection_Member = SmallJavaPackage.eINSTANCE.getSJMemberSelection_Member();
this.error(_builder.toString(), _sJMemberSelection_Member,
SmallJavaValidator.MEMBER_NOT_ACCESSIBLE);
}
}
@Check
public void checkMemberSelection(final SJMemberSelection sel) {
final SJMember member = sel.getMember();
boolean _notEquals = (!Objects.equal(member, null));
if (_notEquals) {
boolean _and = false;
if (!(member instanceof SJField)) {
_and = false;
} else {
boolean _isMethodinvocation = sel.isMethodinvocation();
_and = _isMethodinvocation;
}
if (_and) {
StringConcatenation _builder = new StringConcatenation();
_builder.append("Method invocation on a field");
EAttribute _sJMemberSelection_Methodinvocation = SmallJavaPackage.eINSTANCE.getSJMemberSelection_Methodinvocation();
this.error(_builder.toString(), _sJMemberSelection_Methodinvocation,
SmallJavaValidator.METHOD_INVOCATION_ON_FIELD);
}
boolean _and_1 = false;
if (!(member instanceof SJMethod)) {
_and_1 = false;
} else {
boolean _isMethodinvocation_1 = sel.isMethodinvocation();
boolean _not = (!_isMethodinvocation_1);
_and_1 = _not;
}
if (_and_1) {
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("Field selection on a method");
EReference _sJMemberSelection_Member = SmallJavaPackage.eINSTANCE.getSJMemberSelection_Member();
this.error(_builder_1.toString(), _sJMemberSelection_Member,
SmallJavaValidator.FIELD_SELECTION_ON_METHOD);
}
}
}
@Check
public void checkCompatibleTypes(final SJExpression exp) {
final SJClass actualType = this._smallJavaTypeProvider.typeFor(exp);
final SJClass expectedType = this._smallJavaTypeProvider.expectedType(exp);
boolean _or = false;
boolean _equals = Objects.equal(expectedType, null);
if (_equals) {
_or = true;
} else {
boolean _equals_1 = Objects.equal(actualType, null);
_or = _equals_1;
}
if (_or) {
return;
}
boolean _isConformant = this._smallJavaTypeConformance.isConformant(actualType, expectedType);
boolean _not = (!_isConformant);
if (_not) {
String _name = null;
if (expectedType!=null) {
_name=expectedType.getName();
}
String _plus = ("Incompatible types. Expected \'" + _name);
String _plus_1 = (_plus + "\' but was \'");
String _name_1 = null;
if (actualType!=null) {
_name_1=actualType.getName();
}
String _plus_2 = (_plus_1 + _name_1);
String _plus_3 = (_plus_2 + "\'");
this.error(_plus_3, null,
SmallJavaValidator.INCOMPATIBLE_TYPES);
}
}
@Check
public void checkMethodInvocationArguments(final SJMemberSelection sel) {
boolean _and = false;
SJMember _member = sel.getMember();
boolean _notEquals = (!Objects.equal(_member, null));
if (!_notEquals) {
_and = false;
} else {
SJMember _member_1 = sel.getMember();
_and = (_member_1 instanceof SJMethod);
}
if (_and) {
SJMember _member_2 = sel.getMember();
final SJMethod method = ((SJMethod) _member_2);
EList<SJParameter> _params = method.getParams();
int _size = _params.size();
EList<SJExpression> _args = sel.getArgs();
int _size_1 = _args.size();
boolean _notEquals_1 = (_size != _size_1);
if (_notEquals_1) {
String _memberAsStringWithType = SmallJavaModelUtil.memberAsStringWithType(method);
String _plus = ("Invalid number of arguments. The method " + _memberAsStringWithType);
String _plus_1 = (_plus +
" is not applicable for the arguments ");
String _argsTypesAsStrings = this._smallJavaTypeProvider.argsTypesAsStrings(sel);
String _plus_2 = (_plus_1 + _argsTypesAsStrings);
EReference _sJMemberSelection_Member = SmallJavaPackage.eINSTANCE.getSJMemberSelection_Member();
this.error(_plus_2, _sJMemberSelection_Member,
SmallJavaValidator.INVALID_ARGS);
}
}
}
@Check
public void checkNoDuplicateVariable(final SJVariableDeclaration vardecl) {
SJMethod _containingMethod = SmallJavaModelUtil.containingMethod(vardecl);
SJMethodBody _body = _containingMethod.getBody();
List<SJVariableDeclaration> _allContentsOfType = EcoreUtil2.<SJVariableDeclaration>getAllContentsOfType(_body, SJVariableDeclaration.class);
final Function1<SJVariableDeclaration, Boolean> _function = new Function1<SJVariableDeclaration, Boolean>() {
@Override
public Boolean apply(final SJVariableDeclaration it) {
boolean _and = false;
boolean _notEquals = (!Objects.equal(it, vardecl));
if (!_notEquals) {
_and = false;
} else {
String _name = it.getName();
String _name_1 = vardecl.getName();
boolean _equals = Objects.equal(_name, _name_1);
_and = _equals;
}
return Boolean.valueOf(_and);
}
};
final SJVariableDeclaration duplicate = IterableExtensions.<SJVariableDeclaration>findFirst(_allContentsOfType, _function);
boolean _notEquals = (!Objects.equal(duplicate, null));
if (_notEquals) {
String _name = vardecl.getName();
String _plus = ("Duplicate variable declaration \'" + _name);
String _plus_1 = (_plus + "\'");
EAttribute _sJSymbol_Name = SmallJavaPackage.eINSTANCE.getSJSymbol_Name();
this.error(_plus_1, _sJSymbol_Name,
SmallJavaValidator.DUPLICATE_ELEMENT);
}
}
@Check
public void checkNoDuplicateMember(final SJMember member) {
SJClass _containingClass = SmallJavaModelUtil.containingClass(member);
EList<SJMember> _members = _containingClass.getMembers();
final Function1<SJMember, Boolean> _function = new Function1<SJMember, Boolean>() {
@Override
public Boolean apply(final SJMember it) {
boolean _and = false;
boolean _and_1 = false;
boolean _notEquals = (!Objects.equal(it, member));
if (!_notEquals) {
_and_1 = false;
} else {
EClass _eClass = it.eClass();
EClass _eClass_1 = member.eClass();
boolean _equals = Objects.equal(_eClass, _eClass_1);
_and_1 = _equals;
}
if (!_and_1) {
_and = false;
} else {
String _name = it.getName();
String _name_1 = member.getName();
boolean _equals_1 = Objects.equal(_name, _name_1);
_and = _equals_1;
}
return Boolean.valueOf(_and);
}
};
final SJMember duplicate = IterableExtensions.<SJMember>findFirst(_members, _function);
boolean _notEquals = (!Objects.equal(duplicate, null));
if (_notEquals) {
String _name = member.getName();
String _plus = ("Duplicate member \'" + _name);
String _plus_1 = (_plus + "\'");
EAttribute _sJMember_Name = SmallJavaPackage.eINSTANCE.getSJMember_Name();
this.error(_plus_1, _sJMember_Name,
SmallJavaValidator.DUPLICATE_ELEMENT);
}
}
@Check
public void checkNoDuplicateClass(final SJClass c) {
SJProgram _containingProgram = SmallJavaModelUtil.containingProgram(c);
EList<SJClass> _classes = _containingProgram.getClasses();
final Function1<SJClass, Boolean> _function = new Function1<SJClass, Boolean>() {
@Override
public Boolean apply(final SJClass it) {
boolean _and = false;
boolean _notEquals = (!Objects.equal(it, c));
if (!_notEquals) {
_and = false;
} else {
String _name = it.getName();
String _name_1 = c.getName();
boolean _equals = Objects.equal(_name, _name_1);
_and = _equals;
}
return Boolean.valueOf(_and);
}
};
boolean _exists = IterableExtensions.<SJClass>exists(_classes, _function);
if (_exists) {
String _name = c.getName();
String _plus = ("Duplicate class \'" + _name);
String _plus_1 = (_plus + "\'");
EAttribute _sJClass_Name = SmallJavaPackage.eINSTANCE.getSJClass_Name();
this.error(_plus_1, _sJClass_Name,
SmallJavaValidator.DUPLICATE_ELEMENT);
}
}
@Check
public void checkNoStatementAfterReturn(final SJReturn ret) {
SJBlock _containingBlock = SmallJavaModelUtil.containingBlock(ret);
final EList<SJStatement> statements = _containingBlock.getStatements();
SJStatement _last = IterableExtensions.<SJStatement>last(statements);
boolean _notEquals = (!Objects.equal(_last, ret));
if (_notEquals) {
int _indexOf = statements.indexOf(ret);
int _plus = (_indexOf + 1);
SJStatement _get = statements.get(_plus);
this.error("Unreachable code", _get,
null,
SmallJavaValidator.UNREACHABLE_CODE);
}
}
@Check
public void checkMethodEndsWithReturn(final SJMethod method) {
SJReturn _returnStatement = SmallJavaModelUtil.returnStatement(method);
boolean _equals = Objects.equal(_returnStatement, null);
if (_equals) {
EReference _sJMethod_Body = SmallJavaPackage.eINSTANCE.getSJMethod_Body();
this.error("Method must end with a return statement", _sJMethod_Body,
SmallJavaValidator.MISSING_FINAL_RETURN);
}
}
@Check
public void checkMethodOverride(final SJMethod m) {
SJClass _containingClass = SmallJavaModelUtil.containingClass(m);
ArrayList<SJClass> _classHierarchy = SmallJavaModelUtil.classHierarchy(_containingClass);
final Function1<SJClass, Iterable<SJMethod>> _function = new Function1<SJClass, Iterable<SJMethod>>() {
@Override
public Iterable<SJMethod> apply(final SJClass it) {
return SmallJavaModelUtil.methods(it);
}
};
List<Iterable<SJMethod>> _map = ListExtensions.<SJClass, Iterable<SJMethod>>map(_classHierarchy, _function);
Iterable<SJMethod> _flatten = Iterables.<SJMethod>concat(_map);
final Function1<SJMethod, Boolean> _function_1 = new Function1<SJMethod, Boolean>() {
@Override
public Boolean apply(final SJMethod it) {
String _name = it.getName();
String _name_1 = m.getName();
return Boolean.valueOf(Objects.equal(_name, _name_1));
}
};
final SJMethod overridden = IterableExtensions.<SJMethod>findFirst(_flatten, _function_1);
boolean _notEquals = (!Objects.equal(overridden, null));
if (_notEquals) {
boolean _or = false;
SJClass _type = m.getType();
SJClass _type_1 = overridden.getType();
boolean _isConformant = this._smallJavaTypeConformance.isConformant(_type, _type_1);
boolean _not = (!_isConformant);
if (_not) {
_or = true;
} else {
EList<SJParameter> _params = m.getParams();
final Function1<SJParameter, SJClass> _function_2 = new Function1<SJParameter, SJClass>() {
@Override
public SJClass apply(final SJParameter it) {
return it.getType();
}
};
List<SJClass> _map_1 = ListExtensions.<SJParameter, SJClass>map(_params, _function_2);
EList<SJParameter> _params_1 = overridden.getParams();
final Function1<SJParameter, SJClass> _function_3 = new Function1<SJParameter, SJClass>() {
@Override
public SJClass apply(final SJParameter it) {
return it.getType();
}
};
List<SJClass> _map_2 = ListExtensions.<SJParameter, SJClass>map(_params_1, _function_3);
boolean _elementsEqual = IterableExtensions.elementsEqual(_map_1, _map_2);
boolean _not_1 = (!_elementsEqual);
_or = _not_1;
}
if (_or) {
StringConcatenation _builder = new StringConcatenation();
_builder.append("The method \'");
String _name = m.getName();
_builder.append(_name, "");
_builder.append("\' must override a superclass method");
EReference _sJMember_Type = SmallJavaPackage.eINSTANCE.getSJMember_Type();
this.error(_builder.toString(), _sJMember_Type,
SmallJavaValidator.WRONG_METHOD_OVERRIDE);
}
}
}
@Check
public void checkSuper(final SJSuper s) {
EStructuralFeature _eContainingFeature = s.eContainingFeature();
EReference _sJMemberSelection_Receiver = SmallJavaPackage.eINSTANCE.getSJMemberSelection_Receiver();
boolean _notEquals = (!Objects.equal(_eContainingFeature, _sJMemberSelection_Receiver));
if (_notEquals) {
this.error("\'super\' can be used only as member selection receiver",
null, SmallJavaValidator.WRONG_SUPER_USAGE);
}
}
}