@@ -43,48 +43,70 @@ class LazyResourceMap<T> {
43
43
export class MdDocumentInfoCache < T > extends Disposable {
44
44
45
45
private readonly _cache = new LazyResourceMap < T > ( ) ;
46
+ private readonly _loadingDocuments = new ResourceMap < Promise < SkinnyTextDocument | undefined > > ( ) ;
46
47
47
48
public constructor (
48
49
private readonly workspaceContents : MdWorkspaceContents ,
49
50
private readonly getValue : ( document : SkinnyTextDocument ) => Promise < T > ,
50
51
) {
51
52
super ( ) ;
52
53
53
- this . _register ( this . workspaceContents . onDidChangeMarkdownDocument ( doc => this . onDidChangeDocument ( doc ) ) ) ;
54
- this . _register ( this . workspaceContents . onDidCreateMarkdownDocument ( doc => this . onDidChangeDocument ( doc ) ) ) ;
54
+ this . _register ( this . workspaceContents . onDidChangeMarkdownDocument ( doc => this . invalidate ( doc ) ) ) ;
55
55
this . _register ( this . workspaceContents . onDidDeleteMarkdownDocument ( this . onDidDeleteDocument , this ) ) ;
56
56
}
57
57
58
58
public async get ( resource : vscode . Uri ) : Promise < T | undefined > {
59
- const existing = this . _cache . get ( resource ) ;
59
+ let existing = this . _cache . get ( resource ) ;
60
60
if ( existing ) {
61
61
return existing ;
62
62
}
63
63
64
- const doc = await this . workspaceContents . getOrLoadMarkdownDocument ( resource ) ;
65
- return doc && this . onDidChangeDocument ( doc , true ) ?. value ;
64
+ const doc = await this . loadDocument ( resource ) ;
65
+ if ( ! doc ) {
66
+ return undefined ;
67
+ }
68
+
69
+ // Check if we have invalidated
70
+ existing = this . _cache . get ( resource ) ;
71
+ if ( existing ) {
72
+ return existing ;
73
+ }
74
+
75
+ return this . resetEntry ( doc ) ?. value ;
66
76
}
67
77
68
78
public async getForDocument ( document : SkinnyTextDocument ) : Promise < T > {
69
79
const existing = this . _cache . get ( document . uri ) ;
70
80
if ( existing ) {
71
81
return existing ;
72
82
}
83
+ return this . resetEntry ( document ) . value ;
84
+ }
73
85
74
- return this . onDidChangeDocument ( document , true ) ! . value ;
86
+ private loadDocument ( resource : vscode . Uri ) : Promise < SkinnyTextDocument | undefined > {
87
+ const existing = this . _loadingDocuments . get ( resource ) ;
88
+ if ( existing ) {
89
+ return existing ;
90
+ }
91
+
92
+ const p = this . workspaceContents . getOrLoadMarkdownDocument ( resource ) ;
93
+ this . _loadingDocuments . set ( resource , p ) ;
94
+ p . finally ( ( ) => {
95
+ this . _loadingDocuments . delete ( resource ) ;
96
+ } ) ;
97
+ return p ;
75
98
}
76
99
77
- public async entries ( ) : Promise < Array < [ vscode . Uri , T ] > > {
78
- return this . _cache . entries ( ) ;
100
+ private resetEntry ( document : SkinnyTextDocument ) : Lazy < Promise < T > > {
101
+ const value = lazy ( ( ) => this . getValue ( document ) ) ;
102
+ this . _cache . set ( document . uri , value ) ;
103
+ return value ;
79
104
}
80
105
81
- private onDidChangeDocument ( document : SkinnyTextDocument , forceAdd = false ) : Lazy < Promise < T > > | undefined {
82
- if ( forceAdd || this . _cache . has ( document . uri ) ) {
83
- const value = lazy ( ( ) => this . getValue ( document ) ) ;
84
- this . _cache . set ( document . uri , value ) ;
85
- return value ;
106
+ private invalidate ( document : SkinnyTextDocument ) : void {
107
+ if ( this . _cache . has ( document . uri ) ) {
108
+ this . resetEntry ( document ) ;
86
109
}
87
- return undefined ;
88
110
}
89
111
90
112
private onDidDeleteDocument ( resource : vscode . Uri ) {
0 commit comments