ExpressionEvaluationResult EvalParse( CommandEvaluationContext context, string expr, int outputX, ParseResult parseResult ) { ExpressionEvaluationResult r = null; var errorText = ""; string[] t; int idx; string serr; switch (parseResult.ParseResultType) { /* * case ParseResultType.Valid: * var syntaxParsingResult = parseResult.SyntaxParsingResults.First(); * try * { * var outputData = InvokeCommand(CommandEvaluationContext, syntaxParsingResult.CommandSyntax.CommandSpecification, syntaxParsingResult.MatchingParameters); * * r = new ExpressionEvaluationResult(null, ParseResultType.Valid, outputData, (int)ReturnCode.OK, null); * } catch (Exception commandInvokeError) * { * var commandError = commandInvokeError.InnerException ?? commandInvokeError; * Errorln(commandError.Message); * return new ExpressionEvaluationResult(null, parseResult.ParseResultType, null, (int)ReturnCode.Error, commandError); * } * break; */ case ParseResultType.Empty: r = new ExpressionEvaluationResult(null, parseResult.ParseResultType, null, (int)ReturnCode.OK, null); break; case ParseResultType.NotValid: /* command syntax not valid */ var perComErrs = new Dictionary <string, List <CommandSyntaxParsingResult> >(); foreach (var prs in parseResult.SyntaxParsingResults) { if (prs.CommandSyntax != null) { if (perComErrs.TryGetValue(prs.CommandSyntax?.CommandSpecification?.Name, out var lst)) { lst.Add(prs); } else { perComErrs.Add(prs.CommandSyntax.CommandSpecification.Name, new List <CommandSyntaxParsingResult> { prs }); } } } var errs = new List <string>(); var minErrPosition = int.MaxValue; var errPositions = new List <int>(); foreach (var kvp in perComErrs) { var comSyntax = kvp.Value.First().CommandSyntax; foreach (var prs in kvp.Value) { foreach (var perr in prs.ParseErrors) { minErrPosition = Math.Min(minErrPosition, perr.Position); errPositions.Add(perr.Position); if (!errs.Contains(perr.Description)) { errs.Add(perr.Description); } } errorText += Br + Red + string.Join(Br + Red, errs); } errorText += $"{Br}{Red}for syntax: {comSyntax}{Br}"; } errPositions.Sort(); errPositions = errPositions.Distinct().ToList(); t = new string[expr.Length + 2]; for (int i = 0; i < t.Length; i++) { t[i] = " "; } foreach (var errPos in errPositions) { t[GetIndex(context, errPos, expr)] = ErrorPositionMarker; } serr = string.Join("", t); Error(" ".PadLeft(outputX + 1) + serr); Error(errorText); r = new ExpressionEvaluationResult(errorText, parseResult.ParseResultType, null, (int)ReturnCode.NotDefined, null); break; case ParseResultType.Ambiguous: errorText += $"{Red}ambiguous syntaxes:{Br}"; foreach (var prs in parseResult.SyntaxParsingResults) { errorText += $"{Red}{prs.CommandSyntax}{Br}"; } Error(errorText); r = new ExpressionEvaluationResult(errorText, parseResult.ParseResultType, null, (int)ReturnCode.NotDefined, null); break; case ParseResultType.NotIdentified: t = new string[expr.Length + 2]; for (int j = 0; j < t.Length; j++) { t[j] = " "; } var err = parseResult.SyntaxParsingResults.First().ParseErrors.First(); idx = err.Position; t[idx] = ErrorPositionMarker; errorText += Red + err.Description; serr = string.Join("", t); Errorln(" ".PadLeft(outputX) + serr); Errorln(errorText); r = new ExpressionEvaluationResult(errorText, parseResult.ParseResultType, null, (int)ReturnCode.NotDefined, null); break; case ParseResultType.SyntaxError: t = new string[expr.Length + 2]; for (int j = 0; j < t.Length; j++) { t[j] = " "; } var err2 = parseResult.SyntaxParsingResults.First().ParseErrors.First(); idx = err2.Index; t[idx] = ErrorPositionMarker; errorText += Red + err2.Description; serr = string.Join("", t); Errorln(" ".PadLeft(outputX) + serr); Errorln(errorText); r = new ExpressionEvaluationResult(errorText, parseResult.ParseResultType, null, (int)ReturnCode.NotDefined, null); break; } return(r); }
int RegisterCommandsClass(CommandEvaluationContext context, Type type, bool registerAsModule) { if (type.GetInterface(typeof(ICommandsDeclaringType).FullName) == null) { throw new Exception($"the type '{type.FullName}' must implements interface '{typeof(ICommandsDeclaringType).FullName}' to be registered as a command class"); } var comsCount = 0; object instance = Activator.CreateInstance(type, new object[] { }); var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); if (registerAsModule && _modules.ContainsKey(type.FullName)) { Errorln($"a module with same name than commands type '{type.FullName}' is already registered"); return(0); } foreach (var method in methods) { var cmd = method.GetCustomAttribute <CommandAttribute>(); if (cmd != null) { if (!method.ReturnType.HasInterface(typeof(ICommandResult))) { Errorln($"class={type.FullName} method={method.Name} wrong return type. should be of type '{typeof(ICommandResult).FullName}', but is of type: {method.ReturnType.FullName}"); } else { var paramspecs = new List <CommandParameterSpecification>(); bool syntaxError = false; var pindex = 0; foreach (var parameter in method.GetParameters()) { if (pindex == 0) { // manadatory: param 0 is CommandEvaluationContext if (parameter.ParameterType != typeof(CommandEvaluationContext)) { Errorln($"class={type.FullName} method={method.Name} parameter 0 ('{parameter.Name}') should be of type '{typeof(CommandEvaluationContext).FullName}', but is of type: {parameter.ParameterType.FullName}"); syntaxError = true; break; } } else { CommandParameterSpecification pspec = null; var paramAttr = parameter.GetCustomAttribute <ParameterAttribute>(); object defval = null; if (!parameter.HasDefaultValue && parameter.ParameterType.IsValueType) { defval = Activator.CreateInstance(parameter.ParameterType); } if (paramAttr != null) { // TODO: validate command specification (eg. indexs validity) pspec = new CommandParameterSpecification( parameter.Name, paramAttr.Description, paramAttr.IsOptional, paramAttr.Index, null, true, parameter.HasDefaultValue, (parameter.HasDefaultValue) ? parameter.DefaultValue : defval, parameter); } var optAttr = parameter.GetCustomAttribute <OptionAttribute>(); if (optAttr != null) { var reqParamAttr = parameter.GetCustomAttribute <OptionRequireParameterAttribute>(); try { pspec = new CommandParameterSpecification( parameter.Name, optAttr.Description, optAttr.IsOptional, -1, optAttr.OptionName ?? parameter.Name, optAttr.HasValue, parameter.HasDefaultValue, (parameter.HasDefaultValue) ? parameter.DefaultValue : defval, parameter, reqParamAttr?.RequiredParameterName); } catch (Exception ex) { Errorln(ex.Message); } } if (pspec == null) { syntaxError = true; Errorln($"invalid parameter: class={type.FullName} method={method.Name} name={parameter.Name}"); } else { paramspecs.Add(pspec); } } pindex++; } if (!syntaxError) { var cmdNameAttr = method.GetCustomAttribute <CommandNameAttribute>(); var cmdName = (cmdNameAttr != null && cmdNameAttr.Name != null) ? cmdNameAttr.Name : (cmd.Name ?? method.Name.ToLower()); var cmdspec = new CommandSpecification( cmdName, cmd.Description, cmd.LongDescription, cmd.Documentation, method, instance, paramspecs); bool registered = true; if (_commands.TryGetValue(cmdspec.Name, out var cmdlst)) { if (cmdlst.Select(x => x.MethodInfo.DeclaringType == type).Any()) { Errorln($"command already registered: '{cmdspec.Name}' in type '{cmdspec.DeclaringTypeFullName}'"); registered = false; } else { cmdlst.Add(cmdspec); } } else { _commands.Add(cmdspec.Name, new List <CommandSpecification> { cmdspec }); } if (registered) { _syntaxAnalyzer.Add(cmdspec); comsCount++; } } } } } if (registerAsModule) { if (comsCount == 0) { Errorln($"no commands found in type '{type.FullName}'"); } else { var descAttr = type.GetCustomAttribute <CommandsAttribute>(); var description = descAttr != null ? descAttr.Description : ""; _modules.Add(type.FullName, new CommandsModule(CommandsModule.DeclaringTypeShortName(type), description, type.Assembly, 1, comsCount, type)); } } return(comsCount); }
public void RegisterCommandsClass <T>(CommandEvaluationContext context) => RegisterCommandsClass(context, typeof(T), true);
public int RegisterCommandsClass(CommandEvaluationContext context, Type type) => RegisterCommandsClass(context, type, true);
void InitializeCommandProcessor(string[] args, bool printInfo = true, CommandEvaluationContext commandEvaluationContext = null) { SetArgs(args); cons.ForegroundColor = DefaultForeground; cons.BackgroundColor = DefaultBackground; commandEvaluationContext = commandEvaluationContext ?? new CommandEvaluationContext( this, Out, cons.In, Err, null ); CommandEvaluationContext = commandEvaluationContext; if (printInfo) { PrintInfo(CommandEvaluationContext); } // assume the application folder ($env.APPDATA/OrbitalShell) exists and is initialized var lbr = false; // creates user app data folders if (!Directory.Exists(AppDataFolderPath)) { LogAppendAllLinesErrorIsEnabled = false; Info(ColorSettings.Log + $"creating user shell folder: '{AppDataFolderPath}' ... ", false); try { Directory.CreateDirectory(AppDataFolderPath); Success(); } catch (Exception createAppDataFolderPathException) { Fail(createAppDataFolderPathException); } lbr = true; } // initialize log file if (!File.Exists(LogFilePath)) { Info(ColorSettings.Log + $"creating log file: '{LogFilePath}' ... ", false); try { var logError = Log($"file created on {System.DateTime.Now}"); if (logError == null) { Success(); } else { throw logError; } } catch (Exception createLogFileException) { LogAppendAllLinesErrorIsEnabled = false; Fail(createLogFileException); } lbr = true; } // initialize user profile if (!File.Exists(UserProfileFilePath)) { Info(ColorSettings.Log + $"creating user profile file: '{UserProfileFilePath}' ... ", false); try { var defaultProfileFilePath = Path.Combine(DefaultsFolderPath, UserProfileFileName); File.Copy(defaultProfileFilePath, UserProfileFilePath); Success(); } catch (Exception createUserProfileFileException) { Fail(createUserProfileFileException); } lbr = true; } // create/restore commands history CmdsHistory = new CommandsHistory(); var createNewHistoryFile = !File.Exists(HistoryFilePath); if (createNewHistoryFile) { Info(ColorSettings.Log + $"creating user commands history file: '{HistoryFilePath}' ... ", false); } try { if (createNewHistoryFile) #pragma warning disable CS0642 // Possibilité d'instruction vide erronée { using (var fs = File.Create(HistoryFilePath)); } #pragma warning restore CS0642 // Possibilité d'instruction vide erronée CmdsHistory.Init(AppDataFolderPath, HistoryFileName); if (createNewHistoryFile) { Success(); } } catch (Exception createUserProfileFileException) { Fail(createUserProfileFileException); } lbr |= createNewHistoryFile; // create/restore user aliases CommandsAlias = new CommandsAlias(); var createNewCommandsAliasFile = !File.Exists(CommandsAliasFilePath); if (createNewCommandsAliasFile) { Info(ColorSettings.Log + $"creating user commands aliases file: '{CommandsAliasFilePath}' ... ", false); } try { if (createNewCommandsAliasFile) { var defaultAliasFilePath = Path.Combine(DefaultsFolderPath, CommandsAliasFileName); File.Copy(defaultAliasFilePath, CommandsAliasFilePath); } if (createNewCommandsAliasFile) { Success(); } } catch (Exception createUserProfileFileException) { Fail(createUserProfileFileException); } lbr |= createNewHistoryFile; // end inits if (lbr) { Out.Echoln(); } // load kernel commands RegisterCommandsAssembly(CommandEvaluationContext, Assembly.GetExecutingAssembly()); #if enable_test_commands RegisterCommandsClass <TestCommands>(); #endif }