Question

I've Been Trying to change the order of nodes through quickfix, but something is wrong. Here's my code in xtend:

@Fix(org.xtext.custom.conventions.validation.ConventionsValidator::CONVENTION_NOT_ORDERED)
  def fixFeatureName(  Issue issue,   IssueResolutionAcceptor acceptor){   
    acceptor.accept(issue, 'Sort', "Sort '" + issue.data.head + "'", null)[
      element, context |
        var gr=(element as Greeting)
        if (gr.name === null || gr.name.length === 0)
            return;
        var econt=gr.eContainer.eContents
        var comparator = [ EObject obj1, EObject obj2 |
            var o1 = (obj1 as Greeting)
            var o2 = (obj2 as Greeting)
            return o1.name.compareTo(o2.name)
            ]
        ECollections::sort(econt, comparator)
        ]
      }

No exception is being thrown to console, in debug I found an UnsupportedOperationException is thrown and handled by xtext. I suspect that EList is immutable. So how can I sort the AST?

(Here is the generated code: )

@Fix(ConventionsValidator.CONVENTION_NOT_ORDERED)
  public void fixFeatureName(final Issue issue, final IssueResolutionAcceptor acceptor) {
    String[] _data = issue.getData();
    String _head = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(_data)));
    String _plus = ("Sort \'" + _head);
    String _plus_1 = (_plus + "\'");
    final ISemanticModification _function = new ISemanticModification() {
        public void apply(final EObject element, final IModificationContext context) throws Exception {
          Greeting gr = ((Greeting) element);
          boolean _or = false;
          String _name = gr.getName();
          boolean _tripleEquals = (_name == null);
          if (_tripleEquals) {
            _or = true;
          } else {
            String _name_1 = gr.getName();
            int _length = _name_1.length();
            boolean _tripleEquals_1 = (Integer.valueOf(_length) == Integer.valueOf(0));
            _or = (_tripleEquals || _tripleEquals_1);
          }
          if (_or) {
            return;
          }
          EObject _eContainer = gr.eContainer();
          EList<EObject> econt = _eContainer.eContents();
          final Function2<EObject,EObject,Integer> _function = new Function2<EObject,EObject,Integer>() {
              public Integer apply(final EObject obj1, final EObject obj2) {
                Greeting o1 = ((Greeting) obj1);
                Greeting o2 = ((Greeting) obj2);
                String _name = o1.getName();
                String _name_1 = o2.getName();
                return _name.compareTo(_name_1);
              }
            };
          Function2<EObject,EObject,Integer> comparator = _function;
          final Function2<EObject,EObject,Integer> _converted_comparator = (Function2<EObject,EObject,Integer>)comparator;
          ECollections.<EObject>sort(econt, new Comparator<EObject>() {
              public int compare(EObject o1,EObject o2) {
                return _converted_comparator.apply(o1,o2);
              }
          });
        }
      };
    acceptor.accept(issue, "Sort", _plus_1, null, _function);
  }

thanks!

Was it helpful?

Solution

Sorting a temporary collection which will then replace econt didn't work. but I managed to solve it in a different way.

so one solution was to force a cast of eContainer as it's runtime element (which is Model), and then getting a list with it's getGreetings getter, and with that element the sorting works, but I didn't want to involve non-generic code, for technical reasons.

So after a lot of experiments I finally found that element without involving any other elements or keywords from the grammar:

var econt = (gr.eContainer.eGet(gr.eContainingFeature) as EObjectContainmentEList<Greeting>)

and that is exactly what was looking for. Sorting is successful!

Here's the resulting Xtend code (got rid of casing in the comperator as well):

@Fix(ConventionsValidator::CONVENTION_NOT_ORDERED)
def fixFeatureName(Issue issue, IssueResolutionAcceptor acceptor) {
    acceptor.accept(issue, 'Sort', "Sort '" + issue.data.head + "'", null) [
      element, context |
        var gr = (element as Greeting)
        if (gr.name === null || gr.name.length === 0)
            return;
        var econt = (gr.eContainer.eGet(gr.eContainingFeature) as EObjectContainmentEList<Greeting>)
        var comparator = [ Greeting o1, Greeting o2 |
            return o1.name.compareTo(o2.name)
        ]
        ECollections::sort(econt, comparator)
    ]
}

and the generated java:

@Fix(ConventionsValidator.CONVENTION_NOT_ORDERED)
  public void fixFeatureName(final Issue issue, final IssueResolutionAcceptor acceptor) {
    String[] _data = issue.getData();
    String _head = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(_data)));
    String _plus = ("Sort \'" + _head);
    String _plus_1 = (_plus + "\'");
    final ISemanticModification _function = new ISemanticModification() {
        public void apply(final EObject element, final IModificationContext context) throws Exception {
          Greeting gr = ((Greeting) element);
          boolean _or = false;
          String _name = gr.getName();
          boolean _tripleEquals = (_name == null);
          if (_tripleEquals) {
            _or = true;
          } else {
            String _name_1 = gr.getName();
            int _length = _name_1.length();
            boolean _tripleEquals_1 = (Integer.valueOf(_length) == Integer.valueOf(0));
            _or = (_tripleEquals || _tripleEquals_1);
          }
          if (_or) {
            return;
          }
          EObject _eContainer = gr.eContainer();
          EStructuralFeature _eContainingFeature = gr.eContainingFeature();
          Object _eGet = _eContainer.eGet(_eContainingFeature);
          EObjectContainmentEList<Greeting> econt = ((EObjectContainmentEList<Greeting>) _eGet);
          final Function2<Greeting,Greeting,Integer> _function = new Function2<Greeting,Greeting,Integer>() {
              public Integer apply(final Greeting o1, final Greeting o2) {
                String _name = o1.getName();
                String _name_1 = o2.getName();
                return _name.compareTo(_name_1);
              }
            };
          Function2<Greeting,Greeting,Integer> comparator = _function;
          final Function2<Greeting,Greeting,Integer> _converted_comparator = (Function2<Greeting,Greeting,Integer>)comparator;
          ECollections.<Greeting>sort(econt, new Comparator<Greeting>() {
              public int compare(Greeting o1,Greeting o2) {
                return _converted_comparator.apply(o1,o2);
              }
          });
        }
      };
    acceptor.accept(issue, "Sort", _plus_1, null, _function);
  }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top