Skip to content

Commit

Permalink
Better support for prefixes/labels
Browse files Browse the repository at this point in the history
Signed-off-by: worksofliam <[email protected]>
  • Loading branch information
worksofliam committed Dec 19, 2024
1 parent 17d5faf commit ffac453
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 39 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "vscode-db2i",
"displayName": "Db2 for IBM i",
"description": "Db2 for IBM i tools in VS Code",
"version": "1.7.0-syntaxcheck3`",
"version": "1.7.0-syntaxcheck3",
"engines": {
"vscode": "^1.95.0"
},
Expand Down
3 changes: 2 additions & 1 deletion src/language/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { completionProvider } from "./completionProvider";
import { formatProvider } from "./formatProvider";
import { hoverProvider, openProvider } from "./hoverProvider";
import { signatureProvider } from "./parameterProvider";
import { problemProvider } from "./problemProvider";
import { checkDocumentDefintion, problemProvider } from "./problemProvider";
import { Db2StatusProvider } from "./statusProvider";

export const sqlLanguageStatus = new Db2StatusProvider();
Expand All @@ -17,6 +17,7 @@ export function languageInit() {
hoverProvider,
openProvider,
problemProvider,
checkDocumentDefintion,
sqlLanguageStatus
);

Expand Down
91 changes: 59 additions & 32 deletions src/language/providers/problemProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Document from "../sql/document";
import { remoteAssistIsEnabled } from "./logic/available";
import Configuration from "../../configuration";
import { SQLStatementChecker, SqlSyntaxError } from "../../connection/syntaxChecker";
import { StatementGroup, StatementType } from "../sql/types";

export interface CompletionType {
order: string;
Expand All @@ -15,6 +16,8 @@ export interface CompletionType {
icon: CompletionItemKind;
}

type StatementRange = [number, number];

const diagnosticTypeMap: { [key: string]: DiagnosticSeverity } = {
'error': DiagnosticSeverity.Error,
'warning': DiagnosticSeverity.Warning,
Expand Down Expand Up @@ -57,24 +60,33 @@ export const checkDocumentDefintion = commands.registerCommand(CHECK_DOCUMENT_CO
const sqlDocument = new Document(content);

window.withProgress({ location: ProgressLocation.Window, title: `Checking SQL Syntax...` }, async () => {
const groups = sqlDocument.getStatementGroups();
const allGroups = sqlDocument.getStatementGroups();
let statementRanges: StatementRange[] = [];

for (const group of allGroups) {
const range = getStatementRangeFromGroup(group);
if (range) {
statementRanges.push(range);
}
}

const sqlStatementContents = groups.map(group => content.substring(group.range.start, group.range.end));
const sqlStatementContents = statementRanges.map(range => content.substring(range[0], range[1]));
const syntaxChecked = await checker.checkMultipleStatements(sqlStatementContents);

if (syntaxChecked) {
if (syntaxChecked.length > 0) {
let errors: Diagnostic[] = [];
for (let i = 0; i < groups.length; i++) {
for (let i = 0; i < statementRanges.length; i++) {
const currentRange = statementRanges[i];
const groupError = syntaxChecked[i];

if (shouldShowError(groupError)) {

const selectedWord
= document.getWordRangeAtPosition(document.positionAt(groups[i].range.start + groupError.offset))
= document.getWordRangeAtPosition(document.positionAt(currentRange[0] + groupError.offset))
|| new Range(
document.positionAt(groups[i].range.start + groupError.offset - 1),
document.positionAt(groups[i].range.start + groupError.offset)
document.positionAt(currentRange[0] + groupError.offset - 1),
document.positionAt(currentRange[0] + groupError.offset)
);

errors.push({
Expand Down Expand Up @@ -115,34 +127,49 @@ export const problemProvider = workspace.onDidChangeTextDocument(e => {
const offset = document.offsetAt(position);

const sqlDoc = new Document(content);
const currentStatement = sqlDoc.getGroupByOffset(offset);

if (currentStatement) {
const statementContents = document.getText(new Range(
document.positionAt(currentStatement.range.start),
document.positionAt(currentStatement.range.end)
));

const result = await checker.call(statementContents);
if (result && shouldShowError(result)) {
const selectedWord
= document.getWordRangeAtPosition(document.positionAt(currentStatement.range.start + result.offset))
|| new Range(
document.positionAt(currentStatement.range.start + result.offset - 1),
document.positionAt(currentStatement.range.start + result.offset)
);

sqlDiagnosticCollection.set(document.uri, [{
message: `${result.text} - ${result.sqlstate}`,
code: result.sqlid,
range: selectedWord,
severity: diagnosticTypeMap[result.type],
}]);
} else {
sqlDiagnosticCollection.set(document.uri, []);
const currentGroup = sqlDoc.getGroupByOffset(offset);

if (currentGroup) {
const statementRange = getStatementRangeFromGroup(currentGroup);

if (statementRange) {
const statementContents = content.substring(statementRange[0], statementRange[1]);

const result = await checker.call(statementContents);
if (result && shouldShowError(result)) {
const selectedWord
= document.getWordRangeAtPosition(document.positionAt(statementRange[0] + result.offset))
|| new Range(
document.positionAt(statementRange[0] + result.offset - 1),
document.positionAt(statementRange[0] + result.offset)
);

sqlDiagnosticCollection.set(document.uri, [{
message: `${result.text} - ${result.sqlstate}`,
code: result.sqlid,
range: selectedWord,
severity: diagnosticTypeMap[result.type],
}]);
} else {
sqlDiagnosticCollection.set(document.uri, []);
}
}
}
}
}, getCheckerTimeout());
}
});
});

function getStatementRangeFromGroup(currentGroup: StatementGroup): StatementRange|undefined {
let statementRange: StatementRange|undefined;
const firstStatement = currentGroup.statements[0];
if (firstStatement && firstStatement.type !== StatementType.Unknown) {
statementRange = [currentGroup.range.start, currentGroup.range.end];

if (firstStatement.getLabel()) {
statementRange = [firstStatement.tokens[2].range.start, currentGroup.range.end];
}
}

return statementRange;
}
9 changes: 4 additions & 5 deletions src/language/sql/statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ export default class Statement {
if (tokenIs(first, `word`, `EXEC`) && tokenIs(this.tokens[1], `word`, `SQL`)) {
first = this.tokens[2];
} else if (tokenIs(first, `word`) && tokenIs(this.tokens[1], `colon`)) {
first = this.tokens[2];
}

if (first.value !== undefined && tokenIs(this.tokens[1], `colon`)) {
// Possible label?
this.label = first.value;
first = this.tokens[2];
}
Expand All @@ -40,6 +35,10 @@ export default class Statement {
}
}

getLabel(): string|undefined {
return this.label;
}

isCompoundStart() {
if (this.tokens.length === 1 && tokenIs(this.tokens[0], `keyword`, `BEGIN`)) {
return true;
Expand Down

0 comments on commit ffac453

Please sign in to comment.