TypeFox / yang-lsp

A Language Server for YANG
http://www.yang-central.org
Apache License 2.0
51 stars 13 forks source link

Xpath with Asterisk #160

Closed huyuwen closed 4 years ago

huyuwen commented 5 years ago

Here we have a module which has a must xpath expression

module xpath-asterisk {
  namespace xa;
  prefix xa;
  container routings {
    list routing {
        key "name";
        leaf name {
            type string;
        }
        list api {
          key "name";
      leaf name {
            type string;
            must "count(/xa:routings/xa:routing[*]/xa:api[xa:name = current()]) = 1";
          }
       }
    }
  }
}

When yang-lsp loading this xpath, the stack will go through the following methods XpathResolver.computeType() -> XpathResolver.findNodes() findNodes() will return 2 children nodes correctly. [name, api]

But when Linker get the result from resolver.apply() https://github.com/theia-ide/yang-lsp/blob/8c45e2c6320c3192646e067f7aa123a66b23faff/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/scoping/Linker.xtend#L32 The candidate only have one EObjectDescription.

This is due to XpathResolver.getEObjectDescription() only return the head of XpathType.nodes. https://github.com/theia-ide/yang-lsp/blob/8c45e2c6320c3192646e067f7aa123a66b23faff/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/scoping/xpath/XpathResolver.xtend#L475

In this case, * actually only link to the first returned schema node. There will have two consequnces.

  1. Loading result is not correct,
    • -> [The first node]
  2. Serialize result is not correct. Because * link to a wrong node, the serialization result will only output the linked node name back to string. So the final serialization output looks like.
    ...
    list api {
    key "name";
    leaf name {
      type string;
      must "count(/xa:routings/xa:routing[api]/xa:api[xa:name = current()]) = 1";
     }
    }
    ...
spoenemann commented 4 years ago

I submitted a fix for the serialization part (#178).

Why would you like to link all possible nodes to the asterisk? Do you want to find the nodes in the parsed AST? Or is it rather about language server features like go to definition?