Function list for C++ do not show constructors
-
Sorry that no one got back to you in the last few weeks.
The Function List parsing is based in regular expressions. The original developer of the c++ function-list definition may not have tested against that particular case; or it may be that some ways of defining the constructor will show up and others won’t. But I can confirm that
class SomeClass { SomeClass(void) { 1; } void MyMethod(void) { return; } }
shows
MyMethod
but notSomeClass
, so I can confirm the limitation.I don’t know if our FunctionList FAQ-writer and guru @MAPJe71 has an alternate cpp definition laying around somewhere that fixes that problem (it wouldn’t surprise me), or if he has any ideas to contribute but hadn’t noticed your post (so now he’ll have an @-mention notification the next time he logs in).
But barring guru-intervention, since it’s just the regex in
%ProgramFiles%\notepad++\functionList\cpp.xml
(assuming you have a normal installation), I could suggest that you copy that to%AppData%\Notepad++\functionList\cpp.xml
(assuming you have a normal installation) – a functionList definition there will take priority over the default one in the application directory, so you could then try to customize the definition to work for constructor-style functions. (You have to restart for the appdata version to take effect, and have to restart every time you edit the definition to get it to re-read the definition. It’s can be a pain to develop a new function list definition, I admit; sorry.) -
@PeterJones ,
I kind of must have missed this one, (it happens) but it seems to me that perhaps the constructor code was just left alone because it seems that it is already available, via the Class declaration, and it doesn’t fit the profile for a Function, which would be the next and only next possible level for the functionList format, since as you’ve pointed out before there is no next level of indentation available.Just spitballing here, but maybe the only thing they can do, is add an additional function parsing regex based on the constructor format to make it recognize that particular layout… kind of like you did adding our “with” as an additionally recognized function id, although having looked at the C++ functionList regex, good luck with figuring out where to put that at. :-) I had enough trouble just following it, let alone trying to implement it. :-)
-
@Lycan-Thrope said in Function list for C++ do not show constructors:
@PeterJones ,
… it seems to me that perhaps the constructor code was just left alone because it seems that it is already available, via the Class declaration, and it doesn’t fit the profile for a Function, which would be the next and only next possible level for the functionList format, since as you’ve pointed out before there is no next level of indentation available.The
class SomeClass
defines the name of the class. A constructor is a method/function inside the class (in this example,SomeClass(void)
) which is used for initializing the attributes and anything else that needs constructing. It makes complete sense for the constructor(s) to be listed in at the Function level in Function List, just like any other method of that class is.The constructor is sometimes, but not always, the first function defined in a class. But since you cannot double-click on the name of the Class in FunctionList , you cannot easily get to it.
Just spitballing here, but maybe the only thing they can do, is add an additional function parsing regex based on the constructor format to make it recognize that particular layout…
The only difference between the syntax for a constructor in a class and another method in the class is that the other methods often have data types before the method name, whereas constructors have an assumed return-type being the class’s type itself. But since it is valid (though a
-Wimplicit-int
warning) to declare a function without a return type even in ancient C code (it will default to anint
in the absense of a declared type), then this example functionanother()
will compile/link/run with a gcc c compiler, but it will give a warning while compiling#include <stdio.h> #include <stdlib.h> another(void) { printf("Hello, from another world\n"); return 1; } int main() { printf("Hello from main\n"); another(); return 1; }
Given that’s valid, and that a constructor method is a function in the same way that any other class method is a function, then it’s quite reasonable to expect that a constructor in a class should be recognized and treated as function/method as part of that class.
Interestingly, the c function-list recognizes
another(void)
as a function definition, but the c++ function-list does not, even though gcc compiles the .c version and g++ compiles the c++ version just fine.
although having looked at the C++ functionList regex, good luck with figuring out where to put that at. :-) I had enough trouble just following it, let alone trying to implement it. :-)
You’ll notice I haven’t been brave enough to delve into that monster regex myself. ;-) Maybe someday, but not today.
-
@PeterJones ,
In light of your points, that even without a return type, it should be recognized as a function, then I guess it is an issue for the C++ functionList file.As far as the C functionList regex recognizing it, that would seem normal wouldn’t it, since it ONLY recognizes functions instead of classes? And it is in the correct format for a function so… :-)
Anyway, maybe one day I’ll really try and wade into that mess…but not today. :-)
-
Thanks for the answer, I thought nobody cares! And destructors are also missing. And that is serious flaw of the function list functionality for c++. Normally class has more constructors, each with different arguments and all these are missing. The regex for implementing the function list is too complicated for easy customization and I see that this is not only my opinion :)
-
@Mario-Korva ,
That’s probably why I never really got into learning C++. I already knew some C, which I was using to segue into GOC (Geoworks Object C) which was OOP, and I also use dBASE Plus, which is OOP, and C++ just always seemed to be too complicated to me since it’s description of C with Objects seemed like a patchwork fix of sorts. It needs to be simpler, but alas, that is only my opinion, but explains why I never really sought to do more with it, too many rules and variations. :( -
C++ just always seemed to be too complicated to me since it’s description of C with Objects seemed like a patchwork fix of sorts.
Have you seen what they’ve done with it since 2011?
It’s true the Win32 API was released when C++ was just ANSI C with some features added, but that was 35 years ago.
-
@Mario-Korva, if you want to read an expert’s opinion on how difficult it is to intelligently parse C++ source files, I highly recommend this GitHub discussion: On limitations of Geany for C++
-
@rdipardo said in Function list for C++ do not show constructors:
Have you seen what they’ve done with it since 2011?
To be fair, when I was working to learn C and was taking a crack at C++ in the same stroke, the timeline was 1991, under DOS, about the same time as I was simultaneously trying to learn Assembly, so that might have something to do with it. :-) So your time estimate is about right, it’s been 32 years since I seriously considered learning C++. Feeling old at the moment…give me a sec. ;-)
-
Feeling old at the moment…
It happens, but the point I was making with the linked GH discussion is that a sprawling regular expression pasted into an XML descriptor should not be considered a function “parser”. It’s just another one of N++'s many technical debts, inherited back when XML was the JSON of Web 1.0.
If contemporary C++ is too complex for UCtags (which is a genuine parser), then that’s the end of the matter. Either Geany and N++ get first-class LSP support, or C++ devs with real work to do should look elsewhere.
-
@rdipardo said in Function list for C++ do not show constructors:
If contemporary C++ is too complex for UCtags (which is a genuine parser), then that’s the end of the matter. Either Geany and N++ get first-class LSP support, or C++ devs with real work to do should look elsewhere.
Which is why, with few exceptions, someone usually uses the tool from the tool supplier as the best weapon of choice when it comes to the IDE/development of code…and why NPP is better suited for UDL’s of low complexity for customization and general use.
I personally have an animus toward LSP’s unless they are going to be freely available and freely usable locally, i.e. download and use the server aspect locally on the computer when not in a network scenario. I get the idea of not wanting to reinvent the wheel, but at the cost of independence and autonomy, too much centralization is not necessarily a good thing IMHO. :-)
-
@PeterJones and others
Constructors and destructors do not have return type. Researching Regex sequences of the Function List parser with RegEx101 tool shows that the parser expects functions to have return type. Functions without return type do not appear in the Function List. I changed Regex making return type optional. Change makes constructors without initializer to appear in the Function List but destructors are still missing. The reason is the name of the destructor which starts with tilde ‘~’ which is not the word character. Regex expects function names to be words. Changing the Regex seguence “\w+” to “~?\w+” enables function names to start with tilde. Now destructors are shown also. Constructors with initializer are still missing though. They contain additional code inside initializer between ‘:’ and ‘{’ and the Regex inside mainExpr marks “functions” found inside initalizer too. That confuses the parser and Function List is not built. Regex should skip the code inside the initializer, but I don’t know how to achieve this without regular expression replacement or modification which is not supported inside the parser.
I found that changes in overrideMap.xml are ignored, only changes in cpp.xml are being accepted.Example:
// ExampleClass.h class ExampleClass { private: int i; int j; public: ExampleClass(int x, int y=0); // ctor1 ExampleClass(); // ctor2 ~ExampleClass(); // dtor void Method1(); int Method2() { return i+j; } }; // ExampleClass.cpp #include "ExampleClass.h" // constructor with initializer (ctor1) ExampleClass::ExampleClass(int x, int y) : i(x), j(y) { allocate(); } // constructor without initializer (ctor2) ExampleClass::ExampleClass() { i = 0; j = 0; allocate(); } // destructor (dtor) ExampleClass::~ExampleClass() { deallocate(); } // function not belonging to the class void HelperFunction() { return; } // class method void ExampleClass::Method1() { return; }
Function list with modified cpp.xml:
I put modified cpp.xml on temporary test location for those who want to test it.
I tested modified cpp.xml on my sources and it works for me.