Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2019-10

fcl-passrc method/function invocations

7 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Ryan Joseph

One of my tasks for the language server is determining “references” to a symbol, which means for functions I need to know all the times they were called.

Given the syntax tree the parser creates how do I know when a function was called? I see there is a TPasImplSimple that seems related but I’m not sure exactly. It’s probably possible that it’s not always possible to know because there are unresolved types so: a := clss.DoThis; maybe be a function call or accessing a proeprty/member variable.

Regards,
Ryan Joseph

Michael Van Canneyt
to Ryan Joseph
Ryan Joseph wrote 7 lines
One of my tasks for the language server is determining “references” to a symbol, which means for functions I need to know all the times they were called. Given the syntax tree the parser creates how do I know when a function was called? I see there is a TPasImplSimple that seems related but I’m not sure exactly. It’s probably possible that it’s not always possible to know because there are unresolved types so: a := clss.DoThis; maybe be a function call or accessing a proeprty/member variable.

for this you need the resolver. The resolver resolves symbols.

That is a separate step in the process. You would need to traverse the syntax tree, and let the resolver resolve every symbol encountered in expressions or function call statements. (or just the symbol names you are interested in).

The resolver is implemented in pasresolver.pp and pasresolveeval.pas (but I think you'll only need the former)

You can attach any amount of data to an element of the AST. For instance this could be the number of times the element is accessed.

Separate from the resolver, there is also the pasuseanalyser, which analyses if elements are used.

I don't think it keeps a count, though.

Michael.

Mattias Gaertner
to Michael Van Canneyt
[...] The resolver is implemented in pasresolver.pp and pasresolveeval.pas (but I think you'll only need the former)

The latter is used by the former.
Note that the resolver can only parse whole modules, not mere expressions.
TPasParser supports more FPC elements than the resolver. For example objc and operator overloading are not yet supported.

Show quoted text 6 lines
You can attach any amount of data to an element of the AST. For instance this could be the number of times the element is accessed. Separate from the resolver, there is also the pasuseanalyser, which analyses if elements are used.

Yes. Directly or indirectly. Module or whole program.

I don't think it keeps a count, though.

It does not.

Mattias

Ryan Joseph
to Mattias Gaertner

Another related question about functions.

In unit files there is a InterfaceSection/ImplementationSection in TPasModule and I can use those to get a list of functions (because they descend from TPasSection). In a program file there only seems to be a InitializationSection but this doesn’t contain the same list of functions.

So, how do I find the functions in a program module?

Regards,
Ryan Joseph

Mattias Gaertner
to Ryan Joseph
Show quoted text 9 lines
Another related question about functions. In unit files there is a InterfaceSection/ImplementationSection in TPasModule and I can use those to get a list of functions (because they descend from TPasSection). In a program file there only seems to be a InitializationSection but this doesn’t contain the same list of functions. So, how do I find the functions in a program module?

When parsing a program the module is a TPasProgram, which has a ProgramSection.

Mattias

Ryan Joseph
to Mattias Gaertner
On Oct 15, 2019, at 5:02 PM, Mattias Gaertner via fpc-pascal wrote: When parsing a program the module is a TPasProgram, which has a ProgramSection.

Of course, thanks.

A couple other questions if you don’t mind:

1) Are there any examples of the resolver? I’m looking through the unit and it looks pretty dense.

2) Can the parser take strings as input or just files? I ask because I have a string without a file and currently I’m saving it into a temporary file and giving that to the parser.

3) Can the parser handle code fragments? If not is that something I can possible extend it to accommodate?

Regards,
Ryan Joseph

Michael Van Canneyt
to Ryan Joseph
Ryan Joseph wrote 12 lines
> On Oct 15, 2019, at 5:02 PM, Mattias Gaertner via fpc-pascal wrote: > > When parsing a program the module is a TPasProgram, which has a > ProgramSection. Of course, thanks. A couple other questions if you don’t mind: 1) Are there any examples of the resolver? I’m looking through the unit and it looks pretty dense.

Only pas2js.
But there are a lot of test cases, though. Probably they are more suitable to understand the structure.

2) Can the parser take strings as input or just files? I ask because I have a string without a file and currently I’m saving it into a temporary file and giving that to the parser.

The parser can take streams as input. You can create a TStringStream.

But then you must create the parser manually, and not use ParseSource.

The testsuite contains many examples of how to do that. see the tcpars* units.

3) Can the parser handle code fragments? If not is that something I can possible extend it to accommodate?

That's going to be difficult. The parser expects there to be a module. It's probably easier to encapsulate the code fragment in a minimal module.

Again, see the testsuite for how to do this.

Michael.