public string Rewrite(FunctionCall call) { if (call == null) { throw new ArgumentNullException(nameof(call)); } if (!string.Equals(call.Name, Name, StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException(); } return(_rewriter.Rewrite(call)); }
static string Compile(IEnumerable <Token> tokens, IFunctionCallRewriter rewriter) { using var token = tokens.GetEnumerator(); return(Function(null)); string Function(string name) { var expression = new StringBuilder(); var lastIdentier = (string)null; var args = (ImmutableArray <string> .Builder)null; void PushArg(string arg) { args ??= ImmutableArray.CreateBuilder <string>(); args.Add(arg); } while (token.TryRead(out var t)) { switch (t.Type) { case nameof(TOKEN_ID): case nameof(TOKEN_LEFT): case nameof(TOKEN_RIGHT): case nameof(TOKEN_NULLIF): { lastIdentier = t.Text; break; } case "(": { expression.Append(Function(Reset(ref lastIdentier)?.Trim())); break; } case ")": { if (name is null) // just a parenthesized expression { return("(" + expression.Append(lastIdentier).Append(t.Text)); } var arg = (expression + lastIdentier).Trim(); if (arg.Length > 0) { PushArg(arg); } return(rewriter.Rewrite(new FunctionCall(TransactSql.DequoteQuoutedIdentifier(name), args?.ToImmutable() ?? ImmutableArray <string> .Empty))); } case ",": { PushArg((expression + Reset(ref lastIdentier)).Trim()); expression.Clear(); break; } case nameof(LEX_WHITE): { if (lastIdentier is null) { expression.Append(" "); } else { lastIdentier += " "; } break; } case nameof(LEX_END_OF_LINE_COMMENT): { expression.Append("/*") .Append(t.Text.Substring(2).TrimEnd('\r')) .Append(" */"); break; } case nameof(TOKEN_CONVERT): case nameof(TOKEN_TRY_CONVERT): { // These should have been caught out during parsing so arriving // here is considered an internal implementation error. throw new Exception("Internal error due to forbidden use of native function call: " + t.Text); } default: { expression.Append(Reset(ref lastIdentier)).Append(t.Text); break; } } } return(expression.Append(lastIdentier).ToString()); } }
public static IFunctionCallRewriter Rename(this IFunctionCallRewriter rewriter, string name) => Create(call => rewriter.Rewrite(call.WithName(name)));