Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
bf7a630d
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,发现更多精彩内容 >>
提交
bf7a630d
编写于
9月 08, 2016
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
file model manager: loadOrCreate()
上级
195c04b1
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
99 addition
and
71 deletion
+99
-71
src/vs/workbench/parts/files/common/editors/fileEditorInput.ts
...s/workbench/parts/files/common/editors/fileEditorInput.ts
+5
-57
src/vs/workbench/parts/files/common/editors/textFileEditorModelManager.ts
.../parts/files/common/editors/textFileEditorModelManager.ts
+66
-11
src/vs/workbench/parts/files/common/files.ts
src/vs/workbench/parts/files/common/files.ts
+1
-1
src/vs/workbench/parts/files/test/browser/textFileEditorModelManager.test.ts
...rts/files/test/browser/textFileEditorModelManager.test.ts
+27
-2
未找到文件。
src/vs/workbench/parts/files/common/editors/fileEditorInput.ts
浏览文件 @
bf7a630d
...
...
@@ -17,7 +17,6 @@ import {IEditorRegistry, Extensions, EditorModel, EncodingMode, ConfirmResult, I
import
{
BinaryEditorModel
}
from
'
vs/workbench/common/editor/binaryEditorModel
'
;
import
{
IFileOperationResult
,
FileOperationResult
}
from
'
vs/platform/files/common/files
'
;
import
{
ITextFileService
,
BINARY_FILE_EDITOR_ID
,
FILE_EDITOR_INPUT_ID
,
FileEditorInput
as
CommonFileEditorInput
,
AutoSaveMode
,
ModelState
,
EventType
as
FileEventType
,
TextFileChangeEvent
,
IFileEditorDescriptor
}
from
'
vs/workbench/parts/files/common/files
'
;
import
{
TextFileEditorModel
}
from
'
vs/workbench/parts/files/common/editors/textFileEditorModel
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
...
...
@@ -31,9 +30,6 @@ export class FileEditorInput extends CommonFileEditorInput {
// Do ref counting for all inputs that resolved to a model to be able to dispose when count = 0
private
static
FILE_EDITOR_MODEL_CLIENTS
:
{
[
resource
:
string
]:
FileEditorInput
[];
}
=
Object
.
create
(
null
);
// Keep promises that load a file editor model to avoid loading the same model twice
private
static
FILE_EDITOR_MODEL_LOADERS
:
{
[
resource
:
string
]:
TPromise
<
EditorModel
>
;
}
=
Object
.
create
(
null
);
private
resource
:
URI
;
private
mime
:
string
;
private
preferredEncoding
:
string
;
...
...
@@ -225,7 +221,6 @@ export class FileEditorInput extends CommonFileEditorInput {
}
public
resolve
(
refresh
?:
boolean
):
TPromise
<
EditorModel
>
{
let
modelPromise
:
TPromise
<
EditorModel
>
;
const
resource
=
this
.
resource
.
toString
();
// Keep clients who resolved the input to support proper disposal
...
...
@@ -236,39 +231,14 @@ export class FileEditorInput extends CommonFileEditorInput {
FileEditorInput
.
FILE_EDITOR_MODEL_CLIENTS
[
resource
].
push
(
this
);
}
// Check for running loader to ensure the model is only ever loaded once
if
(
FileEditorInput
.
FILE_EDITOR_MODEL_LOADERS
[
resource
])
{
return
FileEditorInput
.
FILE_EDITOR_MODEL_LOADERS
[
resource
];
}
// Use Cached Model if present
const
cachedModel
=
this
.
textFileService
.
models
.
get
(
this
.
resource
);
if
(
cachedModel
instanceof
TextFileEditorModel
&&
!
refresh
)
{
modelPromise
=
TPromise
.
as
<
EditorModel
>
(
cachedModel
);
}
// Refresh Cached Model if present
else
if
(
cachedModel
&&
refresh
)
{
modelPromise
=
cachedModel
.
load
();
FileEditorInput
.
FILE_EDITOR_MODEL_LOADERS
[
resource
]
=
modelPromise
;
}
// Otherwise Create Model and Load
else
{
modelPromise
=
this
.
createAndLoadModel
();
FileEditorInput
.
FILE_EDITOR_MODEL_LOADERS
[
resource
]
=
modelPromise
;
}
return
this
.
textFileService
.
models
.
loadOrCreate
(
this
.
resource
,
this
.
preferredEncoding
,
refresh
).
then
(
null
,
error
=>
{
return
modelPromise
.
then
((
resolvedModel
:
TextFileEditorModel
|
BinaryEditorModel
)
=>
{
if
(
resolvedModel
instanceof
TextFileEditorModel
)
{
this
.
textFileService
.
models
.
add
(
this
.
resource
,
resolvedModel
);
// Store into the text model cache unless this file is binary
// In case of an error that indicates that the file is binary or too large, just return with the binary editor model
if
(
(
<
IFileOperationResult
>
error
).
fileOperationResult
===
FileOperationResult
.
FILE_IS_BINARY
||
(
<
IFileOperationResult
>
error
).
fileOperationResult
===
FileOperationResult
.
FILE_TOO_LARGE
)
{
return
this
.
instantiationService
.
createInstance
(
BinaryEditorModel
,
this
.
resource
,
this
.
getName
()).
load
();
}
FileEditorInput
.
FILE_EDITOR_MODEL_LOADERS
[
resource
]
=
null
;
// Remove from pending loaders
return
resolvedModel
;
},
(
error
)
=>
{
FileEditorInput
.
FILE_EDITOR_MODEL_LOADERS
[
resource
]
=
null
;
// Remove from pending loaders in case of an error
// Bubble any other error up
return
TPromise
.
wrapError
(
error
);
});
}
...
...
@@ -287,28 +257,6 @@ export class FileEditorInput extends CommonFileEditorInput {
return
-
1
;
}
private
createAndLoadModel
():
TPromise
<
EditorModel
>
{
const
descriptor
=
(
<
IEditorRegistry
>
Registry
.
as
(
Extensions
.
Editors
)).
getEditor
(
this
);
if
(
!
descriptor
)
{
throw
new
Error
(
'
Unable to find an editor in the registry for this input.
'
);
}
// Optimistically create a text model assuming that the file is not binary
const
textModel
=
this
.
instantiationService
.
createInstance
(
TextFileEditorModel
,
this
.
resource
,
this
.
preferredEncoding
);
return
textModel
.
load
().
then
(()
=>
textModel
,
(
error
)
=>
{
// In case of an error that indicates that the file is binary or too large, just return with the binary editor model
if
((
<
IFileOperationResult
>
error
).
fileOperationResult
===
FileOperationResult
.
FILE_IS_BINARY
||
(
<
IFileOperationResult
>
error
).
fileOperationResult
===
FileOperationResult
.
FILE_TOO_LARGE
)
{
textModel
.
dispose
();
return
this
.
instantiationService
.
createInstance
(
BinaryEditorModel
,
this
.
resource
,
this
.
getName
()).
load
();
}
// Bubble any other error up
return
TPromise
.
wrapError
(
error
);
});
}
public
dispose
():
void
{
// Listeners
...
...
src/vs/workbench/parts/files/common/editors/textFileEditorModelManager.ts
浏览文件 @
bf7a630d
...
...
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
TextFileEditorModel
}
from
'
vs/workbench/parts/files/common/editors/textFileEditorModel
'
;
import
{
ITextFileEditorModelManager
}
from
'
vs/workbench/parts/files/common/files
'
;
...
...
@@ -12,6 +13,7 @@ import {IEditorGroupService} from 'vs/workbench/services/group/common/groupServi
import
{
ModelState
,
ITextFileEditorModel
,
LocalFileChangeEvent
}
from
'
vs/workbench/parts/files/common/files
'
;
import
{
ILifecycleService
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
IEventService
}
from
'
vs/platform/event/common/event
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
FileChangesEvent
,
EventType
as
CommonFileEventType
}
from
'
vs/platform/files/common/files
'
;
export
class
TextFileEditorModelManager
implements
ITextFileEditorModelManager
{
...
...
@@ -24,16 +26,19 @@ export class TextFileEditorModelManager implements ITextFileEditorModelManager {
private
mapResourceToDisposeListener
:
{
[
resource
:
string
]:
IDisposable
;
};
private
mapResourcePathToModel
:
{
[
resource
:
string
]:
TextFileEditorModel
;
};
private
mapResourceToPendingModelLoaders
:
{
[
resource
:
string
]:
TPromise
<
TextFileEditorModel
>
};
constructor
(
@
ILifecycleService
private
lifecycleService
:
ILifecycleService
,
@
IEventService
private
eventService
:
IEventService
,
@
IInstantiationService
private
instantiationService
:
IInstantiationService
,
@
IEditorGroupService
private
editorGroupService
:
IEditorGroupService
)
{
this
.
toUnbind
=
[];
this
.
mapResourcePathToModel
=
Object
.
create
(
null
);
this
.
mapResourceToDisposeListener
=
Object
.
create
(
null
);
this
.
mapResourceToPendingModelLoaders
=
Object
.
create
(
null
);
this
.
registerListeners
();
}
...
...
@@ -51,6 +56,17 @@ export class TextFileEditorModelManager implements ITextFileEditorModelManager {
this
.
lifecycleService
.
onShutdown
(
this
.
dispose
,
this
);
}
private
onEditorsChanged
():
void
{
this
.
disposeUnusedModels
();
}
private
disposeModelIfPossible
(
resource
:
URI
):
void
{
const
model
=
this
.
get
(
resource
);
if
(
this
.
canDispose
(
model
))
{
model
.
dispose
();
}
}
private
onLocalFileChange
(
e
:
LocalFileChangeEvent
):
void
{
if
(
e
.
gotMoved
()
||
e
.
gotDeleted
())
{
this
.
disposeModelIfPossible
(
e
.
getBefore
().
resource
);
// dispose models of moved or deleted files
...
...
@@ -82,17 +98,6 @@ export class TextFileEditorModelManager implements ITextFileEditorModelManager {
.
forEach
(
model
=>
this
.
disposeModelIfPossible
(
model
.
getResource
()));
}
private
onEditorsChanged
():
void
{
this
.
disposeUnusedModels
();
}
private
disposeModelIfPossible
(
resource
:
URI
):
void
{
const
model
=
this
.
get
(
resource
);
if
(
this
.
canDispose
(
model
))
{
model
.
dispose
();
}
}
private
canDispose
(
textModel
:
ITextFileEditorModel
):
boolean
{
if
(
!
textModel
)
{
return
false
;
// we need data!
...
...
@@ -117,6 +122,56 @@ export class TextFileEditorModelManager implements ITextFileEditorModelManager {
return
this
.
mapResourcePathToModel
[
resource
.
toString
()];
}
public
loadOrCreate
(
resource
:
URI
,
encoding
:
string
,
refresh
?:
boolean
):
TPromise
<
TextFileEditorModel
>
{
// Return early if model is currently being loaded
const
pendingLoad
=
this
.
mapResourceToPendingModelLoaders
[
resource
.
toString
()];
if
(
pendingLoad
)
{
return
pendingLoad
;
}
let
modelPromise
:
TPromise
<
TextFileEditorModel
>
;
// Model exists
let
model
=
this
.
get
(
resource
);
if
(
model
)
{
if
(
!
refresh
)
{
modelPromise
=
TPromise
.
as
(
model
);
}
else
{
modelPromise
=
model
.
load
();
}
}
// Model does not exist
else
{
model
=
this
.
instantiationService
.
createInstance
(
TextFileEditorModel
,
resource
,
encoding
);
modelPromise
=
model
.
load
();
}
// Store pending loads to avoid race conditions
this
.
mapResourceToPendingModelLoaders
[
resource
.
toString
()]
=
modelPromise
;
return
modelPromise
.
then
(
model
=>
{
// Make known to manager (if not already known)
this
.
add
(
resource
,
model
);
// Remove from pending loads
this
.
mapResourceToPendingModelLoaders
[
resource
.
toString
()]
=
null
;
return
model
;
},
error
=>
{
// Free resources of this invalid model
model
.
dispose
();
// Remove from pending loads
this
.
mapResourceToPendingModelLoaders
[
resource
.
toString
()]
=
null
;
return
TPromise
.
wrapError
(
error
);
});
}
public
getAll
(
resource
?:
URI
):
TextFileEditorModel
[]
{
return
Object
.
keys
(
this
.
mapResourcePathToModel
)
.
filter
(
r
=>
!
resource
||
resource
.
toString
()
===
r
)
...
...
src/vs/workbench/parts/files/common/files.ts
浏览文件 @
bf7a630d
...
...
@@ -281,7 +281,7 @@ export interface ITextFileEditorModelManager {
getAll
(
resource
?:
URI
):
ITextFileEditorModel
[];
add
(
resource
:
URI
,
model
:
ITextFileEditorModel
):
void
;
loadOrCreate
(
resource
:
URI
,
preferredEncoding
:
string
,
refresh
?:
boolean
):
TPromise
<
ITextEditorModel
>
;
}
export
interface
ITextFileEditorModel
extends
ITextEditorModel
,
IEncodingSupport
{
...
...
src/vs/workbench/parts/files/test/browser/textFileEditorModelManager.test.ts
浏览文件 @
bf7a630d
...
...
@@ -54,7 +54,7 @@ suite('Files - TextFileEditorModelManager', () => {
});
test
(
'
add, remove, clear, get, getAll
'
,
function
()
{
const
manager
=
instantiationService
.
createInstance
(
TextFileEditorModelManager
);
const
manager
:
TextFileEditorModelManager
=
instantiationService
.
createInstance
(
TextFileEditorModelManager
);
const
model1
=
new
EditorModel
();
const
model2
=
new
EditorModel
();
...
...
@@ -94,8 +94,33 @@ suite('Files - TextFileEditorModelManager', () => {
assert
.
strictEqual
(
0
,
result
.
length
);
});
test
(
'
loadOrCreate
'
,
function
(
done
)
{
const
manager
:
TextFileEditorModelManager
=
instantiationService
.
createInstance
(
TextFileEditorModelManager
);
const
resource
=
URI
.
file
(
'
/test.html
'
);
const
encoding
=
'
utf8
'
;
manager
.
loadOrCreate
(
resource
,
encoding
,
true
).
then
(
model
=>
{
assert
.
ok
(
model
);
assert
.
equal
(
model
.
getEncoding
(),
encoding
);
assert
.
equal
(
manager
.
get
(
resource
),
model
);
return
manager
.
loadOrCreate
(
resource
,
encoding
).
then
(
model2
=>
{
assert
.
equal
(
model2
,
model
);
model
.
dispose
();
return
manager
.
loadOrCreate
(
resource
,
encoding
).
then
(
model3
=>
{
assert
.
notEqual
(
model3
,
model2
);
assert
.
equal
(
manager
.
get
(
resource
),
model3
);
done
();
});
});
});
});
test
(
'
removed from cache when model disposed
'
,
function
()
{
const
manager
=
instantiationService
.
createInstance
(
TextFileEditorModelManager
);
const
manager
:
TextFileEditorModelManager
=
instantiationService
.
createInstance
(
TextFileEditorModelManager
);
const
model1
=
new
EditorModel
();
const
model2
=
new
EditorModel
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录