Open shilangyu opened 2 years ago
Off the top of my head: replace .
with _
? Then for your second example, we'd get:
One.One
-> One_One
OneOne
-> OneOne
Two.One
-> Two_One
_
is a valid identifier character, so it could be used in a statement name and lead to clashes
Is $
a valid identifier in C#?
Yes, I am pretty sure dart and c# shares the same character set for identifiers there goes my uneducated assumption
Nope, $
is invalid char in an identifier in C#. We might also limit valid identifier character on contracts level if it will be necessary.
Also, I think the "fix" (I still don't like the general algo - it does not generate stable names) for this would be slightly simpler. It relates to point (2):
If it collides with any other statement name (regardless of their namespace),
You should not check if it collides with any other statement, but with already used identifiers. So basically keep a hashset of already used identifiers and check with it. There will also be a case where this fails: a) NS2.Class b) NS2.NamedClass c) NS2.MyNamedClass d) NS2.NSMyNamedClass e) NS.My.Named.Class
For (e), it will try:
Class
collides with (a),NamedClass
collides with (b)MyNamedClass
collides with (d)NSMyNamedClass
collides with (e).So it also needs some other suffix mechanism (e.g. appending numbers).
What if we duplicated the C# namespace hierarchy in generated Dart contracts? Then it'd be the contract user's responsibility to import the correct namespace. Kinda ugly though, and too complex, and too big of a change.
So for your second example, we'd get:
$ tree
.
├── One
│ └── One.dart
├── One.dart
└── Two
└── One.dart
That, IMO, is the ideal option, but I think I am the only one who does think that.
You should not check if it collides with any other statement, but with already used identifiers
Is this stable though? A new statement comes along and affects others (as long as it is ordered before them). Also, I kinda don't like its stateful nature and dependence on order, it feels weird that some statement will receive a different naming just because it is ordered earlier/later. Plus generic nested classes such as Values
will never "stabilize" to a more concrete name.
I feel like the only "stable" solution is when the generated name is fully independent of other statements. Current stable solutions:
Is this stable though?
Stable in the same way that the current solution is, meaning - not stable at all.
- names are always the full namespace (ok-ish readability, does not solve collision problem, DX usability ok)
Why not?
Also, I'm all for option (1) - with Cmd+. shortcut you basically get good enough DX so that the multitude of directories is not a problem (but I would still truncate some of the "static" directories).
- names are always the full namespace (ok-ish readability, does not solve collision problem, DX usability ok)
Why not?
Same case as in before, example: One.One
and OneOne
Ah, got it - I assumed that the "dot" (or any other separator) stays.
I don't have much to add to the discussion, just wanted to let you guys know that we encountered this issue in one of the projects.
Currently, to pick a class name for a contract statement the following is done:
For instance consider two statements
One.Two.Three
andFour.Two.Three
where.
denotes a namespace accessor.Then to find the class name for
One.Two.Three
:Three
Four.Two.Three
, go one namespace up: set current name toTwoThree
Four.Two.Three
, go one namespace up: set current name toOneTwoThree
OneTwoThree
This algorithm was chosen because Dart does not have namespaces and this algorithm produces possibly shortest names without collisions... Or so I thought.
Now consider the following statements:
One.One
,OneOne
,Two.One
. If you follow the algorithm, the resulting class names will be respectivelyOneOne
,OneOne
, andTwoOne
. That's a name clash.This brings us to the question: how do we want to generate names for such cases? Or, what would be a different (better) way of picking class names?