Rework PLCgen name generator
The core data structure in the PLCgen name generator is Map<String, Integer>
, where the key is a clean name (a valid identifier in the PLC code) and the value is next free number suffix to append to the key to create a unique name. By also incrementing the value on each use, unique names with the same base-name are generated.
This worked so far, by having full control over what base-names are added in global and local scopes. Recently new needs came up (injection of PLC tags from I/O that cannot be modified, more extensive use of local scopes). These needs go beyond the full control limits mentioned before.
Therefore, the name generator should be improved and handle multiple scopes with arbitrary names correctly.
Uniqueness goals:
- Assuming a 2 level scope structure: The central global scope, and zero or more local scopes.
- All names in all scopes are valid PLC names.
- All names in a single scope are unique wrt that scope.
- Two different local scopes can have name overlap.
- A local scope and the central scope cannot have name overlap.
Note that the last goal implies that the central scope must never add a new name that is already in use by any local scope.
Other changes:
- The set used names in a scope are explicitly stored, and act as the authoritative source to decide whether a name is unique (in that scope).
- The
Map<String, integer>
data structure is mostly only a cache to avoid trying to create already added names. - Names that should be avoided (eg Structured Text keywords) are directly stored in the set used names.
- The
- In addition to a base-name, a set of prefixes can be supplied. The same generated name becomes available as suffix for all those prefixes.
For example, with prefixes
{a, b}
and generated nameq
, the namesaq
andbq
are guaranteed unique in the scope.
Addresses #679