Custom Language support questions - also next steps after Simple

Hi,

[OFFTOPIC] Why I ask you for help. I want to write this plugin to learn more about the platform so I can share some knowledge(in form of blogpost/tutorials) on some topics related to custom language support. Simple language is great as a starting project but it just leaves a lot of unanswered questions for me as to how to extend what is written there. That is why I want to write a plugin that has some basics things like variables and functions so it can be “a next” step after Simple presented in the docs.

I am working on a plugin for some old scripting language. I written BFN/flex files and made some progress towards syntax highlighting, but there are some topics I just can’t wrap around my head just yet.

  1. References/Usages
    Since Simple language example only contains 1 type of statement(SimpleProperty) I have a really hard time understanding what should be a reference in my parser and where should I implement resolve/getReference functions. Let’s take for example few statements:
classDeclaration ::= CLASS_KEYWORD id classBody
constDeclaration ::= CONST_KEYWORD typeType id EQ variableInitializer SEMICOLON
functionDeclaration ::= FUNC_KEYWORD typeTypeOrVoid id functionArguments codeBlock
functionExecution ::= id LPARENTH (expression (COMMA expression)*)* RPARENTH
id ::= IDENTIFIER

and code examples of above statements:

class class_id {...}
const int some_var = 123;
func void some_func() {...}
fun_exec();

What of those rules should implement setName/getName/getReference and what should implement resolve() method because basically each of those under the hood uses id that is basically IDENTIFIER. So meaby only id should have those methods? But if I implement getReference in id wouldn’t that mean that ANY id in my codebase becomes the reference even the declarations(which I think is a bad thing)? So how should I approach it?

  1. Rename/Replace support
    From what I could understand from the docs rename/replace always uses PSI element, and the approach presented in the docs is to create in-memory file and write a new value from text there so it can be replaced, but how do I do that for let’s say complicated consts:
const int some_const_variable = (very_long_complicated_expression + 320) * 22 / 10 + (some_other_constt + 20 - 55);

Or a whole class declaration, or what about refactoring expressions that can’t be in global(file) scope, but part of it needs to be refactored?
I feel like I am missing something regarding this topic.

  1. How should I approach stubbing? I have a pretty big script codebase and I needed to cache in resolve method just the const declarations because it needed like a long second to show just 1 record and now I am kind of afraid of how to proceed with it. I don’t want to cache from scratch all the definitions for classes, functions, consts, variables etc. because it feels like there should already be a solution for that. Also it feels like something that should use a WordScanner, but for some reason it is only mentioned regarding FindUsages action?