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 369x 369x 369x 369x 369x 369x 369x 368x 368x 368x 368x 368x 1x 1x 1x 1x 1x 195x 195x 195x 195x 195x 195x 1x 1x 24x 24x 1x 1x 153x 153x 153x 153x 153x 1x 1x 169x 169x 169x 169x 169x 169x 689x 689x 166x 166x 166x 166x 166x 166x 689x 3x 3x 3x 1x 1x 2153x 2153x 2153x 4211x 2747x 2747x 2747x 2747x 166x 166x 4211x 1464x 1464x 412x 412x 1464x 4211x 1575x 1575x 1575x 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;
}
} |