/// <summary> /// this is problematic /// </summary> /// <returns></returns> object ICloneable.Clone() { LineEntity ret = new LineEntity(this.LineNumber, this.Parent, this.Type); return ret; //throw new NotImplementedException(); }
int LastFocus { get; set; } //last focus line public emuParser(ITextSnapshot ts, EditorActor ea) { this._ts = ts; this._ea = ea; this.LineCount = _ts.LineCount; this.LastFocus = -1; //init with -1 Roots = new List<LineEntity>(); consLineEntity = new LineEntity[this.LineCount]; }
public int DOI { get; set; } //to store doi public LineEntity(int lineNumber, LineEntity parent, CodeLineType type) { this.LineNumber = lineNumber; if (parent != null) { this.Parent = parent; this.LineDepth = parent.LineDepth + 1; } else //is root { this.Parent = null; this.LineDepth = 0; } this.Type = type; this.DisT = DisplayType.Origin; this.Children = new List<LineEntity>(); this.DOI = 0; }
public void BuildTrees() //build single tree { LineEntity root = new LineEntity(0, null, CodeLineType.Normal); //is 0 origin, comply to textsnapshot this.Add2TreeandArray(root); LineEntity lastLE = root; LineEntity currentParent = root; //current LineEntity foreach (ITextSnapshotLine tsl in _ts.Lines) { if(tsl.LineNumber == 0) { continue; //Root = new LineEntity(tsl.LineNumber, null); //is 0 origin, comply to textsnapshot } CodeLineType linetype = CurrentLineType(tsl); int iIndent = GetIndentation(tsl); int lastDepth = currentParent.LineDepth; //LineEntity thisline = new LineEntity(tsl.LineNumber, currentParent, linetype); // //if this line is blank, regonized as root line, //but will not be parent, parent will be last one if (linetype == CodeLineType.Blank) { LineEntity blankline = new LineEntity(tsl.LineNumber, null, linetype); blankline.DisT = DisplayType.Dismiss; //do not display code line this.Add2TreeandArray(blankline); continue; } if(iIndent == 0) //start a new root line, will be parent { LineEntity newroot = new LineEntity(tsl.LineNumber, null, linetype); this.Add2TreeandArray(newroot); currentParent = consLineEntity[newroot.LineNumber]; } else { if(iIndent == lastDepth) { LineEntity newchild = new LineEntity(tsl.LineNumber, currentParent.Parent, linetype); this.Add2TreeandArray(newchild); //change current parent here? } else if(iIndent - lastDepth == 1) //new children level { LineEntity newchild = new LineEntity(tsl.LineNumber, currentParent, linetype); this.Add2TreeandArray(newchild); currentParent = consLineEntity[newchild.LineNumber]; } else if(iIndent < lastDepth) { int temp = iIndent; while (temp != lastDepth) { currentParent = currentParent.Parent; ++temp; } LineEntity newchild = new LineEntity(tsl.LineNumber, currentParent.Parent, linetype); this.Add2TreeandArray(newchild); currentParent = consLineEntity[newchild.LineNumber]; } //things we do not wish to see, a hard code work around for now //treated as first level child else if(iIndent - lastDepth > 1) { LineEntity newchild = new LineEntity(tsl.LineNumber, currentParent, linetype); this.Add2TreeandArray(newchild); currentParent = consLineEntity[newchild.LineNumber]; } } } }
/// <summary> /// reset the parser, for edit support /// </summary> public void ResetParser(ITextSnapshot newsshot) { this._ts = newsshot; this.LineCount = newsshot.LineCount; this.LastFocus = -1; //init with -1 Roots.Clear(); //these are not enough... Roots = null; foreach (LineEntity le in consLineEntity) le.DisposeMembers(); System.GC.Collect(); Roots = new List<LineEntity>(); consLineEntity = new LineEntity[this.LineCount]; //rebuild tree BuildTrees(); }
void SetDispT(LineEntity sub) { threshold = -consLineEntity[_ea.CentralLine].LineDepth + const_threshold; if (sub.DOI < threshold) { sub.DisT = DisplayType.Dismiss; } else { sub.DisT = DisplayType.Origin; } if (sub.Type == CodeLineType.Blank) sub.DisT = DisplayType.Dismiss; if (Math.Abs(_ea.CentralLine - sub.LineNumber) < central_offset) sub.DisT = DisplayType.Focus; }
LineEntity IsAncestor(LineEntity subject, LineEntity ac) { if (subject == null) { return null; } else { if (subject.LineNumber == ac.LineNumber) return subject; return IsAncestor(subject.Parent, ac); } }
/// <summary> /// renewed method /// </summary> /// <param name="successor"></param> /// <returns></returns> LineEntity GetCommonAncestor(int curFocus, out LineEntity lastroot) { LineEntity curfocus = consLineEntity[curFocus]; //deep clone LineEntity lastfocus = consLineEntity[LastFocus]; // eliminate the situation that two nodes are same bool curDeeper = curfocus.LineDepth > lastfocus.LineDepth; int depthdiff = Math.Abs(curfocus.LineDepth - lastfocus.LineDepth); if (curDeeper) { for (int i = depthdiff; i > 0; --i) curfocus = curfocus.Parent; } else { for (int i = depthdiff; i > 0; --i) lastfocus = lastfocus.Parent; } lastroot = lastfocus; //init while (lastfocus != null && curfocus != null) { lastroot = lastfocus; if (curfocus.Equals(lastfocus)) { return curfocus; } lastfocus = lastfocus.Parent; curfocus = curfocus.Parent; } return null; //stands for the virtual root }
void Add2TreeandArray(LineEntity tobeadded) { consLineEntity[tobeadded.LineNumber] = tobeadded; if (tobeadded.Parent == null) Roots.Add(tobeadded); else tobeadded.Add2Parent(); }
/// <summary> /// make a more adjustive DOI algorithm /// </summary> /// <param name="cur"></param> /// <param name="dest"></param> /// <returns></returns> int makeDOI(LineEntity cur, LineEntity dest) { //another hard code fix, a line 549 bug, //if (cur == null || dest == null) return -1; if (cur.Equals(dest)) return 0; int dist = GetDistInAST(cur, dest); return (-dest.LineDepth - dist); //here can be more complext formular }
void Traverse2SetDispType(LineEntity root) { int thisDOI = makeDOI(consLineEntity[_ea.CentralLine], root); //marked for reducing GetCentralLine root.DOI = thisDOI; //store root DOI //experiment adjustive threshold SetDispT(root); //threshold = -consLineEntity[_ea.CentralLine].LineDepth + const_threshold ; //if (thisDOI < threshold) //{ // root.DisT = DisplayType.Dismiss; //} //else //{ // root.DisT = DisplayType.Origin; //} //a simple approach to FOCUS area, better add color background //for the blank line if (root.Type == CodeLineType.Blank) root.DisT = DisplayType.Dismiss; if (Math.Abs(_ea.CentralLine - root.LineNumber) < central_offset) root.DisT = DisplayType.Focus; //if not leaf if(root.Children.Count != 0) { foreach(LineEntity child in root.Children) { Traverse2SetDispType(child); } } }
/// <summary> /// get the distance from current focus(central line) to dest line /// </summary> /// <param name="cur">focus line</param> /// <param name="dest">dest line</param> /// <returns></returns> int GetDistInAST(LineEntity cur, LineEntity dest, bool rootdist = false)//root level nodes dist is 0 for default { bool curDeeper = cur.LineDepth > dest.LineDepth; int depthdiff = Math.Abs(cur.LineDepth - dest.LineDepth); LineEntity curAnc = cur; LineEntity destAnc = dest; if (curDeeper) { for (int i = depthdiff; i > 0; --i) curAnc = curAnc.Parent; } else { for (int i = depthdiff; i > 0; --i) destAnc = destAnc.Parent; } if(cur.LineDepth == 0) { return dest.LineDepth + (rootdist ? 2 : 0); } else if(dest.LineDepth == 0) { return cur.LineDepth + (rootdist ? 2 : 0); } //if neither is root int dist = 0; //may leave a condition here that two nodes are in a path while(curAnc != null && destAnc != null) { if (curAnc.Equals(destAnc)) { dist = cur.LineDepth - curAnc.LineDepth + dest.LineDepth - destAnc.LineDepth; return dist; } curAnc = curAnc.Parent; destAnc = destAnc.Parent; } dist = cur.LineDepth + dest.LineDepth; return dist; }