@@ -157,90 +157,120 @@ private static GeneratedRoot GenerateDisplayStatements(DataSection dataSection,
157
157
}
158
158
159
159
private static TextEdit InsertBefore ( ISearchableReadOnlyList < ICodeElementsLine > codeLines , Node node , string code )
160
+ => InsertBefore ( codeLines , GetFirstToken ( node ) , code ) ;
161
+
162
+ private static TextEdit InsertAfter ( ISearchableReadOnlyList < ICodeElementsLine > codeLines , Node node , string code )
163
+ => InsertAfter ( codeLines , GetLastToken ( node ) , code ) ;
164
+
165
+ private static Token GetFirstToken ( Node node )
166
+ {
167
+ Debug . Assert ( node != null ) ;
168
+ Debug . Assert ( node . CodeElement != null ) ;
169
+
170
+ if ( node . CodeElement . IsInsideCopy ( ) )
171
+ {
172
+ // Go back up to including COPY directive and return its first token (the COPY token)
173
+ return node . CodeElement . FirstCopyDirective . COPYToken ;
174
+ }
175
+
176
+ // First token of CodeElement
177
+ Debug . Assert ( node . CodeElement . ConsumedTokens . Count > 0 ) ;
178
+ return node . CodeElement . ConsumedTokens [ 0 ] ;
179
+ }
180
+
181
+ private static Token GetLastToken ( Node node )
160
182
{
183
+ // Do not insert inside statements having a body (statement with nested statements)
184
+ // -> Reposition at the end of the whole statement (i.e. on its matching END-xxx node).
185
+ if ( node is StatementWithBody ) node = node . GetLastNode ( ) ;
186
+
187
+ Debug . Assert ( node != null ) ;
161
188
Debug . Assert ( node . CodeElement != null ) ;
162
- int line = node . CodeElement . Line ; // On same line and inserted text ends with a line break
189
+
190
+ if ( node . CodeElement . IsInsideCopy ( ) )
191
+ {
192
+ // Go back up to including COPY directive and return its last token
193
+ var copyDirectiveTokens = node . CodeElement . FirstCopyDirective . ConsumedTokens . SelectedTokensOnSeveralLines ;
194
+ Debug . Assert ( copyDirectiveTokens . Length > 0 ) ;
195
+ Debug . Assert ( copyDirectiveTokens [ ^ 1 ] . Count > 0 ) ;
196
+ return copyDirectiveTokens [ ^ 1 ] [ ^ 1 ] ;
197
+ }
198
+
199
+ // Last token of CodeElement
200
+ Debug . Assert ( node . CodeElement . ConsumedTokens . Count > 0 ) ;
201
+ return node . CodeElement . ConsumedTokens [ ^ 1 ] ;
202
+ }
203
+
204
+ private static TextEdit InsertBefore ( ISearchableReadOnlyList < ICodeElementsLine > codeLines , Token token , string code )
205
+ {
206
+ int line = token . Line ; // On same line and inserted text ends with a line break
163
207
string newText = code + Environment . NewLine ;
164
208
int character = 0 ; // At beginning of the line, except when CodeElement is not the first
165
209
166
- var insertionToken = node . CodeElement . ConsumedTokens . FirstOrDefault ( ) ;
167
- if ( insertionToken != null )
210
+ // Is the first token of the CodeElement also the first token on the line ?
211
+ var tokensLine = token . TokensLine ;
212
+ if ( token != tokensLine . SourceTokens . First ( ) )
168
213
{
169
- // Is the first token of the CodeElement also the first token on the line ?
170
- var tokensLine = insertionToken . TokensLine ;
171
- if ( insertionToken != tokensLine . SourceTokens . First ( ) )
172
- {
173
- // Insertion point is right before CodeElement
174
- character = node . CodeElement . StartIndex ;
175
- // Start a new line and align text located beyond insertion point on its current column
176
- newText = $ " { Environment . NewLine } { newText } { BeginLine ( tokensLine . IndicatorChar , character ) } " ;
177
- }
178
- else
214
+ // Insertion point is right before CodeElement
215
+ character = token . StartIndex ;
216
+ // Start a new line and align text located beyond insertion point on its current column
217
+ newText = $ " { Environment . NewLine } { newText } { BeginLine ( tokensLine . IndicatorChar , character ) } " ;
218
+ }
219
+ else
220
+ {
221
+ // Nothing before insertion point, check for comments preceding the insertion line
222
+ int lineIndex = line - 2 ; // Start with the index of the line before insertion line (line is 1-based whereas lineIndex is 0-based)
223
+ while ( lineIndex >= 0 )
179
224
{
180
- // Nothing before insertion point, check for comments preceding the insertion line
181
- int lineIndex = line - 2 ; // Start with the index of the line before insertion line (line is 1-based whereas lineIndex is 0-based)
182
- while ( lineIndex >= 0 )
225
+ var codeLine = codeLines [ lineIndex ] ;
226
+ if ( IsComment ( codeLine ) || codeLine . Type == CobolTextLineType . MultiFormalizedComment )
183
227
{
184
- var codeLine = codeLines [ lineIndex ] ;
185
- if ( IsComment ( codeLine ) || codeLine . Type == CobolTextLineType . MultiFormalizedComment )
186
- {
187
- // Insert before this comment/debug line
188
- line = lineIndex + 1 ;
189
- character = 0 ;
190
- lineIndex -- ;
191
- }
192
- else
193
- {
194
- // Source line: keep current insertion position
195
- break ;
196
- }
228
+ // Insert before this comment/debug line
229
+ line = lineIndex + 1 ;
230
+ character = 0 ;
231
+ lineIndex -- ;
232
+ }
233
+ else
234
+ {
235
+ // Source line: keep current insertion position
236
+ break ;
197
237
}
198
238
}
199
239
}
200
240
201
241
return TextEdit . Insert ( new Position ( ) { line = line , character = character } , newText ) ;
202
242
}
203
243
204
- private static TextEdit InsertAfter ( ISearchableReadOnlyList < ICodeElementsLine > codeLines , Node node , string code )
244
+ private static TextEdit InsertAfter ( ISearchableReadOnlyList < ICodeElementsLine > codeLines , Token token , string code )
205
245
{
206
- // Do not insert inside statements having a body (statement with nested statements)
207
- // -> Reposition at the end of the whole statement (on its matching END-xxx node).
208
- if ( node is StatementWithBody ) node = node . GetLastNode ( ) ;
209
-
210
- Debug . Assert ( node != null ) ;
211
- Debug . Assert ( node . CodeElement != null ) ;
212
- int line = node . CodeElement . LineEnd ; // On same line and inserted text starts with a line break:
246
+ int line = token . Line ; // On same line and inserted text starts with a line break:
213
247
string newText = Environment . NewLine + code ;
214
- int character = node . CodeElement . StopIndex + 1 ; // At CodeElement end
248
+ int character = token . StopIndex + 1 ; // At CodeElement/CopyDirective end
215
249
216
- var insertionToken = node . CodeElement . ConsumedTokens . LastOrDefault ( ) ;
217
- if ( insertionToken != null )
250
+ // Is there anything after insertion point ?
251
+ var tokensLine = token . TokensLine ;
252
+ if ( tokensLine . Length > character )
218
253
{
219
- // Is there anything after insertion point ?
220
- var tokensLine = insertionToken . TokensLine ;
221
- if ( tokensLine . Length > character )
222
- {
223
- // Align text located beyond insertion point on its current column
224
- newText += BeginLine ( tokensLine . IndicatorChar , character ) ;
225
- }
226
- else
254
+ // Align text located beyond insertion point on its current column
255
+ newText += BeginLine ( tokensLine . IndicatorChar , character ) ;
256
+ }
257
+ else
258
+ {
259
+ // Nothing after insertion point, check for comments following the insertion line
260
+ int lineIndex = line ; // Initialize with insertion line which is 1-based, thus we start here with the index of the line after insertion line
261
+ while ( lineIndex < codeLines . Count )
227
262
{
228
- // Nothing after insertion point, check for comments following the insertion line
229
- int lineIndex = line ; // Initialize with insertion line which is 1-based, thus we start here with the index of the line after insertion line
230
- while ( lineIndex < codeLines . Count )
263
+ var codeLine = codeLines [ lineIndex ] ;
264
+ if ( IsComment ( codeLine ) ) // Do not consider MultiFormalizedComment as they are attached to the code following them
265
+ {
266
+ // Insert after this comment/debug line
267
+ line = ++ lineIndex ;
268
+ character = codeLine . Length ;
269
+ }
270
+ else
231
271
{
232
- var codeLine = codeLines [ lineIndex ] ;
233
- if ( IsComment ( codeLine ) ) // Do not consider MultiFormalizedComment as they are attached to the code following them
234
- {
235
- // Insert after this comment/debug line
236
- line = ++ lineIndex ;
237
- character = codeLine . Length ;
238
- }
239
- else
240
- {
241
- // Source line: keep current insertion position
242
- break ;
243
- }
272
+ // Source line: keep current insertion position
273
+ break ;
244
274
}
245
275
}
246
276
}
0 commit comments