This makes the result of code generation independent of the order
in which classes are defined in the schema, and makes additional
topological sorting not required.
Being independent from schema order will be important for reviewing the
move to a pure python schema, as generated code will be left untouched.
* made `members` children of an `IterableDeclContext`
* removed `elements` from the children of `EnumCaseDecl`, as they are
already children of the enclosing `EnumDecl`
* removed `base` from the children of `SelfApplyExpr`, as they currently
are already descendants via `getArgument(0).getExpr()`. We should
maybe consider either removing `base` from the schema and add it as
a shortcut on QL, or finish up replacing all `SelfApplyExpr` instances
with synthesized types.
There was an issue in case multiple inheritance from classes with
children was involved, where indexes would overlap.
The generated code structure has been reshuffled a bit, with
`Impl::getImmediateChildOf<Class>` predicates giving 0-based children
for a given class, including those coming from bases, and the final
`Impl::getImmediateChild` disjuncting the above on final classes only.
This removes the need of `getMaximumChildrenIndex<Class>`, and also
removes the code scanning alerts.
Also, comments were fixed addressing the review.
Add module context to all declarations. As keeping the `std::variant`s
required slightly more work for this, and we intended to remove them
any way, this is done in this change.
For background, we put those in as we were not extracting all modules at
the time, so we were missing some DB ids that we put back in by adding
the "defining" traps not only in the trap file related to the defining
module but also to the one where the declaration was used. Since then
we fixed module extraction, so this should not be needed any more.
This introduces a `MethodRefExpr` node synthesized out of
`DotSyntaxCallExpr` under the `LookupExpr` hierarchy. This means that
much like
```free_function(1, 2)```
is a `CallExpr` with `getFunction` giving a `DeclRefExpr`,
```foo.method(1, 2)```
is now a `CallExpr` with `getFunction` giving a `MethodRefExpr`.
`ApplyExpr::getStaticTarget` has been made work with it (as well as
`ConstructorRefCallExpr` which for the moment has been left where it
is), a new `MethodApplyExpr` has been introduced deriving from it,
and control and data flow libraries have adapted.
A small but was fixed in `qlgen` where the default constructor for DB
types was not correctly subtracting derived IPA types depending on the
order of definitions in `schema.yml`.
There are still some occurrences of `DotSyntaxCallExpr`, and as already
mentioned the other `SelfApply` class (`ConstructorRefCallExpr`) was
left alone. Their treatment is left for a future PR.
This replaces numeric tag-based prefixes with the actual tag name.
While this means in general slightly larger trap files, it aids
debugging them for a human.
In the future we can make this conditional on some kind of trap debug
option, but for the moment it does not seem detrimental.
Firstly, this change reworks how inter-process races are resolved.
Moreover some responsability reorganization has led to merging
`TrapArena` and `TrapOutput` again into a `TrapDomain` class.
A `TargetFile` class is introduced, that is successfully created
only for the first process that starts processing a given trap output
file. From then on `TargetFile` simply wraps around `<<` stream
operations, dumping them to a temporary file. When `TargetFile::commit`
is called, the temporary file is moved on to the actual target trap
file.
Processes that lose the race can now just ignore the unneeded
extraction and go on, while previously all processes would carry out
all extractions overwriting each other at the end.
Some of the file system logic contained in `SwiftExtractor.cpp` has been
moved to this class, and two TODOs are solved:
* introducing a better inter process file collision avoidance strategy
* better error handling for trap output operations: if unable to write
to the trap file (or carry out other basic file operations), we just
abort.
The changes to `ExprVisitor` and `StmtVisitor` are due to wanting to
hide the raw `TrapDomain::createLabel` from them, and bring more
funcionality under the generic caching/dispatching mechanism.
Now `TypeRepr` is a final class in the AST, which is more or less just
a type with a location in code.
As the frontend does not provide a direct way to get a type from a
type representation, this information must be provided when fetching
the label of a type repr.
This meant:
* removing the type repr field from `EnumIsCaseExpr`: this is a virtual
AST node introduced in place of some kinds of `IsEpxr`. The type
repr is still available from the `ConditionalCheckedCastExpr` wrapped
by this virtual node, and we will rebuild the original `IsExpr` with
the IPA layer.
* some logic to get the type of keypath roots has been added to
`KeyPathExpr`. This was done to keep the `TypeRepr` to `Type` relation
total in the DB, but goes against the design of a dumb extractor. The
logic could be moved to QL in the future
* in the control flow library, `TypeRepr` children are now ignored. As
far as I can tell, there is no runtime evaluation going on in
`TypeRepr`s, so it does not make much sense to have control flow
through them.
Some fields of base classes pose some problems with diamond hierarchies,
and we don't use them any way as we are emitting them using directly
trap entries instead of structured C++ classes.
This introduces a `cpp_skip` pragma to skip generation of those fields
in structured generated C++ classes, and applies it to `is_unknown` and
`location`.