【问题标题】:sorting xtext AST through quickfix通过 quickfix 对 xtext AST 进行排序
【发布时间】:2013-11-08 09:31:16
【问题描述】:

我一直在尝试通过 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);
  }

谢谢!

【问题讨论】:

    标签: eclipse sorting xtext xtend


    【解决方案1】:

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

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

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

    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-03-15
      • 2014-10-17
      • 2020-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-07
      • 2015-01-24
      相关资源
      最近更新 更多