[SAoC2022] Replace libdparse with dmd-as-a-library in D-Scanner

Lucian Danescu lucidanescu28 at yahoo.com
Sat Sep 24 19:29:14 UTC 2022


Hello everyone!

My project wants to replace the usage of `libdparse` with 
`dmd-as-a-library` in `D-Scanner`, and improvind the dmd 
interface by using it in a real life scenario.

My intention is to attempt and template all the public methods in 
`hdrgen.d`. Since header generation is done right after parsing, 
we don’t need to import files related to semantic analysis, so 
the goal here would be to get rid of all the imports that refer 
files with information relevant for semantics, and at the same 
time it would be useful to be able to use `hdrgen` with any AST 
family, not just with `ASTCodegen`.

These are some of the imports present in `hdrgen.d`:

```
import dmd.declaration;
import dmd.denum;
import dmd.dimport;
import dmd.dmodule; // like this one for example
import dmd.doc;
import dmd.dstruct;
import dmd.dsymbol;
import dmd.dtemplate;
import dmd.dversion;
import dmd.expression;
import dmd.func;
import dmd.globals;
import dmd.id;
import dmd.identifier;
import dmd.init;
```

Example of how a templated function would look like:

```
void toCBuffer(const Statement s, OutBuffer* buf, HdrGenState* 
hgs)
{
     scope v = new StatementPrettyPrintVisitor(buf, hgs);
     (cast() s).accept(v);
}
```

to:

```
void toCBuffer(AST = dmd.astcodegen.ASTCodegen)(const 
AST.Statement s, OutBuffer* buf, HdrGenState* hgs)
{
     scope v = new StatementPrettyPrintVisitor(buf, hgs);
     (cast() s).accept(v);
}

```

By templating that method it would bring great benefits to 
ASTBase, because `toCBuffer` is needed in order to print the 
content of an AST node. Example:
ASTCodegen(statement.d)
```
override final const(char)* toChars() const
     {
         HdrGenState hgs;
         OutBuffer buf;
         .toCBuffer(this, &buf, &hgs);
         buf.writeByte(0);
         return buf.extractSlice().ptr;
     }
```
This behavior can’t be implemented also in ASTBase currently, but 
it would be possible if the functions in hdrgen.d were templated.

Now regarding the example for the `toCBuffer` function, this also 
has the following downsides: Taking advantage of the default 
template parameter means that we still have to import ASTCodegen 
(and implicitly all files necessary for semantics), and this 
would also create a circular dependency:

hdrgen.d
```
import dmd.astcodegen
```

astcodegen.d
```
import dmd.hdrgen
```

A solution that avoids these problems would be not to use a 
default value for templated functions, but that implies a lost of 
find and replace work: Example

Statement.d
```
override final const(char)* toChars() const
     {
         HdrGenState hgs;
         OutBuffer buf;

        .toCBuffer!ASTCodegen(this, &buf, &hgs); // instead of old 
toCBuffer(...)
         buf.writeByte(0);
         return buf.extractSlice().ptr;
     }
```

Since this involves a good amount of work I would like to hear 
your thoughts before diving into the implementation.



More information about the Digitalmars-d mailing list