www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.internals - Redundant calls to `expressionSemantic`

I was working on https://github.com/dlang/dmd/pull/8319 when I 
encountered the following problem.

I want to add the `deprecated` attribute to enum members.  
However, in order for the deprecation message to appear for the 
location of where the enum is used and not where it is declared, 
I need to add the `checkDeprecated` message to the 
`expressionSemantic(VarExp)`, actually the `visit(VarExp)` 
implementation.

Unfortunately that results in the message being printed 3 times 
for each usage of the enum member because `visit(VarExp)` is 
being called redundantly.  The `DSymbol` class has a `PASS 
semanticrun` field to indicate whether or not semantic has 
already been run.  The `Expression` class does not.  I seem some 
classes checking `Expression.type` to determine if semantic has 
been run or not, but I don't know if that's uniformly valid.

If I add a check to see if semantic has already been run, then 
all hell breaks loose and a huge cascade of failures ensues, 
which reveals a larger problem:  Instead of using `Expression`'s 
constructor to initialize the object and then rely on 
`expressionSemantic` and the object's method calls to process the 
constructed object's data, users are manipulating the object's 
fields directly, leaving the object, at any given point in time, 
in a potentially invalid or incomplete state.  There's no 
encapsulation.

How can I fix this?

Thanks,
Mike
Jun 08 2018