1

我一直在尝试通过 quickfix 来改变节点的顺序,但是出了点问题。这是我在 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)
        ]
      }

没有向控制台抛出异常,在调试中我发现 UnsupportedOperationException 被抛出并由 xtext 处理。我怀疑 EList 是不可变的。那么如何对 AST 进行排序呢?

(这里是生成的代码:)

@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);
  }

谢谢!

4

1 回答 1

1

对将替换的临时集合进行排序econt不起作用。但我设法以不同的方式解决了它。

所以一种解决方案是强制转换eContainer它的运行时元素(即Model),然后使用它的getGreetingsgetter 获取一个列表,并使用该元素进行排序,但我不想涉及非通用代码,用于技术原因。

所以经过大量实验后,我终于找到了该元素,而不涉及语法中的任何其他元素或关键字:

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

这正是我们想要的。排序成功!

这是生成的 Xtend 代码(也去掉了比较器中的大小写):

@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)
    ]
}

和生成的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);
  }
于 2013-11-08T01:31:16.697 回答