Skip to content

Commit

Permalink
Adds simple warnings on deprecated procedures and functions
Browse files Browse the repository at this point in the history
  • Loading branch information
anderson4j committed Dec 4, 2024
1 parent 532ff90 commit 4eaa1c4
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 2 deletions.
112 changes: 110 additions & 2 deletions packages/language-support/src/syntaxValidation/syntaxValidation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { DiagnosticSeverity, Position } from 'vscode-languageserver-types';
import {
DiagnosticSeverity,
DiagnosticTag,
Position,
} from 'vscode-languageserver-types';

import { ParserRuleContext, ParseTree, Token } from 'antlr4';
import { DbSchema } from '../dbSchema';
Expand Down Expand Up @@ -138,6 +142,60 @@ function generateProcedureNotFoundError(
return error;
}

function generateProcedureDeprecatedWarning(
parsedProcedure: ParsedProcedure,
): SyntaxDiagnostic {
const rawText = parsedProcedure.rawText;
const nameChunks = rawText.split('\n');
const linesOffset = nameChunks.length - 1;
const lineIndex = parsedProcedure.line - 1;
const startColumn = parsedProcedure.column;
const endColumn =
linesOffset == 0
? startColumn + rawText.length
: nameChunks.at(-1)?.length ?? 0;

const warning: SyntaxDiagnostic = {
tags: [DiagnosticTag.Deprecated],
severity: DiagnosticSeverity.Warning,
range: {
start: Position.create(lineIndex, startColumn),
end: Position.create(lineIndex + linesOffset, endColumn),
},
offsets: parsedProcedure.offsets,
message: `Procedure ${parsedProcedure.name} is deprecated.`,
};

return warning;
}

function generateFunctionDeprecatedWarning(
parsedFunction: ParsedFunction,
): SyntaxDiagnostic {
const rawText = parsedFunction.rawText;
const nameChunks = rawText.split('\n');
const linesOffset = nameChunks.length - 1;
const lineIndex = parsedFunction.line - 1;
const startColumn = parsedFunction.column;
const endColumn =
linesOffset == 0
? startColumn + rawText.length
: nameChunks.at(-1)?.length ?? 0;

const warning: SyntaxDiagnostic = {
tags: [DiagnosticTag.Deprecated],
severity: DiagnosticSeverity.Warning,
range: {
start: Position.create(lineIndex, startColumn),
end: Position.create(lineIndex + linesOffset, endColumn),
},
offsets: parsedFunction.offsets,
message: `Function ${parsedFunction.name} is deprecated.`,
};

return warning;
}

function warnOnUndeclaredLabels(
parsingResult: ParsedStatement,
dbSchema: DbSchema,
Expand Down Expand Up @@ -300,6 +358,14 @@ export function validateSemantics(
current,
dbSchema,
);
const procedureWarnings = warningOnDeprecatedProcedure(
current,
dbSchema,
);
const functionWarnings = warningOnDeprecatedFunction(
current,
dbSchema,
);

const { notifications, errors } = wrappedSemanticAnalysis(
cmd.statement,
Expand All @@ -312,7 +378,12 @@ export function validateSemantics(
parseResult: current,
});
return semanticDiagnostics
.concat(functionErrors, procedureErrors)
.concat(
functionErrors,
procedureErrors,
functionWarnings,
procedureWarnings,
)
.sort(sortByPositionAndMessage);
}
}
Expand All @@ -325,6 +396,43 @@ export function validateSemantics(
return [];
}

function warningOnDeprecatedProcedure(
parsingResult: ParsedStatement,
dbSchema: DbSchema,
): SyntaxDiagnostic[] {
const warnings: SyntaxDiagnostic[] = [];
if (dbSchema.procedures) {
const proceduresInQuery = parsingResult.collectedProcedures;

proceduresInQuery.forEach((parsedProcedure) => {
const procedureDeprecated =
dbSchema.procedures?.[parsedProcedure.name]?.option?.deprecated;
if (procedureDeprecated) {
warnings.push(generateProcedureDeprecatedWarning(parsedProcedure));
}
});
}
return warnings;
}

function warningOnDeprecatedFunction(
parsingResult: ParsedStatement,
dbSchema: DbSchema,
): SyntaxDiagnostic[] {
const warnings: SyntaxDiagnostic[] = [];
if (dbSchema.functions) {
const functionsInQuery = parsingResult.collectedFunctions;
functionsInQuery.forEach((parsedFunction) => {
const functionDeprecated =
dbSchema.functions?.[parsedFunction.name]?.isDeprecated;
if (functionDeprecated) {
warnings.push(generateFunctionDeprecatedWarning(parsedFunction));
}
});
}
return warnings;
}

function errorOnUndeclaredFunctions(
parsingResult: ParsedStatement,
dbSchema: DbSchema,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,44 @@
import { DiagnosticTag } from 'vscode-languageserver-types';
import { testData } from '../testData';
import { getDiagnosticsForQuery } from './helpers';

describe('Functions semantic validation spec', () => {
test('Syntax validation warns on deprecated function when database can be contacted', () => {
const query = `RETURN id()`;
expect(
getDiagnosticsForQuery({
query,
dbSchema: {
labels: ['Dog', 'Cat'],
relationshipTypes: ['Person'],
functions: testData.mockSchema.functions,
},
}),
).toEqual(
expect.arrayContaining([
{
tags: [DiagnosticTag.Deprecated],
offsets: {
end: 9,
start: 7,
},
message: 'Function id is deprecated.',
range: {
end: {
character: 9,
line: 0,
},
start: {
character: 7,
line: 0,
},
},
severity: 2,
},
]),
);
});

test('Syntax validation errors on missing function when database can be contacted', () => {
const query = `RETURN dontpanic("marvin")`;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,44 @@
import { DiagnosticTag } from 'vscode-languageserver-types';
import { testData } from '../testData';
import { getDiagnosticsForQuery } from './helpers';

describe('Procedures semantic validation spec', () => {
test('Syntax validation warns on deprecated procedure when database can be contacted', () => {
const query = `CALL db.create.setVectorProperty()`;
expect(
getDiagnosticsForQuery({
query,
dbSchema: {
labels: ['Dog', 'Cat'],
relationshipTypes: ['Person'],
procedures: testData.mockSchema.procedures,
},
}),
).toEqual(
expect.arrayContaining([
{
tags: [DiagnosticTag.Deprecated],
offsets: {
end: 32,
start: 5,
},
message: 'Procedure db.create.setVectorProperty is deprecated.',
range: {
end: {
character: 32,
line: 0,
},
start: {
character: 5,
line: 0,
},
},
severity: 2,
},
]),
);
});

test('Syntax validation warns on missing procedures when database can be contacted', () => {
const query = `CALL dontpanic("marvin")`;

Expand Down

0 comments on commit 4eaa1c4

Please sign in to comment.