Skip to content

Commit 3ddeba8

Browse files
authored
Merge pull request #4400 from MDoerner/FixURCInspectionForInternationalUsers
Fix URC inspection for international users
2 parents 496dcf9 + 626e6ce commit 3ddeba8

File tree

8 files changed

+161
-153
lines changed

8 files changed

+161
-153
lines changed

Rubberduck.CodeAnalysis/Inspections/Concrete/UnreachableCaseInspection/ExpressionFilterFactory.cs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,56 @@
22
using Rubberduck.Parsing.Grammar;
33
using System;
44
using System.Collections.Generic;
5+
using System.Globalization;
56
using System.Linq;
67

78
namespace Rubberduck.Inspections.Concrete.UnreachableCaseInspection{
89

910
public static class ExpressionFilterFactory
1011
{
11-
private static Dictionary<string, (long typeMin, long typeMax)> IntegralNumberExtents = new Dictionary<string, (long typeMin, long typeMax)>()
12+
private static readonly Dictionary<string, (long typeMin, long typeMax)> IntegralNumberExtents = new Dictionary<string, (long typeMin, long typeMax)>()
1213
{
1314
[Tokens.LongLong] = (long.MinValue, long.MaxValue),
14-
[Tokens.Long] = (Int32.MinValue, Int32.MaxValue),
15-
[Tokens.Integer] = (Int16.MinValue, Int16.MaxValue),
16-
[Tokens.Int] = (Int16.MinValue, Int16.MaxValue),
15+
[Tokens.Long] = (int.MinValue, int.MaxValue),
16+
[Tokens.Integer] = (short.MinValue, short.MaxValue),
17+
[Tokens.Int] = (short.MinValue, short.MaxValue),
1718
[Tokens.Byte] = (byte.MinValue, byte.MaxValue)
1819
};
1920

2021
public static IExpressionFilter Create(string valueType)
2122
{
2223
if (IntegralNumberExtents.Keys.Contains(valueType))
2324
{
24-
var integralNumberFilter = new ExpressionFilterIntegral(valueType, long.Parse);
25+
var integralNumberFilter = new ExpressionFilterIntegral(valueType, s => long.Parse(s, CultureInfo.InvariantCulture));
2526
integralNumberFilter.SetExtents(IntegralNumberExtents[valueType].typeMin, IntegralNumberExtents[valueType].typeMax);
2627
return integralNumberFilter;
2728
}
28-
else if (valueType.Equals(Tokens.Double) || valueType.Equals(Tokens.Single))
29+
if (valueType.Equals(Tokens.Double) || valueType.Equals(Tokens.Single))
2930
{
30-
var floatingPointNumberFilter = new ExpressionFilter<double>(valueType, double.Parse);
31+
var floatingPointNumberFilter = new ExpressionFilter<double>(valueType, s => double.Parse(s, CultureInfo.InvariantCulture));
3132
if (valueType.Equals(Tokens.Single))
3233
{
3334
floatingPointNumberFilter.SetExtents(float.MinValue, float.MaxValue);
3435
}
3536
return floatingPointNumberFilter;
3637
}
37-
else if (valueType.Equals(Tokens.Currency))
38+
if (valueType.Equals(Tokens.Currency))
3839
{
3940
var fixedPointNumberFilter = new ExpressionFilter<decimal>(valueType, VBACurrency.Parse);
4041
fixedPointNumberFilter.SetExtents(VBACurrency.MinValue, VBACurrency.MaxValue);
4142
return fixedPointNumberFilter;
4243
}
43-
else if (valueType.Equals(Tokens.Boolean))
44+
if (valueType.Equals(Tokens.Boolean))
4445
{
4546
return new ExpressionFilterBoolean();
4647
}
4748

48-
else if (valueType.Equals(Tokens.Date))
49+
if (valueType.Equals(Tokens.Date))
4950
{
5051
return new ExpressionFilterDate();
5152
}
5253

53-
return new ExpressionFilter<string>(valueType, (a) => { return a; });
54+
return new ExpressionFilter<string>(valueType, a => a);
5455
}
5556
}
5657
}

Rubberduck.CodeAnalysis/Inspections/Concrete/UnreachableCaseInspection/LetCoerce.cs

Lines changed: 111 additions & 108 deletions
Large diffs are not rendered by default.

Rubberduck.CodeAnalysis/Inspections/Concrete/UnreachableCaseInspection/ParseTreeExpressionEvaluator.cs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,8 @@ private IParseTreeValue EvaluateArithmeticOp(string opSymbol, IParseTreeValue LH
283283
return _valueFactory.CreateExpression($"{LHS.Token} {opSymbol} {RHS.Token}", opProvider.OperatorDeclaredType);
284284
}
285285

