@@ -115,9 +115,9 @@ export class RecursiveReference extends ResolveError {
115
115
public override errorType = 'RecursiveReferenceError' ;
116
116
117
117
/**
118
- * Default string representation of the recursive path.
118
+ * Cached default string representation of the recursive path.
119
119
*/
120
- public readonly recursivePathString : string ;
120
+ private defaultPathStringCache : string | undefined ;
121
121
122
122
constructor (
123
123
uri : URI ,
@@ -130,29 +130,30 @@ export class RecursiveReference extends ResolveError {
130
130
`Recursive path must contain at least two paths, got '${ recursivePath . length } '.` ,
131
131
) ;
132
132
133
- const pathString = recursivePath . join ( DEFAULT_RECURSIVE_PATH_JOIN_CHAR ) ;
134
133
super (
135
- uri ,
136
- `Recursive references found: ${ pathString } .` ,
134
+ uri , 'Recursive references found.' ,
137
135
) ;
138
136
}
139
137
138
+ public override get message ( ) : string {
139
+ return `${ super . message } ${ this . getRecursivePathString ( 'fullpath' ) } ` ;
140
+ }
141
+
140
142
/**
141
143
* Returns a string representation of the recursive path.
142
144
*/
143
145
public getRecursivePathString (
144
146
filename : 'basename' | 'fullpath' ,
145
147
pathJoinCharacter : string = DEFAULT_RECURSIVE_PATH_JOIN_CHAR ,
146
148
) : string {
147
- /**
148
- * TODO: @lego - this not currently true though
149
- * TODO: @lego - cache
150
- */
151
- if ( filename === 'fullpath' && pathJoinCharacter === DEFAULT_RECURSIVE_PATH_JOIN_CHAR ) {
152
- return this . recursivePathString ;
149
+ const isDefault = ( filename === 'fullpath' ) &&
150
+ ( pathJoinCharacter === DEFAULT_RECURSIVE_PATH_JOIN_CHAR ) ;
151
+
152
+ if ( isDefault && ( this . defaultPathStringCache !== undefined ) ) {
153
+ return this . defaultPathStringCache ;
153
154
}
154
155
155
- return this . recursivePath
156
+ const result = this . recursivePath
156
157
. map ( ( path ) => {
157
158
if ( filename === 'fullpath' ) {
158
159
return `'${ path } '` ;
@@ -168,6 +169,12 @@ export class RecursiveReference extends ResolveError {
168
169
) ;
169
170
} )
170
171
. join ( pathJoinCharacter ) ;
172
+
173
+ if ( isDefault ) {
174
+ this . defaultPathStringCache = result ;
175
+ }
176
+
177
+ return result ;
171
178
}
172
179
173
180
/**
@@ -183,15 +190,22 @@ export class RecursiveReference extends ResolveError {
183
190
return false ;
184
191
}
185
192
186
- // TODO: @lego - check array lengths first
193
+ // performance optimization - compare number of paths in the
194
+ // recursive path chains first to avoid comparison of all strings
195
+ if ( this . recursivePath . length !== other . recursivePath . length ) {
196
+ return false ;
197
+ }
198
+
199
+ const myRecursivePath = this . getRecursivePathString ( 'fullpath' ) ;
200
+ const theirRecursivePath = other . getRecursivePathString ( 'fullpath' ) ;
187
201
188
- // performance optimization - if the paths lengths don't match,
202
+ // performance optimization - if the path lengths don't match,
189
203
// no need to compare entire strings as they must be different
190
- if ( this . recursivePathString . length !== other . recursivePathString . length ) {
204
+ if ( myRecursivePath . length !== theirRecursivePath . length ) {
191
205
return false ;
192
206
}
193
207
194
- return this . recursivePathString === other . recursivePathString ;
208
+ return myRecursivePath === theirRecursivePath ;
195
209
}
196
210
197
211
/**
0 commit comments