xamarin / binding-tools-for-swift

MIT License
157 stars 21 forks source link

Infrastructure - Naming Items needs better design #834

Open stephen-hawley opened 6 months ago

stephen-hawley commented 6 months ago

Naming of local variables, pinvokes and class names needs some attention.

Generally speaking, items are named with string constants used as a prefix and then run through a simple algorithm for making them unique. The constants tend to be spread over a number of different locations and small changes in one place often break things in others and renaming things to be more pretty is hard.

What I would like to see instead is a class named Nomenclature or Naming to centralize the functionality.

In addition, the code that is used to ensure that symbols are unique uses a very simple O(n) algorithm where a symbol is checked progressively using the pattern symbol, symbol0, symbol1... against a List<string> of symbols in use. For the most part, this is not as expensive at might sound in that the typical number of symbols in use is usually small and similarly the number of conflicts is small so that it shouldn't be more than a scant few milliseconds to general a unique symbol.

However, this could be better and we can improve the usefulness at the same time.

To do this, we can consider every naming context to be a scope which contains its own set of symbols. So consider that we should have a stack of hash sets which have the symbols in use. The again introduces and O(n) complexity, but we could instead accumulate all of the elements into a "current" each time a new scope is entered and revert back to the oldest when a scope is left.

Currently the typical use in BTfS is:

    var symName = Uniquify ("candidateSymbol", usedSymbols);
    usedSymbols.Add (symName);
    var symID = new CSIdentifier (symName);

which really should only ever be a single line:

    var symID = nomenclature.UniqueID ("candidateSymbol"); // make a unique symbol, store it in scope, return identifier

The general API should be something like this:

    public class Nomenclature {
        public void EnterScope (params string [] seed symbols); // enter a scope and add symbols
        public void ExitScope ();
        public string Unique (string seed);
        public string UniqueID (string seed);
    }