ソースを参照

uareference: navigate to all references directly

Martin Kunz 1 年間 前
コミット
87cb29c54f
共有4 個のファイルを変更した50 個の追加30 個の削除を含む
  1. 3 2
      src/components/TreeItem.vue
  2. 31 16
      src/ua/UABaseNode.ts
  3. 2 2
      src/ua/UANodeSet.ts
  4. 14 10
      src/ua/UAReference.ts

+ 3 - 2
src/components/TreeItem.vue

@@ -10,7 +10,8 @@ const props = defineProps({
 
 const isOpen = ref(false)
 const isFolder = computed(() => {
-  return props.model?.children && props.model.children.length
+  const children=props.model?.getChildren();
+  return children &&children.length;
 })
 
 function toggle() {
@@ -34,7 +35,7 @@ function selectNode(node: UABaseNode) {
       <TreeItem
         class="item"
         @click.stop="selectNode(child)"
-        v-for="child in model.children"
+        v-for="child in model.getChildren()"
         v-bind:key="child.nodeId.toString()"
         :model="child">
       </TreeItem>

+ 31 - 16
src/ua/UABaseNode.ts

@@ -5,13 +5,14 @@ import { assert } from "@/util/assert";
 import { XMLElem, type IToXML } from "@/util/XmlElem";
 
 export class UABaseNode implements IToXML{
-    children: UABaseNode[]=[];
     constructor(public nodeId: NodeId,
                 public browseName: string,
                 public displayName: string,
                 public references: UAReference[]) {
     }
 
+    public static nullBaseNode=new UABaseNode(NodeId.nullNodeId,"","",[]);
+
     reIndex(nst: NamespaceTable, onst: NamespaceTable) {
         const nsName=onst.getUri(this.nodeId.namespace);
         assert(nsName!=undefined)
@@ -24,13 +25,9 @@ export class UABaseNode implements IToXML{
         }
     }
 
-    resolveChildren(nm: Map<string, UABaseNode>) {
+    getChildren(): UABaseNode[] {
+        const children: UABaseNode[]=[];
         for(const ref of this.references) {
-            const node=nm.get(ref.ref.toString()) 
-            if(node==undefined) {
-                //TODO: parse all types/nodes
-                continue;
-            }
             switch(ref.referenceType) {
                 case 'HasComponent':
                 case 'HasOrderedComponent':
@@ -38,25 +35,43 @@ export class UABaseNode implements IToXML{
                 case 'HasProperty':
                 case 'HasSubtype':
                 case 'HasAddIn':
-                    if(ref.isForward) {
-                        if(!this.children.includes(node))
-                            this.children.push(node);
-                    } else {
-                        if(!node.children.includes(this))
-                            node.children.push(this);
+                    if(ref.isForward&&ref.fromNode===this) {
+                        if(!children.includes(ref.toNode))
+                            children.push(ref.toNode);
+                    } 
+                    if(!ref.isForward&&ref.toNode===this) {
+                        if(!children.includes(ref.fromNode))
+                            children.push(ref.fromNode);
                     }
                     break;
                 }
         }
+        return children;
+    }
+
+    resolveReferences(nm: Map<string, UABaseNode>) {
+        for(const ref of this.references) {
+            const fromNode=nm.get(ref.fromRef.toString()) 
+            if(fromNode)
+                ref.fromNode=fromNode;
+            const toNode=nm.get(ref.toRef.toString()) 
+            if(toNode) //TODO: if we cant find the node; the parser is incomplete or the nodeset is broken
+                ref.toNode=toNode;
+            if(ref.fromNode===this&&toNode){ //add this reference to referenced node
+                if(!ref.toNode.references.includes(ref))
+                    ref.toNode.references.push(ref);
+            } 
+        }
     }
 
-    static  fromXML(xmlObject: any): UABaseNode{
+    static fromXML(xmlObject: any): UABaseNode{
         const xmlReferences=xmlObject['References'];
         const references:UAReference[]=[];
+        const nodeId=coerceNodeId(xmlObject['@_NodeId']);
         for(const xmlref of xmlReferences.Reference) {
-            references.push(UAReference.fromXML(xmlref));
+            references.push(UAReference.fromXML(xmlref, nodeId));
         }
-        const ua=new UABaseNode(coerceNodeId(xmlObject['@_NodeId']), xmlObject['@_BrowseName'], xmlObject['DisplayName'], references);
+        const ua=new UABaseNode(nodeId, xmlObject['@_BrowseName'], xmlObject['DisplayName'], references);
         return ua;
     }
 

+ 2 - 2
src/ua/UANodeSet.ts

@@ -26,7 +26,7 @@ export class UANodeSet implements IToXML{
 
     resolveChildren(nm: Map<string, UABaseNode>) {
         for(const node of this.nodes) {
-            node.resolveChildren(nm);
+            node.resolveReferences(nm);
         }    
     }
 
@@ -53,7 +53,7 @@ export class UANodeSet implements IToXML{
             numberParseOptions: {
                 hex: false,
                 leadingZeros: false,
-                skipLike: /./
+                skipLike: /./ //disable number detection. Otherwise string values might end up as numbers.
             },
             // eslint-disable-next-line @typescript-eslint/no-unused-vars
             isArray: (name, jpath, isLeafNode, isAttribute):boolean => { 

+ 14 - 10
src/ua/UAReference.ts

@@ -2,31 +2,35 @@ import { XMLElem, type IToXML } from "@/util/XmlElem";
 import type { NamespaceTable } from "./NameSpaceTable";
 import { assert } from "@/util/assert";
 import { NodeId, coerceNodeId } from "./NodeId";
+import { UABaseNode } from "./UABaseNode";
 
 export class UAReference implements IToXML{
-    constructor(public referenceType: string,
-                public ref: NodeId,
+    public fromNode:UABaseNode = UABaseNode.nullBaseNode;
+    public toNode:UABaseNode = UABaseNode.nullBaseNode;
+
+    constructor(public fromRef: NodeId,
+                public referenceType: string,
+                public toRef: NodeId,
                 public isForward: boolean) {
     }
 
-
     reIndex(nst: NamespaceTable, onst: NamespaceTable) {
-        const nsName=onst.getUri(this.ref.namespace);
+        const nsName=onst.getUri(this.toRef.namespace);
         assert(nsName!=undefined)
         const newIndex=nst.getIndex(nsName);
         assert(newIndex!=undefined)
-        this.ref.namespace=newIndex;    
+        this.toRef.namespace=newIndex;    
     }
 
     toXML(): XMLElem {
-        return new XMLElem('Reference', this.ref.toString())
+        return new XMLElem('Reference', this.toRef.toString())
             .attr('ReferenceType', this.referenceType.toString())
-            .attr('IsForward',this.isForward);
-        
+            .attr('IsForward',this.isForward);       
     }
 
-    static fromXML(uaReference: any): UAReference {
-        return new UAReference(uaReference['@_ReferenceType'], 
+    static fromXML(uaReference: any, fromRef: NodeId): UAReference {
+        return new UAReference( fromRef,
+                                uaReference['@_ReferenceType'], 
                                 coerceNodeId(uaReference['#text']), 
                                 uaReference['@_IsForward']!="false");
     }