1

Closed

ParsingContext.Culture should be used when retrieving error message

description

I was willing to translate errors message when I noticed a major bug (at least for us) !

Changing Resources.Culture in constructor of ParsingContext is way too early (therefore almost completely useless) since several grammar using different culture can be instantiated before being actually used for parsing (latest instance always win with current implementation).

REM: This has nothing to do with multi-threading mentioned in the code comments, as it is also fully affect single threaded application.

Resources.Culture should be changed just before accessing the resource (for eg: in OnValidateToken) or even better to also evolve toward solving multi-threading issues by refining custom methods (to preserve strong typing) such as:
/// <summary>
/// Convert a lambda expression as property name
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression"></param>
/// <returns></returns>
private static string ConvertAsPropertyName<T>(Expression<Func<T>> expression)
{
   if (expression == null)
   {
      throw new ArgumentNullException("expression");
   }

   var body = expression.Body as MemberExpression;
   if (body == null)
   {
      throw new ArgumentException("Lambda expression must return a property");
   }

   return body.Member.Name;
}

private string LookupResource(Expression<Func<string>> resourceNameExpr)
{
   string resourceName = ConvertAsPropertyName(resourceNameExpr);
   return Resources.ResourceManager.GetString(resourceName, this.Culture);
}

public Token CreateErrorToken(Expression<Func<string>> resourceNameExpr, params object[] args) {
   string propertyName = LookupResource(resourceNameExpr);

   string message = "";

  if (args != null && args.Length > 0)
    message = string.Format(message, args);
  return Source.CreateToken(Language.Grammar.SyntaxError, message);
}
Call later becomes for example:
context.CurrentToken = context.CreateErrorToken(() => Resources.ErrNoLetterAfterNum);

For now I'm not implementing the suggested fix (too much work that is outside my project) and I will try to quickly dirty fix it otherwise to move on :/
Closed Feb 26, 2013 at 4:15 AM by rivantsov
no easy fix for now - for supporting multiple languages at the same time (in one app). Will look at this in new version

comments

mulder999 wrote Apr 5, 2012 at 12:29 PM

CreateErrorToken should obviously be:
public Token CreateErrorToken(Expression<Func<string>> resourceNameExpr, params object[] args) {
  string message = LookupResource(resourceNameExpr);
  if (args != null && args.Length > 0)
    message = string.Format(message, args);
  return Source.CreateToken(Language.Grammar.SyntaxError, message);
}