286-
if (!LHS.TryLetCoerce(opProvider.OperatorEffectiveType, out IParseTreeValue effLHS)
287-
|| !RHS.TryLetCoerce(opProvider.OperatorEffectiveType, out IParseTreeValue effRHS))
286+
if (!LHS.TryLetCoerce(opProvider.OperatorEffectiveType, out var effLHS)
287+
|| !RHS.TryLetCoerce(opProvider.OperatorEffectiveType, out var effRHS))
288288
{
289289
return _valueFactory.CreateExpression($"{LHS.Token} {opSymbol} {RHS.Token}", opProvider.OperatorDeclaredType);
290290
}
@@ -299,45 +299,45 @@ private IParseTreeValue EvaluateArithmeticOp(string opSymbol, IParseTreeValue LH
299299

300300
if (opSymbol.Equals(ArithmeticOperators.MULTIPLY))
301301
{
302-
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => { return a * b; }, (double a, double b) => { return a * b; }), opProvider.OperatorDeclaredType);
302+
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => a * b, (double a, double b) => a * b), opProvider.OperatorDeclaredType);
303303
}
304-
else if (opSymbol.Equals(ArithmeticOperators.DIVIDE))
304+
if (opSymbol.Equals(ArithmeticOperators.DIVIDE))
305305
{
306-
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => { return a / b; }, (double a, double b) => { return a / b; }), opProvider.OperatorDeclaredType);
306+
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => a / b, (double a, double b) => a / b), opProvider.OperatorDeclaredType);
307307
}
308-
else if (opSymbol.Equals(ArithmeticOperators.INTEGER_DIVIDE))
308+
if (opSymbol.Equals(ArithmeticOperators.INTEGER_DIVIDE))
309309
{
310310
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, IntDivision, IntDivision), opProvider.OperatorDeclaredType);
311311
}
312-
else if (opSymbol.Equals(ArithmeticOperators.PLUS))
312+
if (opSymbol.Equals(ArithmeticOperators.PLUS))
313313
{
314314
if (opProvider.OperatorEffectiveType.Equals(Tokens.String))
315315
{
316316
return _valueFactory.CreateValueType(Concatenate(LHS, RHS), opProvider.OperatorDeclaredType);
317317
}
318318
if (opProvider.OperatorEffectiveType.Equals(Tokens.Date))
319319
{
320-
var result = _valueFactory.CreateDeclaredType(Calculate(effLHS, effRHS, null, (double a, double b) => { return a + b; }), Tokens.Double);
320+
var result = _valueFactory.CreateDeclaredType(Calculate(effLHS, effRHS, null, (double a, double b) => a + b), Tokens.Double);
321321
return _valueFactory.CreateDate(result.AsDouble());
322322
}
323-
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => { return a + b; }, (double a, double b) => { return a + b; }), opProvider.OperatorDeclaredType);
323+
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => a + b, (double a, double b) => a + b), opProvider.OperatorDeclaredType);
324324
}
325-
else if (opSymbol.Equals(ArithmeticOperators.MINUS))
325+
if (opSymbol.Equals(ArithmeticOperators.MINUS))
326326
{
327327
if (LHS.ValueType.Equals(Tokens.Date) && RHS.ValueType.Equals(Tokens.Date))
328328
{
329329
return _valueFactory.CreateDate(LHS.AsDouble() - RHS.AsDouble());
330330
}
331-
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => { return a - b; }, (double a, double b) => { return a - b; }), opProvider.OperatorDeclaredType);
331+
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => a - b, (double a, double b) => a - b), opProvider.OperatorDeclaredType);
332332
}
333-
else if (opSymbol.Equals(ArithmeticOperators.EXPONENT))
333+
if (opSymbol.Equals(ArithmeticOperators.EXPONENT))
334334
{
335335
//Math.Pow only takes doubles, so the decimal conversion option is null
336-
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, null, (double a, double b) => { return Math.Pow(a, b); }), opProvider.OperatorDeclaredType);
336+
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, null, Math.Pow), opProvider.OperatorDeclaredType);
337337
}
338-
else if (opSymbol.Equals(ArithmeticOperators.MODULO))
338+
if (opSymbol.Equals(ArithmeticOperators.MODULO))
339339
{
340-
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => { return a % b; }, (double a, double b) => { return a % b; }), opProvider.OperatorDeclaredType);
340+
return _valueFactory.CreateValueType(Calculate(effLHS, effRHS, (decimal a, decimal b) => a % b, (double a, double b) => a % b), opProvider.OperatorDeclaredType);
341341
}
342342

