Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 323x 323x 323x 323x 323x 323x 323x 322x 322x 322x 322x 322x 1x 1x 1x 1x 1x 172x 172x 172x 172x 172x 172x 1x 1x 17x 17x 1x 1x 132x 132x 132x 132x 132x 1x 1x 147x 147x 147x 147x 147x 147x 572x 572x 144x 144x 144x 144x 144x 144x 572x 3x 3x 3x 1x 1x 1501x 1501x 1501x 2975x 2046x 2046x 2046x 2046x 144x 144x 2975x 929x 929x 317x 317x 929x 2975x 1040x 1040x 1040x 1x 1x | import {IRegistry} from "../_iregistry"; import {AbstractToken} from "../abap/1_lexer/tokens/abstract_token"; import {StatementNode, TokenNode} from "../abap/nodes"; import {Identifier} from "../abap/4_file_information/_identifier"; import {ABAPObject} from "../objects/_abap_object"; import {ITextDocumentPositionParams} from "./_interfaces"; import {INode} from "../abap/nodes/_inode"; import {Position} from "../position"; import * as LServer from "vscode-languageserver-types"; import {ABAPFile} from "../abap/abap_file"; export interface ICursorData { token: AbstractToken; identifier: Identifier; stack: INode[]; snode: StatementNode; } export class LSPUtils { public static getABAPFile(reg: IRegistry, filename: string): ABAPFile | undefined { const file = reg.getFileByName(filename); if (file === undefined) { return undefined; } const obj = reg.findObjectForFile(file); obj?.parse(); if (obj instanceof ABAPObject) { for (const abapfile of obj.getABAPFiles()) { if (abapfile.getFilename().toUpperCase() === filename.toUpperCase()) { return abapfile; } } } return undefined; } public static tokenToRange(token: AbstractToken): LServer.Range { return LServer.Range.create( token.getStart().getRow() - 1, token.getStart().getCol() - 1, token.getEnd().getRow() - 1, token.getEnd().getCol() - 1); } public static positionToLS(pos: Position): LServer.Position { return LServer.Position.create(pos.getRow() - 1, pos.getCol() - 1); } public static identiferToLocation(identifier: Identifier): LServer.Location { return { uri: identifier.getFilename(), range: LSPUtils.tokenToRange(identifier.getToken()), }; } public static findCursor(reg: IRegistry, pos: ITextDocumentPositionParams): ICursorData | undefined { const file = LSPUtils.getABAPFile(reg, pos.textDocument.uri); if (file === undefined) { return undefined; } const search = new Position(pos.position.line + 1, pos.position.character + 1); for (const statement of file.getStatements()) { const res = this.buildStack(statement, search, [statement]); if (res !== undefined) { return { token: res.token, identifier: new Identifier(res.token, file.getFilename()), stack: res.stack, snode: statement}; } } return undefined; } private static buildStack(node: INode, search: Position, parents: INode[]): {token: AbstractToken, stack: INode[]} | undefined { const stack: INode[] = parents; for (const c of node.getChildren()) { if (c instanceof TokenNode) { const token = c.getFirstToken(); if (token.getRow() === search.getRow() && token.getCol() <= search.getCol() && token.getCol() + token.getStr().length > search.getCol()) { return {token, stack}; } } else { const res = this.buildStack(c, search, stack.concat([c])); if (res !== undefined) { return res; } } } return undefined; } } |