Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions packages/language-support/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@
"node": ">=22.15.0"
},
"dependencies": {
"antlr4": "4.13.2",
"antlr4ng": "3.0.16",
"antlr4-c3": "3.4.4",
"fastest-levenshtein": "^1.0.16",
"vscode-languageserver-types": "^3.17.3"
},
"scripts": {
"gen-parser": "cross-env ANTLR4_TOOLS_ANTLR_VERSION=4.13.2 antlr4 -Dlanguage=TypeScript -visitor src/antlr-grammar/CypherCmdLexer.g4 src/antlr-grammar/CypherCmdParser.g4 -o src/generated-parser/ -Xexact-output-dir",
"build": "cd ../../vendor/antlr4-c3/ && pnpm build && cd - && pnpm gen-parser && concurrently 'npm:build-esm-and-types' 'npm:build-commonjs' 'npm:build-cypherfmt-cli'",
"build-esm-and-types": "tsc --module esnext --outDir dist/esm/project/language-support && cp src/syntaxValidation/semanticAnalysis.js dist/esm/project/language-support/src/syntaxValidation/semanticAnalysis.js && mkdir -p dist/esm/vendor/antlr4-c3/dist/ && cp -r ../../vendor/antlr4-c3/dist/esm dist/esm/vendor/antlr4-c3/dist/",
"gen-parser": "cross-env antlr-ng -Dlanguage=TypeScript --generate-visitor true src/antlr-grammar/CypherCmdLexer.g4 src/antlr-grammar/CypherCmdParser.g4 -o src/generated-parser/ --exact-output-dir",
"build": "pnpm gen-parser && concurrently 'npm:build-esm-and-types' 'npm:build-commonjs' 'npm:build-cypherfmt-cli'",
"build-esm-and-types": "tsc --module esnext --outDir dist/esm/project/language-support && cp src/syntaxValidation/semanticAnalysis.js dist/esm/project/language-support/src/syntaxValidation/semanticAnalysis.js",
"build-commonjs": "esbuild ./src/index.ts --bundle --format=cjs --sourcemap --outfile=dist/cjs/index.cjs",
"build-cypherfmt-cli": "esbuild ./src/formatting/cli.ts --bundle --format=esm --sourcemap --outfile=dist/esm/formatting/cli.mjs --external:fs --external:path",
"dev": "pnpm build && concurrently 'tsc --module esnext --outDir dist/esm/project/language-support --watch' 'npm:build-commonjs -- --watch'",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import {
InsertTextFormat,
} from 'vscode-languageserver-types';
import { DbSchema } from '../dbSchema';
import CypherLexer from '../generated-parser/CypherCmdLexer';
import CypherParser, {
import { CypherCmdLexer as CypherLexer } from '../generated-parser/CypherCmdLexer';
import {
CypherCmdParser as CypherParser,
CallClauseContext,
Expression2Context,
} from '../generated-parser/CypherCmdParser';
Expand All @@ -24,12 +25,13 @@ import {

import { getMethodName, ParsedStatement } from '../parserWrapper';

import type { CandidateRule } from '../../../../vendor/antlr4-c3/dist/esm/index.js';
import type { ICandidateRule } from 'antlr4-c3';
import {
CandidatesCollection,
CodeCompletionCore,
Token,
} from '../../../../vendor/antlr4-c3/dist/esm/index.js';
} from 'antlr4-c3';
import { Token } from 'antlr4ng';

import { _internalFeatureFlags } from '../featureFlags';
import {
CompletionItem,
Expand Down Expand Up @@ -80,7 +82,7 @@ const procedureReturnCompletions = (
};

const functionNameCompletions = (
candidateRule: CandidateRule,
candidateRule: ICandidateRule,
tokens: Token[],
dbSchema: DbSchema,
cypherVersion: CypherVersion,
Expand All @@ -93,7 +95,7 @@ const functionNameCompletions = (
);

const procedureNameCompletions = (
candidateRule: CandidateRule,
candidateRule: ICandidateRule,
tokens: Token[],
dbSchema: DbSchema,
cypherVersion: CypherVersion,
Expand Down Expand Up @@ -143,7 +145,7 @@ function getMethodCompletionItem(
}

const namespacedCompletion = (
candidateRule: CandidateRule,
candidateRule: ICandidateRule,
tokens: Token[],
signatures: Record<string, Neo4jFunction> | Record<string, Neo4jProcedure>,
type: 'procedure' | 'function',
Expand Down Expand Up @@ -246,8 +248,10 @@ function getTokenCompletions(
const firstToken = isConsoleCommand
? tokenNames[tokenNumber].toLowerCase()
: tokenNames[tokenNumber];



const followUpIndexes = followUpList.indexes;
const followUpIndexes = followUpList;
const firstIgnoredToken = followUpIndexes.findIndex((t) =>
ignoredTokens.has(t),
);
Expand All @@ -269,12 +273,12 @@ function getTokenCompletions(
' ' +
(isConsoleCommand ? followUpString.toLowerCase() : followUpString);

if (followUpList.optional) {
return [
{ label: firstToken, kind },
{ label: followUp, kind },
];
}
// if (followUpList.optional) {
// return [
// { label: firstToken, kind },
// { label: followUp, kind },
// ];
// }

return [{ label: followUp, kind }];
}
Expand Down Expand Up @@ -345,7 +349,7 @@ enum ExpectedParameterType {
Any = 'ANY',
}

const inferExpectedParameterTypeFromContext = (context: CandidateRule) => {
const inferExpectedParameterTypeFromContext = (context: ICandidateRule) => {
const parentRule = context.ruleList.at(-1);

if (
Expand Down Expand Up @@ -421,15 +425,15 @@ function couldBeNodeOrRel(
}

function calculateNamespacePrefix(
candidateRule: CandidateRule,
candidateRule: ICandidateRule,
tokens: Token[],
): string | null {
const ruleTokens = tokens.slice(candidateRule.startTokenIndex);
const lastNonEOFToken = ruleTokens.at(-2);

const nonSpaceTokens = ruleTokens.filter(
(token) =>
token.type !== CypherLexer.SPACE && token.type !== CypherLexer.EOF,
token.type !== CypherLexer.SPACE && token.type !== CypherLexer.cEOF,
);

const lastNonSpaceIsDot = nonSpaceTokens.at(-1)?.type === CypherLexer.DOT;
Expand Down Expand Up @@ -478,7 +482,7 @@ export function completionCoreCompletion(
// When we have EOF with a different text in the token, it means the parser has failed to parse it.
// We give empty completions in that case because the query is severely broken at the
// point of completion (e.g. an unclosed string)
if (eof.type === CypherLexer.EOF && eof.text !== '<EOF>') {
if (eof.type === CypherLexer.cEOF && eof.text !== '<EOF>') {
return [];
}

Expand Down Expand Up @@ -563,13 +567,13 @@ export function completionCoreCompletion(

if (ruleNumber === CypherParser.RULE_procedureResultItem) {
const callContext = findParent(
parsingResult.lastRule.parentCtx,
parsingResult.lastRule.parent,
(x) => x instanceof CallClauseContext,
);
if (callContext instanceof CallClauseContext) {
const procedureNameCtx = callContext.procedureName();
const existingYieldItems = new Set(
callContext.procedureResultItem_list().map((a) => a.getText()),
callContext.procedureResultItem().map((a) => a.getText()),
);
const name = getMethodName(procedureNameCtx);
return procedureReturnCompletions(
Expand Down Expand Up @@ -794,7 +798,7 @@ type CompletionHelperArgs = {
dbSchema: DbSchema;
previousToken?: Token;
tokens: Token[];
candidateRule: CandidateRule;
candidateRule: ICandidateRule;
};
function completeAliasName({
candidateRule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
PatternElementContext,
QuantifierContext,
} from '../generated-parser/CypherCmdParser';
import { ParserRuleContext } from 'antlr4';
import { ParserRuleContext } from 'antlr4ng';
import { backtickIfNeeded } from './autocompletionHelpers';
import { _internalFeatureFlags } from '../featureFlags';

Expand Down Expand Up @@ -128,7 +128,7 @@ export function completeRelationshipType(
// limitation: not checking PathPatternNonEmptyContext
// limitation: not handling parenthesized paths
const patternContext = findParent(
parsingResult.lastRule.parentCtx,
parsingResult.lastRule.parent,
(x) => x instanceof PatternElementContext,
);

Expand All @@ -137,9 +137,7 @@ export function completeRelationshipType(
.toReversed()
.find((child) => {
if (child instanceof ParserRuleContext) {
if (child.exception === null) {
return true;
}
return true;
}
});

Expand Down
Loading