343343
//ArithmeticOperators.AMPERSAND
@@ -377,9 +377,9 @@ private string Calculate(IParseTreeValue LHS, IParseTreeValue RHS, Func<decimal,
377377

378378
if (!(DecimalCalc is null) && LHS.TryLetCoerce(out decimal lhsValue) && RHS.TryLetCoerce(out decimal rhsValue))
379379
{
380-
return DecimalCalc(lhsValue, rhsValue).ToString();
380+
return DecimalCalc(lhsValue, rhsValue).ToString(CultureInfo.InvariantCulture);
381381
}
382-
return DoubleCalc(LHS.AsDouble(), RHS.AsDouble()).ToString();
382+
return DoubleCalc(LHS.AsDouble(), RHS.AsDouble()).ToString(CultureInfo.InvariantCulture);
383383
}
384384

385385
private string Compare(IParseTreeValue LHS, IParseTreeValue RHS, Func<decimal, decimal, bool> DecimalCompare, Func<double, double, bool> DoubleCompare)

Rubberduck.CodeAnalysis/Inspections/Concrete/UnreachableCaseInspection/ParseTreeValue.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Rubberduck.Parsing.Grammar;
22
using Rubberduck.Parsing.PreProcessing;
33
using System;
4+
using System.Globalization;
45

