1
1
import { SymbolKind , TextDocument } from 'vscode' ;
2
- import { METHOD_KINDS , getClassesAndMethodsContainedInRange , getClassesAndMethodsOfDocument , logger } from '../utils' ;
2
+ import { METHOD_KINDS , getSymbolsContainedInRange , getSymbolsOfDocument , logger } from '../utils' ;
3
3
import { Inspection } from './Inspection' ;
4
- import * as crypto from "crypto" ;
5
4
import { SymbolNode } from './SymbolNode' ;
6
5
7
6
/**
8
7
* A map based cache for inspections of a document.
9
- * format: `Map<documentKey, Map<symbolQualifiedName, [symbolVersionId , Inspection[]]`
8
+ * format: `Map<documentKey, Map<symbolQualifiedName, [symbolSnapshotId , Inspection[]]`
10
9
*/
11
- const DOC_SYMBOL_VERSION_INSPECTIONS : Map < string , Map < string , [ string , Inspection [ ] ] > > = new Map ( ) ;
10
+ const DOC_SYMBOL_SNAPSHOT_INSPECTIONS : Map < string , Map < string , [ string , Inspection [ ] ] > > = new Map ( ) ;
12
11
13
12
export default class InspectionCache {
14
13
/**
@@ -18,15 +17,14 @@ export default class InspectionCache {
18
17
public static async hasCache ( document : TextDocument , symbol ?: SymbolNode ) : Promise < boolean > {
19
18
const documentKey = document . uri . fsPath ;
20
19
if ( ! symbol ) {
21
- return DOC_SYMBOL_VERSION_INSPECTIONS . has ( documentKey ) ;
20
+ return DOC_SYMBOL_SNAPSHOT_INSPECTIONS . has ( documentKey ) ;
22
21
}
23
- const symbolInspections = DOC_SYMBOL_VERSION_INSPECTIONS . get ( documentKey ) ;
22
+ const symbolInspections = DOC_SYMBOL_SNAPSHOT_INSPECTIONS . get ( documentKey ) ;
24
23
// check if the symbol or its contained symbols are cached
25
- const symbols = await getClassesAndMethodsContainedInRange ( symbol . range , document ) ;
24
+ const symbols = await getSymbolsContainedInRange ( symbol . range , document ) ;
26
25
for ( const s of symbols ) {
27
- const versionInspections = symbolInspections ?. get ( s . qualifiedName ) ;
28
- const symbolVersionId = InspectionCache . calculateSymbolVersionId ( document , s ) ;
29
- if ( versionInspections ?. [ 0 ] === symbolVersionId ) {
26
+ const snapshotInspections = symbolInspections ?. get ( s . qualifiedName ) ;
27
+ if ( snapshotInspections ?. [ 0 ] === s . snapshotId && snapshotInspections [ 1 ] . length > 0 ) {
30
28
return true ;
31
29
}
32
30
}
@@ -39,7 +37,7 @@ export default class InspectionCache {
39
37
* their content has changed.
40
38
*/
41
39
public static async getCachedInspectionsOfDoc ( document : TextDocument ) : Promise < Inspection [ ] > {
42
- const symbols : SymbolNode [ ] = await getClassesAndMethodsOfDocument ( document ) ;
40
+ const symbols : SymbolNode [ ] = await getSymbolsOfDocument ( document ) ;
43
41
const inspections : Inspection [ ] = [ ] ;
44
42
// we don't get cached inspections directly from the cache, because we need to filter out outdated symbols
45
43
for ( const symbol of symbols ) {
@@ -54,12 +52,11 @@ export default class InspectionCache {
54
52
*/
55
53
public static getCachedInspectionsOfSymbol ( document : TextDocument , symbol : SymbolNode ) : Inspection [ ] {
56
54
const documentKey = document . uri . fsPath ;
57
- const symbolInspections = DOC_SYMBOL_VERSION_INSPECTIONS . get ( documentKey ) ;
58
- const versionInspections = symbolInspections ?. get ( symbol . qualifiedName ) ;
59
- const symbolVersionId = InspectionCache . calculateSymbolVersionId ( document , symbol ) ;
60
- if ( versionInspections ?. [ 0 ] === symbolVersionId ) {
55
+ const symbolInspections = DOC_SYMBOL_SNAPSHOT_INSPECTIONS . get ( documentKey ) ;
56
+ const snapshotInspections = symbolInspections ?. get ( symbol . qualifiedName ) ;
57
+ if ( snapshotInspections ?. [ 0 ] === symbol . snapshotId ) {
61
58
logger . debug ( `cache hit for ${ SymbolKind [ symbol . kind ] } ${ symbol . qualifiedName } of ${ document . uri . fsPath } ` ) ;
62
- const inspections = versionInspections [ 1 ] ;
59
+ const inspections = snapshotInspections [ 1 ] ;
63
60
inspections . forEach ( s => {
64
61
s . document = document ;
65
62
s . problem . position . line = s . problem . position . relativeLine + symbol . range . start . line ;
@@ -78,7 +75,7 @@ export default class InspectionCache {
78
75
return isMethod ?
79
76
// NOTE: method inspections are inspections whose `position.line` is within the method's range
80
77
inspectionLine >= symbol . range . start . line && inspectionLine <= symbol . range . end . line :
81
- // NOTE: class inspections are inspections whose `position.line` is exactly the first line number of the class
78
+ // NOTE: class/field inspections are inspections whose `position.line` is exactly the first line number of the class/field
82
79
inspectionLine === symbol . range . start . line ;
83
80
} ) ;
84
81
// re-calculate `relativeLine` of method inspections, `relativeLine` is the relative line number to the start of the method
@@ -93,13 +90,13 @@ export default class InspectionCache {
93
90
*/
94
91
public static invalidateInspectionCache ( document ?: TextDocument , symbol ?: SymbolNode , inspeciton ?: Inspection ) : void {
95
92
if ( ! document ) {
96
- DOC_SYMBOL_VERSION_INSPECTIONS . clear ( ) ;
93
+ DOC_SYMBOL_SNAPSHOT_INSPECTIONS . clear ( ) ;
97
94
} else if ( ! symbol ) {
98
95
const documentKey = document . uri . fsPath ;
99
- DOC_SYMBOL_VERSION_INSPECTIONS . delete ( documentKey ) ;
96
+ DOC_SYMBOL_SNAPSHOT_INSPECTIONS . delete ( documentKey ) ;
100
97
} else if ( ! inspeciton ) {
101
98
const documentKey = document . uri . fsPath ;
102
- const symbolInspections = DOC_SYMBOL_VERSION_INSPECTIONS . get ( documentKey ) ;
99
+ const symbolInspections = DOC_SYMBOL_SNAPSHOT_INSPECTIONS . get ( documentKey ) ;
103
100
// remove the cached inspections of the symbol
104
101
symbolInspections ?. delete ( symbol . qualifiedName ) ;
105
102
// remove the cached inspections of contained symbols
@@ -110,11 +107,10 @@ export default class InspectionCache {
110
107
} ) ;
111
108
} else {
112
109
const documentKey = document . uri . fsPath ;
113
- const symbolInspections = DOC_SYMBOL_VERSION_INSPECTIONS . get ( documentKey ) ;
114
- const versionInspections = symbolInspections ?. get ( symbol . qualifiedName ) ;
115
- const symbolVersionId = InspectionCache . calculateSymbolVersionId ( document , symbol ) ;
116
- if ( versionInspections ?. [ 0 ] === symbolVersionId ) {
117
- const inspections = versionInspections [ 1 ] ;
110
+ const symbolInspections = DOC_SYMBOL_SNAPSHOT_INSPECTIONS . get ( documentKey ) ;
111
+ const snapshotInspections = symbolInspections ?. get ( symbol . qualifiedName ) ;
112
+ if ( snapshotInspections ?. [ 0 ] === symbol . snapshotId ) {
113
+ const inspections = snapshotInspections [ 1 ] ;
118
114
// remove the inspection
119
115
inspections . splice ( inspections . indexOf ( inspeciton ) , 1 ) ;
120
116
}
@@ -124,22 +120,13 @@ export default class InspectionCache {
124
120
private static cacheSymbolInspections ( document : TextDocument , symbol : SymbolNode , inspections : Inspection [ ] ) : void {
125
121
logger . debug ( `cache ${ inspections . length } inspections for ${ SymbolKind [ symbol . kind ] } ${ symbol . qualifiedName } of ${ document . uri . fsPath } ` ) ;
126
122
const documentKey = document . uri . fsPath ;
127
- const symbolVersionId = InspectionCache . calculateSymbolVersionId ( document , symbol ) ;
128
- const cachedSymbolInspections = DOC_SYMBOL_VERSION_INSPECTIONS . get ( documentKey ) ?? new Map ( ) ;
123
+ const cachedSymbolInspections = DOC_SYMBOL_SNAPSHOT_INSPECTIONS . get ( documentKey ) ?? new Map ( ) ;
129
124
inspections . forEach ( s => {
130
125
s . document = document ;
131
126
s . symbol = symbol ;
132
127
} ) ;
133
128
// use qualified name to prevent conflicts between symbols with the same signature in same document
134
- cachedSymbolInspections . set ( symbol . qualifiedName , [ symbolVersionId , inspections ] ) ;
135
- DOC_SYMBOL_VERSION_INSPECTIONS . set ( documentKey , cachedSymbolInspections ) ;
136
- }
137
-
138
- /**
139
- * generate a unique id for the symbol based on its content, so that we can detect if the symbol has changed
140
- */
141
- private static calculateSymbolVersionId ( document : TextDocument , symbol : SymbolNode ) : string {
142
- const body = document . getText ( symbol . range ) ;
143
- return crypto . createHash ( 'md5' ) . update ( body ) . digest ( "hex" )
129
+ cachedSymbolInspections . set ( symbol . qualifiedName , [ symbol . snapshotId , inspections ] ) ;
130
+ DOC_SYMBOL_SNAPSHOT_INSPECTIONS . set ( documentKey , cachedSymbolInspections ) ;
144
131
}
145
132
}
0 commit comments