Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
94343c80
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
94343c80
编写于
6月 22, 2018
作者:
J
Joao Moreno
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
use iterators in tree model
上级
66d7ae89
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
108 addition
and
122 deletion
+108
-122
src/vs/base/browser/ui/list/treeModel.ts
src/vs/base/browser/ui/list/treeModel.ts
+30
-80
src/vs/base/common/iterator.ts
src/vs/base/common/iterator.ts
+37
-2
src/vs/base/test/browser/ui/list/treeModel.test.ts
src/vs/base/test/browser/ui/list/treeModel.test.ts
+41
-40
未找到文件。
src/vs/base/browser/ui/list/treeModel.ts
浏览文件 @
94343c80
...
...
@@ -6,13 +6,17 @@
'
use strict
'
;
import
{
ISpliceable
}
from
'
vs/base/common/sequence
'
;
import
{
Tree
}
from
'
vs/base/common/tree
'
;
import
{
tail2
}
from
'
vs/base/common/arrays
'
;
import
{
Trie
}
from
'
vs/base/browser/ui/list/trie
'
;
import
{
IIterator
,
map
,
collect
,
forEach
,
iter
}
from
'
vs/base/common/iterator
'
;
/**
* TODO:
* remove trie
* remote base tree
*/
export
interface
ITreeElement
<
T
>
{
readonly
element
:
T
;
readonly
children
:
I
TreeElement
<
T
>
[]
;
readonly
children
:
I
Iterator
<
ITreeElement
<
T
>>
;
}
export
interface
ITreeListElement
<
T
>
{
...
...
@@ -22,8 +26,8 @@ export interface ITreeListElement<T> {
class
TreeNode
<
T
>
implements
ITreeListElement
<
T
>
{
static
createRoot
<
T
>
():
TreeNode
<
T
>
{
const
node
=
new
TreeNode
<
T
>
();
static
createRoot
<
T
>
(
element
:
T
):
TreeNode
<
T
>
{
const
node
=
new
TreeNode
<
T
>
(
element
);
node
.
children
=
[];
node
.
count
=
1
;
node
.
depth
=
0
;
...
...
@@ -31,19 +35,18 @@ class TreeNode<T> implements ITreeListElement<T> {
}
static
createNode
<
T
>
(
treeElement
:
ITreeElement
<
T
>
,
depth
:
number
,
list
:
ITreeListElement
<
T
>
[]):
TreeNode
<
T
>
{
const
node
=
new
TreeNode
<
T
>
();
const
node
=
new
TreeNode
<
T
>
(
treeElement
.
element
);
list
.
push
(
node
);
let
count
=
1
;
const
children
:
TreeNode
<
T
>
[]
=
[];
for
(
const
childItem
of
treeElement
.
children
)
{
const
node
=
TreeNode
.
createNode
<
T
>
(
child
Item
,
depth
+
1
,
list
);
for
Each
(
treeElement
.
children
,
child
=>
{
const
node
=
TreeNode
.
createNode
<
T
>
(
child
,
depth
+
1
,
list
);
children
.
push
(
node
);
count
+=
node
.
count
;
}
}
);
node
.
element
=
treeElement
.
element
;
node
.
children
=
children
;
node
.
count
=
count
;
node
.
depth
=
depth
;
...
...
@@ -51,20 +54,18 @@ class TreeNode<T> implements ITreeListElement<T> {
return
node
;
}
element
:
T
;
children
:
TreeNode
<
T
>
[];
count
:
number
;
depth
:
number
;
private
constructor
()
{
}
private
constructor
(
public
element
:
T
)
{
}
splice
(
index
:
number
,
deleteCount
:
number
,
t
reeElements
:
ITreeElement
<
T
>
[]
):
{
listDeleteCount
:
number
;
listElements
:
ITreeListElement
<
T
>
[];
deletedNodes
:
TreeNode
<
T
>
[];
}
{
splice
(
index
:
number
,
deleteCount
:
number
,
t
oInsert
:
IIterator
<
ITreeElement
<
T
>>
):
{
listDeleteCount
:
number
;
listElements
:
ITreeListElement
<
T
>
[];
deletedNodes
:
TreeNode
<
T
>
[];
}
{
const
listElements
=
[]
as
ITreeListElement
<
T
>
[];
const
added
=
treeElements
.
map
(
e
=>
TreeNode
.
createNode
<
T
>
(
e
,
this
.
depth
+
1
,
listElements
));
const
listAddCount
=
added
.
reduce
((
r
,
n
)
=>
r
+
n
.
count
,
0
);
const
deletedNodes
=
this
.
children
.
splice
(
index
,
deleteCount
,
...
added
);
const
nodesToInsert
=
collect
(
map
(
toInsert
,
e
=>
TreeNode
.
createNode
<
T
>
(
e
,
this
.
depth
+
1
,
listElements
)));
const
listAddCount
=
nodesToInsert
.
reduce
((
r
,
n
)
=>
r
+
n
.
count
,
0
);
const
deletedNodes
=
this
.
children
.
splice
(
index
,
deleteCount
,
...
nodesToInsert
);
const
listDeleteCount
=
deletedNodes
.
reduce
((
r
,
n
)
=>
r
+
n
.
count
,
0
);
this
.
count
+=
listAddCount
-
listDeleteCount
;
...
...
@@ -72,24 +73,31 @@ class TreeNode<T> implements ITreeListElement<T> {
}
}
function
asTreeElement
<
T
>
(
node
:
TreeNode
<
T
>
):
ITreeElement
<
T
>
{
return
{
element
:
node
.
element
,
children
:
map
(
iter
(
node
.
children
),
asTreeElement
)
};
}
export
class
TreeModel
<
T
>
{
private
root
=
TreeNode
.
createRoot
<
T
>
();
private
root
=
TreeNode
.
createRoot
<
T
>
(
undefined
);
constructor
(
private
spliceable
:
ISpliceable
<
ITreeListElement
<
T
>>
)
{
}
splice
(
start
:
number
[],
deleteCount
:
number
,
elements
:
ITreeElement
<
T
>
[]
=
[]):
ITreeElement
<
T
>
[]
{
splice
(
start
:
number
[],
deleteCount
:
number
,
toInsert
:
IIterator
<
ITreeElement
<
T
>>
):
IIterator
<
ITreeElement
<
T
>>
{
if
(
start
.
length
===
0
)
{
throw
new
Error
(
'
Invalid tree location
'
);
}
const
{
parentNode
,
parentListIndex
}
=
this
.
findParentNode
(
start
);
const
lastIndex
=
start
[
start
.
length
-
1
];
const
{
listDeleteCount
,
listElements
,
deletedNodes
}
=
parentNode
.
splice
(
lastIndex
,
deleteCount
,
elements
);
const
{
listDeleteCount
,
listElements
,
deletedNodes
}
=
parentNode
.
splice
(
lastIndex
,
deleteCount
,
toInsert
);
this
.
spliceable
.
splice
(
parentListIndex
+
lastIndex
,
listDeleteCount
,
listElements
);
return
deletedNodes
;
return
map
(
iter
(
deletedNodes
),
asTreeElement
)
;
}
private
findParentNode
(
location
:
number
[],
node
:
TreeNode
<
T
>
=
this
.
root
,
listIndex
:
number
=
0
):
{
parentNode
:
TreeNode
<
T
>
;
parentListIndex
:
number
}
{
...
...
@@ -108,61 +116,3 @@ export class TreeModel<T> {
return
this
.
findParentNode
(
rest
,
node
.
children
[
i
],
listIndex
+
1
);
}
}
export
interface
ICollapsibleTreeElement
<
T
>
{
element
:
T
;
collapsed
:
boolean
;
}
export
class
CollapsibleTreeModel
<
T
>
{
private
model
=
new
Tree
<
ICollapsibleTreeElement
<
T
>>
();
private
collapsedElements
=
new
Trie
<
number
,
ITreeElement
<
T
>>
();
private
visibleModel
:
TreeModel
<
T
>
;
constructor
(
spliceable
:
ISpliceable
<
ITreeListElement
<
T
>>
)
{
this
.
visibleModel
=
new
TreeModel
<
T
>
(
spliceable
);
}
splice
(
start
:
number
[],
deleteCount
:
number
,
items
:
ITreeElement
<
ICollapsibleTreeElement
<
T
>>
[]):
void
{
// const elementPath = this.model.getElementPath(start);
this
.
model
.
splice
(
start
,
deleteCount
,
items
);
// this.visibleModel.splice(start, deleteCount, items);
}
setCollapsed
(
location
:
number
[],
collapsed
:
boolean
):
void
{
const
elementPath
=
this
.
model
.
getElementPath
(
location
);
const
[
pathToElement
,
collapsibleElement
]
=
tail2
(
elementPath
);
if
(
collapsibleElement
.
collapsed
===
collapsed
)
{
return
;
}
collapsibleElement
.
collapsed
=
collapsed
;
if
(
pathToElement
.
some
(
e
=>
e
.
collapsed
))
{
return
;
}
if
(
collapsed
)
{
const
collapsedElement
:
ITreeElement
<
T
>
=
{
element
:
collapsibleElement
.
element
,
children
:
[]
};
const
[
element
]
=
this
.
visibleModel
.
splice
(
location
,
1
,
[
collapsedElement
]);
this
.
collapsedElements
.
set
(
location
,
element
);
}
else
{
const
expandedElement
=
this
.
collapsedElements
.
delete
(
location
);
this
.
visibleModel
.
splice
(
location
,
1
,
[
expandedElement
]);
}
// gotta reflect the state on the visibleModel
}
isCollapsed
(
location
:
number
[]):
boolean
{
return
this
.
model
.
getElement
(
location
).
collapsed
;
}
}
\ No newline at end of file
src/vs/base/common/iterator.ts
浏览文件 @
94343c80
...
...
@@ -10,8 +10,43 @@ export interface IIteratorResult<T> {
readonly
value
:
T
|
undefined
;
}
export
interface
IIterator
<
E
>
{
next
():
IIteratorResult
<
E
>
;
export
interface
IIterator
<
T
>
{
next
():
IIteratorResult
<
T
>
;
}
export
function
iter
<
T
>
(
array
:
T
[]):
IIterator
<
T
>
{
let
index
=
0
;
return
{
next
():
IIteratorResult
<
T
>
{
if
(
index
===
array
.
length
)
{
return
{
done
:
true
,
value
:
undefined
};
}
return
{
done
:
false
,
value
:
array
[
index
++
]
};
}
};
}
export
function
map
<
T
,
R
>
(
iterator
:
IIterator
<
T
>
,
fn
:
(
t
:
T
)
=>
R
):
IIterator
<
R
>
{
return
{
next
()
{
const
{
done
,
value
}
=
iterator
.
next
();
return
{
done
,
value
:
done
?
undefined
:
fn
(
value
)
};
}
};
}
export
function
forEach
<
T
>
(
iterator
:
IIterator
<
T
>
,
fn
:
(
t
:
T
)
=>
void
):
void
{
for
(
let
next
=
iterator
.
next
();
!
next
.
done
;
next
=
iterator
.
next
())
{
fn
(
next
.
value
);
}
}
export
function
collect
<
T
>
(
iterator
:
IIterator
<
T
>
):
T
[]
{
const
result
:
T
[]
=
[];
forEach
(
iterator
,
value
=>
result
.
push
(
value
));
return
result
;
}
export
interface
INextIterator
<
T
>
{
...
...
src/vs/base/test/browser/ui/list/treeModel.test.ts
浏览文件 @
94343c80
...
...
@@ -6,6 +6,7 @@
import
*
as
assert
from
'
assert
'
;
import
{
TreeModel
,
ITreeListElement
}
from
'
vs/base/browser/ui/list/treeModel
'
;
import
{
ISpliceable
}
from
'
vs/base/browser/ui/list/splice
'
;
import
{
iter
}
from
'
vs/base/common/iterator
'
;
function
toSpliceable
<
T
>
(
arr
:
T
[]):
ISpliceable
<
T
>
{
return
{
...
...
@@ -28,11 +29,11 @@ suite('TreeModel2', () => {
const
list
=
[]
as
ITreeListElement
<
number
>
[];
const
model
=
new
TreeModel
<
number
>
(
toSpliceable
(
list
));
model
.
splice
([
0
],
0
,
[
{
element
:
0
,
children
:
[]
},
{
element
:
1
,
children
:
[]
},
{
element
:
2
,
children
:
[]
}
]);
model
.
splice
([
0
],
0
,
iter
(
[
{
element
:
0
,
children
:
iter
([])
},
{
element
:
1
,
children
:
iter
([])
},
{
element
:
2
,
children
:
iter
([])
}
])
)
;
assert
.
deepEqual
(
list
.
length
,
3
);
assert
.
deepEqual
(
list
[
0
].
element
,
0
);
...
...
@@ -47,17 +48,17 @@ suite('TreeModel2', () => {
const
list
=
[]
as
ITreeListElement
<
number
>
[];
const
model
=
new
TreeModel
<
number
>
(
toSpliceable
(
list
));
model
.
splice
([
0
],
0
,
[
model
.
splice
([
0
],
0
,
iter
(
[
{
element
:
0
,
children
:
[
{
element
:
10
,
children
:
[]
},
{
element
:
11
,
children
:
[]
},
{
element
:
12
,
children
:
[]
},
]
element
:
0
,
children
:
iter
(
[
{
element
:
10
,
children
:
iter
([])
},
{
element
:
11
,
children
:
iter
([])
},
{
element
:
12
,
children
:
iter
([])
},
]
)
},
{
element
:
1
,
children
:
[]
},
{
element
:
2
,
children
:
[]
}
]);
{
element
:
1
,
children
:
iter
([])
},
{
element
:
2
,
children
:
iter
([])
}
])
)
;
assert
.
deepEqual
(
list
.
length
,
6
);
assert
.
deepEqual
(
list
[
0
].
element
,
0
);
...
...
@@ -78,13 +79,13 @@ suite('TreeModel2', () => {
const
list
=
[]
as
ITreeListElement
<
number
>
[];
const
model
=
new
TreeModel
<
number
>
(
toSpliceable
(
list
));
model
.
splice
([
0
],
0
,
[
{
element
:
0
,
children
:
[]
},
{
element
:
1
,
children
:
[]
},
{
element
:
2
,
children
:
[]
}
]);
model
.
splice
([
0
],
0
,
iter
(
[
{
element
:
0
,
children
:
iter
([])
},
{
element
:
1
,
children
:
iter
([])
},
{
element
:
2
,
children
:
iter
([])
}
])
)
;
model
.
splice
([
0
],
3
,
[]
);
model
.
splice
([
0
],
3
,
iter
([])
);
assert
.
equal
(
list
.
length
,
0
);
});
...
...
@@ -93,19 +94,19 @@ suite('TreeModel2', () => {
const
list
=
[]
as
ITreeListElement
<
number
>
[];
const
model
=
new
TreeModel
<
number
>
(
toSpliceable
(
list
));
model
.
splice
([
0
],
0
,
[
model
.
splice
([
0
],
0
,
iter
(
[
{
element
:
0
,
children
:
[
{
element
:
10
,
children
:
[]
},
{
element
:
11
,
children
:
[]
},
{
element
:
12
,
children
:
[]
},
]
element
:
0
,
children
:
iter
(
[
{
element
:
10
,
children
:
iter
([])
},
{
element
:
11
,
children
:
iter
([])
},
{
element
:
12
,
children
:
iter
([])
},
]
)
},
{
element
:
1
,
children
:
[]
},
{
element
:
2
,
children
:
[]
}
]);
{
element
:
1
,
children
:
iter
([])
},
{
element
:
2
,
children
:
iter
([])
}
])
)
;
model
.
splice
([
0
,
1
],
1
,
[]
);
model
.
splice
([
0
,
1
],
1
,
iter
([])
);
assert
.
deepEqual
(
list
.
length
,
5
,
'
list has 5 elements
'
);
assert
.
deepEqual
(
list
[
0
].
element
,
0
);
...
...
@@ -124,19 +125,19 @@ suite('TreeModel2', () => {
const
list
=
[]
as
ITreeListElement
<
number
>
[];
const
model
=
new
TreeModel
<
number
>
(
toSpliceable
(
list
));
model
.
splice
([
0
],
0
,
[
model
.
splice
([
0
],
0
,
iter
(
[
{
element
:
0
,
children
:
[
{
element
:
10
,
children
:
[]
},
{
element
:
11
,
children
:
[]
},
{
element
:
12
,
children
:
[]
},
]
element
:
0
,
children
:
iter
(
[
{
element
:
10
,
children
:
iter
([])
},
{
element
:
11
,
children
:
iter
([])
},
{
element
:
12
,
children
:
iter
([])
},
]
)
},
{
element
:
1
,
children
:
[]
},
{
element
:
2
,
children
:
[]
}
]);
{
element
:
1
,
children
:
iter
([])
},
{
element
:
2
,
children
:
iter
([])
}
])
)
;
model
.
splice
([
0
],
1
,
[]
);
model
.
splice
([
0
],
1
,
iter
([])
);
assert
.
deepEqual
(
list
.
length
,
2
,
'
list has 2 elements only
'
);
assert
.
deepEqual
(
list
[
0
].
element
,
1
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录