56
namespace Rubberduck.Inspections.Concrete.UnreachableCaseInspection
67
{
@@ -153,7 +154,7 @@ public static class ParseTreeValueExtensions
153154
public static bool TryLetCoerce(this IParseTreeValue parseTreeValue, string destinationType, out IParseTreeValue newValue)
154155
{
155156
newValue = null;
156-
if (LetCoerce.TryCoerceToken((parseTreeValue.ValueType, parseTreeValue.Token), destinationType, out string valueText))
157+
if (LetCoerce.TryCoerceToken((parseTreeValue.ValueType, parseTreeValue.Token), destinationType, out var valueText))
157158
{
158159
newValue = ParseTreeValue.CreateValueType(new TypeTokenPair(destinationType, valueText));
159160
return true;
@@ -162,31 +163,31 @@ public static bool TryLetCoerce(this IParseTreeValue parseTreeValue, string dest
162163
}
163164

164165
public static double AsDouble(this IParseTreeValue parseTreeValue)
165-
=> double.Parse(LetCoerce.Coerce((parseTreeValue.ValueType, parseTreeValue.Token), Tokens.Double));
166+
=> double.Parse(LetCoerce.Coerce((parseTreeValue.ValueType, parseTreeValue.Token), Tokens.Double), CultureInfo.InvariantCulture);
166167

167168
public static decimal AsCurrency(this IParseTreeValue parseTreeValue)
168-
=> decimal.Parse(LetCoerce.Coerce((parseTreeValue.ValueType, parseTreeValue.Token), Tokens.Currency));
169+
=> decimal.Parse(LetCoerce.Coerce((parseTreeValue.ValueType, parseTreeValue.Token), Tokens.Currency), CultureInfo.InvariantCulture);
169170

170171
public static long AsLong(this IParseTreeValue parseTreeValue)
171-
=> long.Parse(LetCoerce.Coerce((parseTreeValue.ValueType, parseTreeValue.Token), Tokens.Long));
172+
=> long.Parse(LetCoerce.Coerce((parseTreeValue.ValueType, parseTreeValue.Token), Tokens.Long), CultureInfo.InvariantCulture);
172173

173174
public static bool AsBoolean(this IParseTreeValue parseTreeValue)
174-
=>LetCoerce.Coerce((parseTreeValue.ValueType, parseTreeValue.Token), Tokens.Boolean).Equals(Tokens.True);
175+
=> LetCoerce.Coerce((parseTreeValue.ValueType, parseTreeValue.Token), Tokens.Boolean).Equals(Tokens.True);
175176

176177
public static bool TryLetCoerce(this IParseTreeValue parseTreeValue, out long newValue)
177-
=> TryLetCoerce(parseTreeValue, long.Parse, Tokens.Long, out newValue);
178+
=> TryLetCoerce(parseTreeValue, s => long.Parse(s, CultureInfo.InvariantCulture), Tokens.Long, out newValue);
178179

179180
public static bool TryLetCoerce(this IParseTreeValue parseTreeValue, out double newValue)
180-
=> TryLetCoerce(parseTreeValue, double.Parse, Tokens.Double, out newValue);
181+
=> TryLetCoerce(parseTreeValue, s => double.Parse(s, CultureInfo.InvariantCulture), Tokens.Double, out newValue);
181182

182183
public static bool TryLetCoerce(this IParseTreeValue parseTreeValue, out decimal newValue)
183-
=> TryLetCoerce(parseTreeValue, decimal.Parse, Tokens.Currency, out newValue);
184+
=> TryLetCoerce(parseTreeValue, s => decimal.Parse(s, CultureInfo.InvariantCulture), Tokens.Currency, out newValue);
184185

185186
public static bool TryLetCoerce(this IParseTreeValue parseTreeValue, out bool value)
186187
=> TryLetCoerce(parseTreeValue, bool.Parse, Tokens.Boolean, out value);
187188

188189
public static bool TryLetCoerce(this IParseTreeValue parseTreeValue, out string value)
189-
=> TryLetCoerce(parseTreeValue, (a) => { return a; }, Tokens.String, out value);
190+
=> TryLetCoerce(parseTreeValue, a => a, Tokens.String, out value);
190191

191192
private static bool TryLetCoerce(this IParseTreeValue parseTreeValue, out ComparableDateValue value)
192193
=> TryLetCoerceToDate(parseTreeValue, out value);

Rubberduck.CodeAnalysis/Inspections/Concrete/UnreachableCaseInspection/TypeTokenPair.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ namespace Rubberduck.Inspections.Concrete.UnreachableCaseInspection
88
{
99
public struct TypeTokenPair
1010
{
11-
public string ValueType { private set; get; }
12-
public string Token { private set; get; }
11+
public string ValueType { get; }
12+
public string Token { get; }
1313

1414
public TypeTokenPair(string valueType, string token)
1515
{

RubberduckTests/Inspections/UnreachableCase/ExpressionFilterUnitTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ private IParseTreeValue CreateInspValueFrom(string valAndType)
491491
{
492492
var args = RetrieveDelimitedElements(valAndType, VALUE_TYPE_DELIMITER);
493493
var value = args[0];
494-
string declaredType = args[1].Equals(string.Empty) ? null : args[1];
494+
var declaredType = args[1].Equals(string.Empty) ? null : args[1];
495495
if (declaredType is null)
496496
{
497497
return ValueFactory.Create(value);
@@ -533,12 +533,12 @@ private IEnumerable<IRangeClauseExpression> RangeClauseTokensToExpressions(IEnum
533533
var operandDelimiters = clause.Where(ch => ch.Equals('_'));
534534
if (operandDelimiters.Count() == 2)
535535
{
536-
(IParseTreeValue lhs, IParseTreeValue rhs, string symbol) = GetBinaryOpValues(clause);
536+
var (lhs, rhs, symbol) = GetBinaryOpValues(clause);
537537
expressionClause = CreateRangeClauseExpression((lhs, rhs, symbol));
538538
}
539539
else if (operandDelimiters.Count() <= 1)
540540
{
541-
(IParseTreeValue operand, string symbol) = GetUnaryOpValues(clause);
541+
var (operand, symbol) = GetUnaryOpValues(clause);
542542
if (symbol.Equals(LogicalOperators.NOT))
543543
{
544544
expressionClause = new UnaryExpression(operand, symbol);

RubberduckTests/Inspections/UnreachableCase/ParseTreeExpressionEvaluatorUnitTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Rubberduck.Inspections.Concrete.UnreachableCaseInspection;
33
using Rubberduck.Parsing.Grammar;
44
using System;
5+
using System.Globalization;
56

67
namespace RubberduckTests.Inspections.UnreachableCase
78
{
@@ -942,8 +943,8 @@ private IParseTreeValue CreateInspValueFrom(string valAndType, string conformTo
942943
{
943944
var compareLength = expected.Length > 5 ? 5 : expected.Length;
944945
var accuracy = Math.Pow(10, -1.0 * compareLength);
945-
var lhs = double.Parse(result.Token.Substring(0, compareLength));
946-
var rhs = double.Parse(expected.Substring(0, compareLength));
946+
var lhs = double.Parse(result.Token.Substring(0, compareLength), CultureInfo.InvariantCulture);
947+
var rhs = double.Parse(expected.Substring(0, compareLength), CultureInfo.InvariantCulture);
947948
Assert.IsTrue(Math.Abs(lhs - rhs) <= accuracy, $"Actual={result.Token} Expected={expected}");
948949
return (result,result);
949950
}

RubberduckTests/Mocks/MockVbeBuilder.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,9 @@ private Mock<IVBE> CreateVbeMock()
216216

217217
var commandBars = DummyCommandBars();
218218
vbe.SetupGet(m => m.CommandBars).Returns(() => commandBars);
219-
219+
220+
vbe.Setup(m => m.IsInDesignMode).Returns(true);
221+
220222
return vbe;
221223
}
222224

0 commit comments

Comments
 (0)