C
C#2y ago
Thinker

✅ How to design an error interface

In my current project I have an interface called ISymbol. This interface has tons of derived interfaces (INamedSymbol, ITypeSymbol, IFunctionSymbol, IVariableSymbol, among others), which all can have multiple implementations. However, I also have an interface called IErrorSymbol which just represents an error which has been produced somewhere. There are several cases in which I have to cast between these interfaces, and many times I also have to perform is checks. The IErrorSymbol is meant to act as a more or less general-purpose interface which can describe any error, but which also can be used in place of any of the other interfaces. Currently I have a general ErrorSymbol : IErrorSymbol implementation, as well as a couple specialized ones like NamedErrorSymbol : INamedSymbol, IErrorSymbol and ErrorTypeSymbol : ITypeSymbol, IErrorSymbol, although having one of these for every kind of error feels very annoying. What I would love to have is just a single (or at least very few) implementations which can serve the roll of any of the interfaces, however which don't necessarily implicitly implement those interfaces. Does that even make sense? Like, in my ideal world, new ErrorSymbol() is ITypeSymbol would be false, but (ITypeSymbol)new ErrorSymbol() would be acceptable. Is there any decent way to describe/implement this?
19 Replies
Thinker
ThinkerOP2y ago
Unfortunately I can't have public static explicit operator ITypeSymbol(ErrorSymbol e), because you can't define implicit or explicit operators to/from an interface.
Anton
Anton2y ago
just have a "referenced symbol" property making a subclass for each one is nonsense
Thinker
ThinkerOP2y ago
wdym?
Anton
Anton2y ago
hold on what do those implementations do they are both an error an a named symbol? what's that supposed to mean?
Thinker
ThinkerOP2y ago
An NamedErrorSymbol is an error for when an INamedSymbol was expected
333fred
333fred2y ago
What roslyn does is only have error types
Anton
Anton2y ago
You should have a IErrorSymbol that wraps the deduced symbol, or just use a normal named symbol while recording the errors, I guess
333fred
333fred2y ago
I'm not certain what the scenario is for something like an error IFunctionSymbol
Thinker
ThinkerOP2y ago
Hmm, right Idk I suppose I can synthesize the rest of the symbols, i.e. just use the pre-existing ones but give them made-up data?
333fred
333fred2y ago
What is the scenario you're thinking of here?
Thinker
ThinkerOP2y ago
foo(x: Int32, x: String): Something; What do you do if you ask for the symbol of x: String?
Anton
Anton2y ago
it would a normal parameter with the name x
333fred
333fred2y ago
You get a parameter symbol There's no error there
Anton
Anton2y ago
the same name error would be a diagnostic
333fred
333fred2y ago
Even if String is not defined, there's no error with x When you ask for the type of x, you get an IErrorTypeSymbol You can't be more specific because you don't know what type of symbol it was intended to be
Thinker
ThinkerOP2y ago
hmm, fair I suppose, maybe I don't need any more error symbols
333fred
333fred2y ago
That's really what I'm meaning here. Like, let's take a function call M(1, 2), where M is undefined, and someone asks for the method symbol. What could you return other than null? What we do in roslyn is you can query for the all the candidate methods, but the resolved symbol will be null
Thinker
ThinkerOP2y ago
right Also with the case above, I was mostly thinking about x being redefined
333fred
333fred2y ago
Well, the symbol itself can still be created, and isn't an error itself. It's just that in the context it's defined in, it's an error
Want results from more Discord servers?
Add your server