@@ -120,13 +120,9 @@ function getInliningInfo(file: SourceFile, startPosition: number, tryWithReferen
120
120
if ( ! referencedSymbols || referencedSymbols . length !== 1 ) {
121
121
return undefined ;
122
122
}
123
+ const referenceNodes = getReferenceNodes ( referencedSymbols [ 0 ] . references , name ) ;
123
124
124
- // Only replace node references, and exclude the original variable too.
125
- const references = mapDefined ( referencedSymbols [ 0 ] . references , entry =>
126
- entry . kind === FindAllReferences . EntryKind . Node ? entry . node === name ? undefined : entry . node : undefined
127
- ) ;
128
-
129
- return references . length === 0 ? undefined : { references, declaration : parent , replacement : parent . initializer } ;
125
+ return referenceNodes && { references : referenceNodes , declaration : parent , replacement : parent . initializer } ;
130
126
}
131
127
132
128
if ( tryWithReferenceToken && isIdentifier ( token ) ) {
@@ -136,21 +132,40 @@ function getInliningInfo(file: SourceFile, startPosition: number, tryWithReferen
136
132
return undefined ;
137
133
}
138
134
139
- const { definition } = referencedSymbols [ 0 ] ;
135
+ const { definition, references } = referencedSymbols [ 0 ] ;
140
136
if ( definition ?. type !== FindAllReferences . DefinitionKind . Symbol ) {
141
137
return undefined ;
142
138
}
143
139
144
140
const { valueDeclaration } = definition . symbol ;
145
141
if ( valueDeclaration && isInitializedVariable ( valueDeclaration ) && isVariableDeclarationInVariableStatement ( valueDeclaration ) ) {
146
- const references = mapDefined ( referencedSymbols [ 0 ] . references , entry =>
147
- entry . kind === FindAllReferences . EntryKind . Node ? entry . node === valueDeclaration . name ? undefined : entry . node : undefined
148
- ) ;
142
+ const referenceNodes = getReferenceNodes ( references , valueDeclaration . name ) ;
149
143
150
- return references . length === 0 ? undefined : { references, declaration : valueDeclaration , replacement : valueDeclaration . initializer } ;
144
+ return referenceNodes && { references : referenceNodes , declaration : valueDeclaration , replacement : valueDeclaration . initializer } ;
151
145
}
152
146
}
153
147
154
148
// TODO: Do we want to have other errors too?
155
149
return { error : getLocaleSpecificMessage ( Diagnostics . Could_not_find_variable_to_inline ) } ;
150
+ }
151
+
152
+ function getReferenceNodes ( entries : readonly FindAllReferences . Entry [ ] , declaration : Node ) {
153
+ const referenceNodes = mapDefined ( entries , entry => {
154
+ // Only replace node references, and exclude the original variable too.
155
+ if ( entry . kind !== FindAllReferences . EntryKind . Node || entry . node === declaration ) {
156
+ return undefined ;
157
+ }
158
+
159
+ // Only inline if all references are reads. Else we might end up with an invalid scenario like:
160
+ // const y = x++ + 1 -> const y = 2++ + 1
161
+ if ( FindAllReferences . isWriteAccessForReference ( entry . node ) ) {
162
+ return undefined ;
163
+ }
164
+
165
+ return entry . node ;
166
+ } ) ;
167
+
168
+ // Return undefined if the only reference is the declaration itself, or if a reference
169
+ // isn't applicable for inlining.
170
+ return referenceNodes . length > 0 && referenceNodes . length === entries . length - 1 ? referenceNodes : undefined ;
156
171
}
0 commit comments