@@ -14,7 +14,12 @@ public interface IParseTreeValueVisitor : IParseTreeVisitor<IParseTreeVisitorRes
14
14
event EventHandler < ValueResultEventArgs > OnValueResultCreated ;
15
15
}
16
16
17
- public class ParseTreeValueVisitor : IParseTreeValueVisitor
17
+ public interface ITestParseTreeVisitor
18
+ {
19
+ void InjectValuedDeclarationEvaluator ( Func < Declaration , ( bool , string , string ) > func ) ;
20
+ }
21
+
22
+ public class ParseTreeValueVisitor : IParseTreeValueVisitor , ITestParseTreeVisitor
18
23
{
19
24
private class EnumMember
20
25
{
@@ -41,8 +46,6 @@ public ParseTreeValueVisitor(IParseTreeValueFactory valueFactory, List<VBAParser
41
46
_contextValues = new ParseTreeVisitorResults ( ) ;
42
47
OnValueResultCreated += _contextValues . OnNewValueResult ;
43
48
_enumStmtContexts = allEnums ;
44
- _enumMembers = new List < EnumMember > ( ) ;
45
- LoadEnumMemberValues ( ) ;
46
49
}
47
50
48
51
private Func < ParserRuleContext , ( bool success , IdentifierReference idRef ) > IdRefRetriever { set ; get ; } = null ;
@@ -272,9 +275,41 @@ private bool TryGetLExprValue(VBAParser.LExprContext lExprContext, out string ex
272
275
return true ;
273
276
}
274
277
278
+ if ( lExprContext . TryGetChildContext ( out VBAParser . IndexExprContext idxExpr )
279
+ && ParseTreeValue . TryGetNonPrintingControlCharCompareToken ( idxExpr . GetText ( ) , out string comparableToken ) )
280
+ {
281
+ declaredTypeName = Tokens . String ;
282
+ expressionValue = comparableToken ;
283
+ return true ;
284
+ }
285
+
275
286
return false ;
276
287
}
277
288
289
+ private Func < Declaration , ( bool , string , string ) > _valueDeclarationEvaluator ;
290
+ private Func < Declaration , ( bool , string , string ) > ValuedDeclarationEvaluator
291
+ {
292
+ set
293
+ {
294
+ _valueDeclarationEvaluator = value ;
295
+ }
296
+ get
297
+ {
298
+ return _valueDeclarationEvaluator ?? GetValuedDeclaration ;
299
+ }
300
+ }
301
+
302
+
303
+ private ( bool IsType , string ExpressionValue , string TypeName ) GetValuedDeclaration ( Declaration declaration )
304
+ {
305
+ if ( declaration is ValuedDeclaration valuedDeclaration )
306
+ {
307
+ var typeName = GetBaseTypeForDeclaration ( declaration ) ;
308
+ return ( true , valuedDeclaration . Expression , typeName ) ;
309
+ }
310
+ return ( false , null , null ) ;
311
+ }
312
+
278
313
private void GetContextValue ( ParserRuleContext context , out string declaredTypeName , out string expressionValue )
279
314
{
280
315
expressionValue = context . GetText ( ) ;
@@ -286,6 +321,25 @@ private void GetContextValue(ParserRuleContext context, out string declaredTypeN
286
321
expressionValue = rangeClauseIdentifierReference . IdentifierName ;
287
322
declaredTypeName = GetBaseTypeForDeclaration ( declaration ) ;
288
323
324
+ ( bool IsValuedDeclaration , string ExpressionValue , string TypeName ) = ValuedDeclarationEvaluator ( declaration ) ;
325
+
326
+ if ( IsValuedDeclaration )
327
+ {
328
+ expressionValue = ExpressionValue ;
329
+ declaredTypeName = TypeName ;
330
+
331
+ if ( ParseTreeValue . TryGetNonPrintingControlCharCompareToken ( expressionValue , out string resolvedValue ) )
332
+ {
333
+ expressionValue = resolvedValue ;
334
+ declaredTypeName = Tokens . String ;
335
+ return ;
336
+ }
337
+ else if ( long . TryParse ( expressionValue , out _ ) )
338
+ {
339
+ return ;
340
+ }
341
+ }
342
+
289
343
if ( declaration . DeclarationType . HasFlag ( DeclarationType . Constant ) )
290
344
{
291
345
expressionValue = GetConstantContextValueToken ( declaration . Context ) ;
@@ -296,12 +350,12 @@ private void GetContextValue(ParserRuleContext context, out string declaredTypeN
296
350
expressionValue = GetConstantContextValueToken ( declaration . Context ) ;
297
351
if ( expressionValue . Equals ( string . Empty ) )
298
352
{
299
- var enumValues = _enumMembers . Where ( dt => dt . ConstantContext == declaration . Context ) ;
300
- if ( enumValues . Any ( ) )
353
+ if ( _enumMembers is null )
301
354
{
302
- var enumValue = enumValues . First ( ) ;
303
- expressionValue = enumValue . Value . ToString ( ) ;
355
+ LoadEnumMemberValues ( ) ;
304
356
}
357
+ var enumValue = _enumMembers . SingleOrDefault ( dt => dt . ConstantContext == declaration . Context ) ;
358
+ expressionValue = enumValue ? . Value . ToString ( ) ?? string . Empty ;
305
359
}
306
360
}
307
361
}
@@ -321,6 +375,11 @@ private bool TryGetIdentifierReferenceForContext(ParserRuleContext context, out
321
375
322
376
private string GetConstantContextValueToken ( ParserRuleContext context )
323
377
{
378
+ if ( context is null )
379
+ {
380
+ return string . Empty ;
381
+ }
382
+
324
383
var declarationContextChildren = context . children . ToList ( ) ;
325
384
var equalsSymbolIndex = declarationContextChildren . FindIndex ( ch => ch . Equals ( context . GetToken ( VBAParser . EQ , 0 ) ) ) ;
326
385
@@ -378,8 +437,12 @@ private static bool IsBinaryOpEvaluationContext<T>(T context)
378
437
return false ;
379
438
}
380
439
440
+ public void InjectValuedDeclarationEvaluator ( Func < Declaration , ( bool , string , string ) > func )
441
+ => ValuedDeclarationEvaluator = func ;
442
+
381
443
private void LoadEnumMemberValues ( )
382
444
{
445
+ _enumMembers = new List < EnumMember > ( ) ;
383
446
foreach ( var enumStmt in _enumStmtContexts )
384
447
{
385
448
long enumAssignedValue = - 1 ;
@@ -390,6 +453,8 @@ private void LoadEnumMemberValues()
390
453
var enumMember = new EnumMember ( enumConstContext , enumAssignedValue ) ;
391
454
if ( enumMember . HasAssignment )
392
455
{
456
+ Visit ( enumMember . ConstantContext ) ;
457
+
393
458
var valueText = GetConstantContextValueToken ( enumMember . ConstantContext ) ;
394
459
if ( ! valueText . Equals ( string . Empty ) )
395
460
{
0 commit comments