public static object ExecuteDynamicObjectMethod(
     IScriptCallContext context,
     IDynamicStepBroObject instance,
     string name,
     object[] arguments)
 {
     try
     {
         if (context != null && context.LoggingEnabled)
         {
             context.Log($"Calling dynamic method \"{name}\".");
         }
         return(instance.TryInvokeMethod(name, arguments));
     }
     catch (DynamicMethodNotFoundException)
     {
         if (context != null)
         {
             context.ReportError(
                 $"Method named '{name}' was not found on the object of type '{instance.GetType().Name}'.",
                 new DynamicMethodNotFoundError());
         }
         throw;
     }
     catch (Exception ex)
     {
         if (context != null)
         {
             context.ReportError(
                 $"Exception executing method '{name}' on the object of type '{instance.GetType().Name}'.",
                 exception: ex);
         }
         throw;
     }
 }
        public static IProcedureReference <T> GetPartnerReference <T>(
            IScriptCallContext context, IFileElement element, string partnerName)
        {
            Type t = typeof(T);
            var  e = element;

            while (e != null)
            {
                var partner = e.ListPartners().FirstOrDefault(p => p.Name.Equals(partnerName, StringComparison.InvariantCulture));
                if (partner != null)
                {
                    System.Diagnostics.Debug.WriteLine("Expected type: " + typeof(T).FullName);
                    System.Diagnostics.Debug.WriteLine("Found type:    " + partner.ProcedureReference.ProcedureReference.GetType().GetGenericArguments()[0].FullName);
                    if (partner.ProcedureReference.ProcedureReference is IProcedureReference <T> )
                    {
                        return(partner.ProcedureReference.ProcedureReference as IProcedureReference <T>);
                    }
                    else
                    {
                        context.ReportError("The partner procedure is not the expected type.");
                        return(null);
                    }
                }
                e = e.BaseElement;
            }
            context.ReportError($"The element \"{element.FullName}\" has no partner named \"{partnerName}\".");
            return(null);
        }
        public static IProcedureReference GetProcedure(IScriptCallContext context, int fileID, int procedureID)
        {
            IProcedureReference procedure = null;

            if (fileID < 0)
            {
                procedure = ((ScriptFile)context.Self.ParentFile).GetProcedure(procedureID);
                if (procedure == null)
                {
                    if (context != null)
                    {
                        context.ReportError(String.Format("INTERNAL ERROR: Could not find procedure with id = {0}.", procedureID));
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }
            else
            {
                ScriptFile file = context.LoadedFiles.ListFiles <ScriptFile>().FirstOrDefault(f => f.UniqueID == fileID);
                if (file == null)
                {
                    if (context != null)
                    {
                        context.ReportError(String.Format("INTERNAL ERROR: Could not find script file with id = {0}.", fileID));
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    procedure = file.GetProcedure(procedureID);
                    if (procedure == null)
                    {
                        if (context != null)
                        {
                            context.ReportError(String.Format("INTERNAL ERROR: Could not find procedure with id = {0}.", procedureID));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                }
            }
            return(procedure);
        }
 public static IAsyncResult <object> ExecuteDynamicAsyncObjectMethod(
     IScriptCallContext context,
     IDynamicAsyncStepBroObject instance,
     string name,
     object[] arguments)
 {
     try
     {
         var result = instance.TryInvokeMethod(name, arguments);
         if (result != null)
         {
             if (context != null && context.LoggingEnabled)
             {
                 context.Log($"Called method \"{name}\" on object of type '{instance.GetType().Name}'.");
             }
         }
         else
         {
             if (context != null && context.LoggingEnabled)
             {
                 context.Log($"Null value returned from method \"{name}\" on object of type '{instance.GetType().Name}'.");
             }
         }
         return(result);
     }
     catch (DynamicMethodNotFoundException)
     {
         if (context != null)
         {
             context.ReportError(
                 $"Method named '{name}' was not found on the object of type '{instance.GetType().Name}'.",
                 new DynamicMethodNotFoundError());
         }
         throw;
     }
     catch (Exception ex)
     {
         if (context != null)
         {
             context.ReportError(
                 $"Exception executing method '{name}' on the object of type '{instance.GetType().Name}'.",
                 exception: ex);
         }
         throw;
     }
 }
        public static T AwaitAsyncToTyped <T>(IScriptCallContext context, Tasks.IAsyncResult <object> result)
        {
            if (result != null && !result.IsCompleted)
            {
                if (!result.AsyncWaitHandle.WaitOne(20000))       // TODO: Register this "task" and replace with loop that waits a short while.
                {
                    throw new TimeoutException($"Timeout waiting for asynchronous result in line {context.CurrentScriptFileLine}.");
                }
            }
            if (result.IsFaulted)
            {
                if (result is IObjectFaultDescriptor)
                {
                    context.ReportError("Async operation failed. Fault: " + ((IObjectFaultDescriptor)result).FaultDescription);
                }
                else
                {
                    context.ReportError("Async operation failed.");
                }
                return(default(T));
            }
            else
            {
                object v = result?.Result;
                if (v != null)
                {
                    var valueType = v.GetType();
                    if (typeof(T).IsAssignableFrom(valueType))
                    {
                        return((T)v);
                    }
                    else if (valueType == typeof(string))
                    {
                        try
                        {
                            object value = Convert.ChangeType(v, typeof(T));
                            return((T)value);
                        }
                        catch { }
                    }

                    throw new InvalidCastException($"The async result value type is \"{v.GetType().TypeName()}\", and cannot be converted into a \"{typeof(T).TypeName()}\".");
                }
            }
            return(default(T));
        }
        public static IFileElement GetFileElement(IScriptCallContext context, int id)
        {
            var element = ((ScriptFile)context.Self.ParentFile).GetFileElement(id);

            if (element == null)
            {
                context.ReportError(String.Format("INTERNAL ERROR: Could not find procedure with id = {0}.", id));
            }
            return(element);
        }
 public static IProcedureReference <T> CastToSpecificProcedureType <T>(IScriptCallContext context, IProcedureReference reference)
 {
     if (reference is IProcedureReference <T> )
     {
         return((IProcedureReference <T>)reference);
     }
     else
     {
         context.ReportError("The procedure reference is not the expected type. Type: " + reference.GetType().Name);
         return(null);
     }
 }
        public static object DynamicProcedureCall(
            this IProcedureReference procedure,
            IScriptCallContext context,
            PropertyBlock propertyBlock,
            object[] sequencialFirstArguments,
            ArgumentList namedArguments,
            object[] sequencialLastArguments)
        {
            if (procedure == null)
            {
                throw new ArgumentNullException("procedure");
            }


            IScriptCallContext subContext = null;

            try
            {
                subContext = context.EnterNewScriptContext(procedure, Logging.ContextLogOption.Normal, true);

                var methodInfo = ((FileProcedure)procedure.ProcedureData).DelegateType.GetMethod("Invoke");
                var arguments  = new List <object>();
                int i          = 0;
                foreach (var p in methodInfo.GetParameters())
                {
                    if (i == 0)
                    {
                        arguments.Add(subContext);
                    }
                    i++;
                }
                Delegate runtimeProcedure = ((FileProcedure)procedure.ProcedureData).RuntimeProcedure;
                return(runtimeProcedure.DynamicInvoke(arguments.ToArray()));
            }
            catch (Exception ex)
            {
                context.ReportError("Exception in dynamic procedure call.", exception: ex);
                return(null);
            }
            finally
            {
                subContext.InternalDispose();
            }
        }
        /// <summary>
        /// Executes the evaluation of an expect statement.
        /// </summary>
        /// <param name="context">Execution call context.</param>
        /// <param name="evaluation">The expect statement evaluation code.</param>
        /// <param name="negativeVerdict">The verdict for negative evaluation result.</param>
        /// <param name="title">The expect statement title.</param>
        /// <param name="expected">String representation of the expectation.</param>
        /// <returns>Whether the procedure should skip the rest and return immediately.</returns>
        public static bool ExpectStatement(
            IScriptCallContext context,
            ExpectStatementEvaluationDelegate evaluation,
            Verdict negativeVerdict,
            string title,
            string expected)
        {
            bool success;

            try
            {
                string actual;
                success = evaluation(context, out actual);
                context.ReportExpectResult(title, expected, actual, success ? Verdict.Pass : negativeVerdict);

                if (success)
                {
                    return(false);
                }
                else if (negativeVerdict == Verdict.Error)
                {
                    return(true);
                }
                else
                {
                    return((context.Self.Flags & ProcedureFlags.ContinueOnFail) == ProcedureFlags.None);
                }
            }
            catch (Exception ex)
            {
                if (context != null)
                {
                    context.ReportError($"Exception thrown during expect statement execution.", exception: ex);
                }
                else
                {
                    throw;
                }

                return(true); // Do exit the procedure
            }
        }
 public static IValueContainer <T> GetGlobalVariable <T>(IScriptCallContext context, int id)
 {
     if (context == null)
     {
         foreach (var file in ServiceManager.Global.Get <ILoadedFilesManager>().ListFiles <ScriptFile>())
         {
             var container = file.TryGetVariableContainer <T>(id);
             if (container != null)
             {
                 return(container);
             }
         }
     }
     else
     {
         var container = ((StepBro.Core.ScriptData.ScriptFile)context.Self.ParentFile).TryGetVariableContainer <T>(id);
         if (container != null)
         {
             return(container);
         }
     }
     context.ReportError(String.Format("INTERNAL ERROR: Could not find variable container with id = {0}.", id));
     return(null);
 }