Esempio n. 1
0
		public TransactionScope(TransactionMode mode) : base(SessionScopeType.Transactional)
		{
			this.mode = mode;

			ISessionScope previousScope = ScopeUtil.FindPreviousScope(this,  
				mode == TransactionMode.Inherits ? true : false );

			if (previousScope != null)
			{
				if (previousScope.ScopeType == SessionScopeType.Transactional)
				{
					parentTransactionScope = previousScope as TransactionScope;
				}
				else
				{
					// This is not a safe cast. Reconsider it
					parentSimpleScope = (AbstractScope) previousScope;

					foreach(ISession session in parentSimpleScope.GetSessions())
					{
						EnsureHasTransaction(session);
					}
				}
			}
		}
        public void Visit(ClassAst ast)
        {
            if (Global == null)
            {
                Global = Current;
            }

            var classSymbol = ScopeUtil.DefineClassSymbol(ast);

            Current.Define(classSymbol);

            SetScopeType(ScopeType.Class);

            SetScopeSource(classSymbol);

            ScopeTree.CreateScope();

            ast.Body.Visit(this);

            classSymbol.Symbols = ast.Body.CurrentScope.Symbols;

            //redefine the class symbol now with actual symbols
            Current.Define(classSymbol);

            ast.Body.CurrentScope.AllowAllForwardReferences = true;

            ScopeTree.PopScope();

            if (ast.Global == null)
            {
                ast.Global = Global;
            }

            SetScopeType(ScopeType.Global);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="executionEntityManager"></param>
        /// <param name="parentExecution"></param>
        protected internal virtual void HandleMultiInstanceSubProcess(IExecutionEntityManager executionEntityManager, IExecutionEntity parentExecution)
        {
            IList <IExecutionEntity> activeChildExecutions = GetActiveChildExecutionsForExecution(executionEntityManager, parentExecution.Id);
            bool containsOtherChildExecutions = false;

            foreach (IExecutionEntity activeExecution in activeChildExecutions)
            {
                if (!activeExecution.Id.Equals(execution.Id))
                {
                    containsOtherChildExecutions = true;
                }
            }

            if (!containsOtherChildExecutions)
            {
                // Destroy the current scope (subprocess) and leave via the subprocess

                ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(parentExecution);
                Context.Agenda.PlanDestroyScopeOperation(parentExecution);

                SubProcess subProcess = execution.CurrentFlowElement.SubProcess;
                MultiInstanceActivityBehavior multiInstanceBehavior = (MultiInstanceActivityBehavior)subProcess.Behavior;
                parentExecution.CurrentFlowElement = subProcess;
                multiInstanceBehavior.Leave(parentExecution);
            }
        }
        private void ValidateReturnStatementType(MethodDeclr ast, Symbol symbol)
        {
            if (!ResolvingTypes)
            {
                return;
            }

            IType returnStatementType;

            // no return found
            if (ast.ReturnAst == null)
            {
                returnStatementType = new BuiltInType(ExpressionTypes.Void);
            }
            else
            {
                returnStatementType = ast.ReturnAst.AstSymbolType;
            }

            var delcaredSymbol = ScopeUtil.CreateSymbolType(ast.MethodReturnType);

            // if its inferred, just use whatever the return statement i
            if (delcaredSymbol.ExpressionType == ExpressionTypes.Inferred)
            {
                return;
            }

            if (!TokenUtil.EqualOrPromotable(returnStatementType.ExpressionType, delcaredSymbol.ExpressionType))
            {
                throw new InvalidSyntax(String.Format("Return type {0} for function {1} is not of the same type of declared method (type {2})",
                                                      returnStatementType.ExpressionType, symbol.Name, delcaredSymbol.ExpressionType));
            }
        }
        public void Visit(FuncInvoke ast)
        {
            if (ast.CallingScope != null)
            {
                ast.Arguments.ForEach(arg => arg.CallingScope = ast.CallingScope);
            }

            ast.Arguments.ForEach(arg => arg.Visit(this));

            SetScope(ast);

            var functionType = Resolve(ast.FunctionName) as MethodSymbol;

            if (functionType != null && ast.Arguments.Count < functionType.MethodDeclr.Arguments.Count)
            {
                var curriedMethod = CreateCurriedMethod(ast, functionType);

                curriedMethod.Visit(this);

                var methodSymbol = ScopeUtil.DefineMethod(curriedMethod);

                Current.Define(methodSymbol);

                ast.ConvertedExpression = curriedMethod;
            }
            else if (ResolvingTypes)
            {
                ast.AstSymbolType = ResolveType(ast.FunctionName, ast.CurrentScope);
            }
        }
Esempio n. 6
0
 public object get(string str, Class c)
 {
     try {
         return(ScopeUtil.get(ReferenceObject, str ?? "", c ?? null));
     } catch { }
     return(null);
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="TransactionScope"/> class.
        /// </summary>
        /// <param name="mode">Whatever to create a new transaction or inherits an existing one</param>
        /// <param name="isolationLevel">The transaction isolation level.</param>
        /// <param name="onDisposeBehavior">The on dispose behavior.</param>
        public TransactionScope(TransactionMode mode, IsolationLevel isolationLevel, OnDispose onDisposeBehavior)
            : base(FlushAction.Config, SessionScopeType.Transactional)
        {
            this.mode              = mode;
            this.isolationLevel    = isolationLevel;
            this.onDisposeBehavior = onDisposeBehavior;

            bool preferenceForTransactionScope = mode == TransactionMode.Inherits ? true : false;

            ISessionScope previousScope = ScopeUtil.FindPreviousScope(this, preferenceForTransactionScope);

            if (previousScope != null)
            {
                if (previousScope.ScopeType == SessionScopeType.Transactional)
                {
                    parentTransactionScope = previousScope as TransactionScope;
                }
                else
                {
                    // This is not a safe cast. Reconsider it
                    parentSimpleScope = (AbstractScope)previousScope;

                    foreach (ISession session in parentSimpleScope.GetSessions())
                    {
                        EnsureHasTransaction(session);
                    }
                }
            }
        }
        public override void Execute(IExecutionEntity execution)
        {
            ThrowEvent throwEvent = (ThrowEvent)execution.CurrentFlowElement;

            /*
             * From the BPMN 2.0 spec:
             *
             * The Activity to be compensated MAY be supplied.
             *
             * If an Activity is not supplied, then the compensation is broadcast to all completed Activities in
             * the current Sub- Process (if present), or the entire Process instance (if at the global level). This "throws" the compensation.
             */
            string activityRef = compensateEventDefinition.ActivityRef;

            ICommandContext commandContext = Context.CommandContext;
            IEventSubscriptionEntityManager eventSubscriptionEntityManager = commandContext.EventSubscriptionEntityManager;

            IList <ICompensateEventSubscriptionEntity> eventSubscriptions = new List <ICompensateEventSubscriptionEntity>();

            if (!string.IsNullOrWhiteSpace(activityRef))
            {
                // If an activity ref is provided, only that activity is compensated
                ((List <ICompensateEventSubscriptionEntity>)eventSubscriptions).AddRange(eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.ProcessInstanceId, activityRef));
            }
            else
            {
                // If no activity ref is provided, it is broadcast to the current sub process / process instance
                Process process = ProcessDefinitionUtil.GetProcess(execution.ProcessDefinitionId);

                IFlowElementsContainer flowElementsContainer;
                if (throwEvent.SubProcess == null)
                {
                    flowElementsContainer = process;
                }
                else
                {
                    flowElementsContainer = throwEvent.SubProcess;
                }

                foreach (FlowElement flowElement in flowElementsContainer.FlowElements)
                {
                    if (flowElement is Activity)
                    {
                        ((List <ICompensateEventSubscriptionEntity>)eventSubscriptions).AddRange(eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByProcessInstanceIdAndActivityId(execution.ProcessInstanceId, flowElement.Id));
                    }
                }
            }

            if (eventSubscriptions.Count == 0)
            {
                Leave(execution);
            }
            else
            {
                // TODO: implement async (waitForCompletion=false in bpmn)
                ScopeUtil.ThrowCompensationEvent(eventSubscriptions, execution, false);
                Leave(execution);
            }
        }
Esempio n. 9
0
        public override void Trigger(IExecutionEntity execution, string triggerName, object triggerData, bool throwError = true)
        {
            BoundaryEvent boundaryEvent = (BoundaryEvent)execution.CurrentFlowElement;

            ICommandContext         commandContext         = Context.CommandContext;
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;

            IExecutionEntity subProcessExecution = null;
            // TODO: this can be optimized. A full search in the all executions shouldn't be needed
            IList <IExecutionEntity> processInstanceExecutions = executionEntityManager.FindChildExecutionsByProcessInstanceId(execution.ProcessInstanceId);

            foreach (IExecutionEntity childExecution in processInstanceExecutions)
            {
                if (childExecution.CurrentFlowElement != null && childExecution.CurrentFlowElement.Id.Equals(boundaryEvent.AttachedToRefId))
                {
                    subProcessExecution = childExecution;
                    break;
                }
            }

            if (subProcessExecution == null)
            {
                throw new ActivitiException("No execution found for sub process of boundary cancel event " + boundaryEvent.Id);
            }

            IEventSubscriptionEntityManager            eventSubscriptionEntityManager = commandContext.EventSubscriptionEntityManager;
            IList <ICompensateEventSubscriptionEntity> eventSubscriptions             = eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByExecutionId(subProcessExecution.ParentId);

            if (eventSubscriptions.Count == 0)
            {
                Leave(execution);
            }
            else
            {
                Leave(execution);

                string deleteReason = History.DeleteReasonFields.BOUNDARY_EVENT_INTERRUPTING + "(" + boundaryEvent.Id + ")";

                // cancel boundary is always sync
                ScopeUtil.ThrowCompensationEvent(eventSubscriptions, execution, false);
                executionEntityManager.DeleteExecutionAndRelatedData(subProcessExecution, deleteReason, false);
                if (subProcessExecution.CurrentFlowElement is Activity activity)
                {
                    if (activity.LoopCharacteristics != null)
                    {
                        IExecutionEntity         miExecution       = subProcessExecution.Parent;
                        IList <IExecutionEntity> miChildExecutions = executionEntityManager.FindChildExecutionsByParentExecutionId(miExecution.Id);
                        foreach (IExecutionEntity miChildExecution in miChildExecutions)
                        {
                            if (subProcessExecution.Id.Equals(miChildExecution.Id) == false && activity.Id.Equals(miChildExecution.CurrentActivityId))
                            {
                                executionEntityManager.DeleteExecutionAndRelatedData(miChildExecution, deleteReason, false);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Creates a type for built in types or resolves user defined types
        /// </summary>
        /// <param name="ast"></param>
        /// <returns></returns>
        private IType ResolveOrDefine(Expr ast)
        {
            if (ast == null)
            {
                return(null);
            }

            switch (ast.Token.TokenType)
            {
            case TokenType.Word: return(ResolveType(ast));
            }

            return(ScopeUtil.CreateSymbolType(ast));
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="executionEntityManager"></param>
        /// <param name="parentExecution"></param>
        /// <param name="subProcess"></param>
        /// <returns></returns>
        protected internal virtual IExecutionEntity HandleSubProcessEnd(IExecutionEntityManager executionEntityManager, IExecutionEntity parentExecution, SubProcess subProcess)
        {
            // create a new execution to take the outgoing sequence flows
            IExecutionEntity executionToContinue = executionEntityManager.CreateChildExecution(parentExecution.Parent);

            executionToContinue.CurrentFlowElement = subProcess;

            bool hasCompensation = false;

            if (subProcess is Transaction)
            {
                hasCompensation = true;
            }
            else
            {
                foreach (FlowElement subElement in subProcess.FlowElements)
                {
                    if (subElement is Activity subActivity)
                    {
                        if (CollectionUtil.IsNotEmpty(subActivity.BoundaryEvents))
                        {
                            foreach (BoundaryEvent boundaryEvent in subActivity.BoundaryEvents)
                            {
                                if (CollectionUtil.IsNotEmpty(boundaryEvent.EventDefinitions) && boundaryEvent.EventDefinitions[0] is CompensateEventDefinition)
                                {
                                    hasCompensation = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            // All executions will be cleaned up afterwards. However, for compensation we need
            // a copy of these executions so we can use them later on when the compensation is thrown.
            // The following method does exactly that, and moves the executions beneath the process instance.
            if (hasCompensation)
            {
                ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(parentExecution);
            }

            executionEntityManager.DeleteChildExecutions(parentExecution, null, false);
            executionEntityManager.DeleteExecutionAndRelatedData(parentExecution, null, false);

            Context.ProcessEngineConfiguration.EventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateActivityEvent(ActivitiEventType.ACTIVITY_COMPLETED, subProcess.Id, subProcess.Name, parentExecution.Id, parentExecution.ProcessInstanceId, parentExecution.ProcessDefinitionId, subProcess));
            return(executionToContinue);
        }
        private LambdaDeclr CreateCurriedMethod(FuncInvoke ast, MethodSymbol functionType)
        {
            var srcMethod = functionType.MethodDeclr;

            var fixedAssignments = new List <VarDeclrAst>();

            var count = 0;

            foreach (var argValue in ast.Arguments)
            {
                var srcArg = srcMethod.Arguments[count] as VarDeclrAst;

                var token = new Token(srcArg.DeclarationType.Token.TokenType, argValue.Token.TokenValue);

                var declr = new VarDeclrAst(token, srcArg.Token, new Expr(argValue.Token));

                // if we're creating a curry using a variable then we need to resolve the variable type
                // otherwise we can make a symbol for the literal
                var newArgType = argValue.Token.TokenType == TokenType.Word ?
                                 ast.CurrentScope.Resolve(argValue).Type
                                    :   ScopeUtil.CreateSymbolType(argValue);

                // create a symbol type for the target we're invoking on so we can do type checking
                var targetArgType = ScopeUtil.CreateSymbolType(srcArg.DeclarationType);

                if (!TokenUtil.EqualOrPromotable(newArgType, targetArgType))
                {
                    throw new InvalidSyntax(String.Format("Cannot pass argument {0} of type {1} to partial function {2} as argument {3} of type {4}",
                                                          argValue.Token.TokenValue,
                                                          newArgType.TypeName,
                                                          srcMethod.MethodName.Token.TokenValue,
                                                          srcArg.VariableName.Token.TokenValue,
                                                          targetArgType.TypeName));
                }

                fixedAssignments.Add(declr);

                count++;
            }

            var newBody = fixedAssignments.Concat(srcMethod.Body.ScopedStatements).ToList();

            var curriedMethod = new LambdaDeclr(srcMethod.Arguments.Skip(ast.Arguments.Count).ToList(), new ScopeDeclr(newBody));

            SetScope(curriedMethod);

            return(curriedMethod);
        }
        public virtual void HandleEvent(IEventSubscriptionEntity eventSubscription, object payload, ICommandContext commandContext)
        {
            string configuration = eventSubscription.Configuration;

            if (configuration is null)
            {
                throw new ActivitiException("Compensating execution not set for compensate event subscription with id " + eventSubscription.Id);
            }

            IExecutionEntity compensatingExecution = commandContext.ExecutionEntityManager.FindById <IExecutionEntity>(configuration);

            string  processDefinitionId = compensatingExecution.ProcessDefinitionId;
            Process process             = ProcessDefinitionUtil.GetProcess(processDefinitionId);

            if (process == null)
            {
                throw new ActivitiException("Cannot start process instance. Process model (id = " + processDefinitionId + ") could not be found");
            }

            FlowElement flowElement = process.GetFlowElement(eventSubscription.ActivityId, true);

            if (flowElement is SubProcess && !((SubProcess)flowElement).ForCompensation)
            {
                // descend into scope:
                compensatingExecution.IsScope = true;
                IList <ICompensateEventSubscriptionEntity> eventsForThisScope = commandContext.EventSubscriptionEntityManager.FindCompensateEventSubscriptionsByExecutionId(compensatingExecution.Id);
                ScopeUtil.ThrowCompensationEvent(eventsForThisScope, compensatingExecution, false);
            }
            else
            {
                try
                {
                    if (commandContext.ProcessEngineConfiguration.EventDispatcher.Enabled)
                    {
                        commandContext.ProcessEngineConfiguration.EventDispatcher.DispatchEvent(ActivitiEventBuilder.CreateActivityEvent(ActivitiEventType.ACTIVITY_COMPENSATE, flowElement.Id, flowElement.Name, compensatingExecution.Id, compensatingExecution.ProcessInstanceId, compensatingExecution.ProcessDefinitionId, flowElement));
                    }
                    compensatingExecution.CurrentFlowElement = flowElement;
                    Context.Agenda.PlanContinueProcessInCompensation(compensatingExecution);
                }
                catch (Exception e)
                {
                    throw new ActivitiException("Error while handling compensation event " + eventSubscription, e);
                }
            }
        }
        public void Visit(MethodDeclr ast)
        {
            var previousMethod = CurrentMethod;

            CurrentMethod = ast;

            var symbol = ScopeUtil.DefineMethod(ast);

            Current.Define(symbol);

            ScopeTree.CreateScope();

            ast.Arguments.ForEach(arg => arg.Visit(this));

            ast.Body.Visit(this);

            SetScope(ast);

            if (symbol.Type.ExpressionType == ExpressionTypes.Inferred)
            {
                if (ast.ReturnAst == null)
                {
                    ast.AstSymbolType = new BuiltInType(ExpressionTypes.Void);
                }
                else
                {
                    ast.AstSymbolType = ast.ReturnAst.AstSymbolType;
                }
            }
            else
            {
                ast.AstSymbolType = symbol.Type;
            }

            ValidateReturnStatementType(ast, symbol);

            ScopeTree.PopScope();

            CurrentMethod = previousMethod;
        }
Esempio n. 15
0
        public override void Execute(IExecutionEntity execution)
        {
            IExecutionEntity        executionEntity        = execution;
            ICommandContext         commandContext         = Context.CommandContext;
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;

            // find cancel boundary event:
            IExecutionEntity parentScopeExecution       = null;
            IExecutionEntity currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(executionEntity.ParentId);

            while (currentlyExaminedExecution != null && parentScopeExecution == null)
            {
                if (currentlyExaminedExecution.CurrentFlowElement is SubProcess)
                {
                    parentScopeExecution = currentlyExaminedExecution;
                    SubProcess subProcess = (SubProcess)currentlyExaminedExecution.CurrentFlowElement;
                    if (subProcess.LoopCharacteristics != null)
                    {
                        IExecutionEntity miExecution = parentScopeExecution.Parent;
                        FlowElement      miElement   = miExecution.CurrentFlowElement;
                        if (miElement != null && miElement.Id.Equals(subProcess.Id))
                        {
                            parentScopeExecution = miExecution;
                        }
                    }
                }
                else
                {
                    currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId);
                }
            }

            if (parentScopeExecution == null)
            {
                throw new ActivitiException("No sub process execution found for cancel end event " + executionEntity.CurrentActivityId);
            }

            {
                SubProcess    subProcess          = (SubProcess)parentScopeExecution.CurrentFlowElement;
                BoundaryEvent cancelBoundaryEvent = null;
                if (CollectionUtil.IsNotEmpty(subProcess.BoundaryEvents))
                {
                    foreach (BoundaryEvent boundaryEvent in subProcess.BoundaryEvents)
                    {
                        if (CollectionUtil.IsNotEmpty(boundaryEvent.EventDefinitions) && boundaryEvent.EventDefinitions[0] is CancelEventDefinition)
                        {
                            cancelBoundaryEvent = boundaryEvent;
                            break;
                        }
                    }
                }

                if (cancelBoundaryEvent == null)
                {
                    throw new ActivitiException("Could not find cancel boundary event for cancel end event " + executionEntity.CurrentActivityId);
                }

                IExecutionEntity newParentScopeExecution = null;
                currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(parentScopeExecution.ParentId);
                while (currentlyExaminedExecution != null && newParentScopeExecution == null)
                {
                    if (currentlyExaminedExecution.IsScope)
                    {
                        newParentScopeExecution = currentlyExaminedExecution;
                    }
                    else
                    {
                        currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId);
                    }
                }

                ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(parentScopeExecution);

                if (subProcess.LoopCharacteristics != null)
                {
                    IList <IExecutionEntity> multiInstanceExecutions = parentScopeExecution.Executions;
                    IList <IExecutionEntity> executionsToDelete      = new List <IExecutionEntity>();
                    foreach (IExecutionEntity multiInstanceExecution in multiInstanceExecutions)
                    {
                        if (!multiInstanceExecution.Id.Equals(parentScopeExecution.Id))
                        {
                            ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(multiInstanceExecution);

                            // end all executions in the scope of the transaction
                            executionsToDelete.Add(multiInstanceExecution);
                            DeleteChildExecutions(multiInstanceExecution, executionEntity, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED);
                        }
                    }

                    foreach (IExecutionEntity executionEntityToDelete in executionsToDelete)
                    {
                        DeleteChildExecutions(executionEntityToDelete, executionEntity, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED);
                    }
                }

                // The current activity is finished (and will not be ended in the deleteChildExecutions)
                commandContext.HistoryManager.RecordActivityEnd(executionEntity, null);

                // set new parent for boundary event execution
                executionEntity.Parent             = newParentScopeExecution ?? throw new ActivitiException("Programmatic error: no parent scope execution found for boundary event " + cancelBoundaryEvent.Id);
                executionEntity.CurrentFlowElement = cancelBoundaryEvent;

                // end all executions in the scope of the transaction
                DeleteChildExecutions(parentScopeExecution, executionEntity, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED);
                commandContext.HistoryManager.RecordActivityEnd(parentScopeExecution, History.DeleteReasonFields.TRANSACTION_CANCELED);

                Context.Agenda.PlanTriggerExecutionOperation(executionEntity);
            }
        }
        public void Visit(VarDeclrAst ast)
        {
            var isVar = ast.DeclarationType.Token.TokenType == TokenType.Infer;

            if (ast.DeclarationType != null && !isVar)
            {
                var symbol = ScopeUtil.DefineUserSymbol(ast.DeclarationType, ast.VariableName);

                symbol.IsArray = ast is ArrayDeclrAst;

                DefineToScope(ast, symbol);

                ast.AstSymbolType = symbol.Type;
            }

            if (ast.VariableValue == null && isVar)
            {
                var symbol = ScopeUtil.DefineUserSymbol(ast.DeclarationType, ast.VariableName);

                DefineToScope(ast, symbol);

                ast.AstSymbolType = symbol.Type;
            }

            else if (ast.VariableValue != null)
            {
                ast.VariableValue.Visit(this);

                // if its type inferred, determine the declaration by the value's type
                if (isVar)
                {
                    // if the right hand side is a method declaration, make sure to track the source value
                    // this way we can reference it later to determine not only that this is a method type, but what
                    // is the expected return value for static type checking later

                    var val = ast.VariableValue.ConvertedExpression ?? ast.VariableValue;

                    ast.AstSymbolType = val is MethodDeclr
                                            ? new BuiltInType(ExpressionTypes.Method, val)
                                            : val.AstSymbolType;

                    var symbol = ScopeUtil.DefineUserSymbol(ast.AstSymbolType, ast.VariableName);

                    symbol.IsArray = ast is ArrayDeclrAst;

                    DefineToScope(ast, symbol);
                }
                else if (ResolvingTypes)
                {
                    var declaredType = ScopeUtil.CreateSymbolType(ast.DeclarationType);

                    var value = ast.VariableValue.ConvertedExpression ?? ast.VariableValue;

                    ReturnAst returnType = null;

                    // when we're resolving types check if the rhs is a function invoke. if it is, see
                    // what the return value of the src expression is so we can make sure that the
                    // lhs and the rhs match.
                    try
                    {
                        returnType =
                            value is FuncInvoke
                                ? ((value as FuncInvoke).AstSymbolType) != null
                                      ? ((value as FuncInvoke).AstSymbolType.Src as MethodDeclr).ReturnAst
                                      : null
                                : null;
                    }
                    catch
                    {
                    }

                    value = returnType != null ? returnType.ReturnExpression : value;

                    if (!TokenUtil.EqualOrPromotable(value.AstSymbolType.ExpressionType, declaredType.ExpressionType))
                    {
                        throw new InvalidSyntax(String.Format("Cannot assign {0} of type {1} to {2}", ast.VariableValue,
                                                              value.AstSymbolType.ExpressionType,
                                                              declaredType.ExpressionType));
                    }
                }
            }

            SetScope(ast);
        }
        private dynamic Exec(Ast ast)
        {
            try
            {
                if (ast == null)
                {
                    return(null);
                }

                if (ast.ConvertedExpression != null)
                {
                    return(Exec(ast.ConvertedExpression));
                }

                switch (ast.AstType)
                {
                case AstTypes.ScopeDeclr:
                    ScopeDelcaration(ast as ScopeDeclr);
                    break;

                case AstTypes.VarDeclr:
                    VariableDeclaration(ast as VarDeclrAst);
                    break;

                case AstTypes.Expression:
                    var ret = Expression(ast as Expr);
                    if (ret != null)
                    {
                        return(ret);
                    }
                    break;

                case AstTypes.Print:
                    Print(ast as PrintAst);
                    break;

                case AstTypes.FunctionInvoke:
                    return(InvokeFunction(ast as FuncInvoke));

                case AstTypes.Conditional:
                    ConditionalDo(ast as Conditional);
                    break;

                case AstTypes.MethodDeclr:
                    var methodDeclr = ast as MethodDeclr;
                    return(new MethodSymbol(methodDeclr.Token.TokenValue, ScopeUtil.CreateSymbolType(methodDeclr.ReturnAst), methodDeclr));

                case AstTypes.While:
                    WhileDo(ast as WhileLoop);
                    break;

                case AstTypes.Return:
                    ReturnDo(ast as ReturnAst);
                    break;

                case AstTypes.For:
                    ForDo(ast as ForLoop);
                    break;

                case AstTypes.Class:
                    ClassDo(ast as ClassAst);
                    break;

                case AstTypes.ClassRef:
                    return(ClassRefDo(ast as ClassReference));

                    break;

                case AstTypes.New:
                    return(NewDo(ast as NewAst));

                    break;
                }
            }
            catch (ReturnException ex)
            {
                // let the return value bubble up through all the exectuions until we
                // get to the source syntax tree that invoked it. at that point safely return the value
                if (ast.AstType == AstTypes.FunctionInvoke)
                {
                    return(ex.Value);
                }

                throw;
            }

            return(null);
        }
Esempio n. 18
0
        public override void Leave(IExecutionEntity execution, object signalData)
        {
            lock (syncRoot)
            {
                ICommandContext commandContext = Context.CommandContext;
                if (commandContext == null)
                {
                    throw new ActivitiException("lazy loading outside command context");
                }

                completedPolicy.LeaveExection = execution;

                bool zeroNrOfInstances = false;
                if (ResolveNrOfInstances(execution) == 0)
                {
                    // Empty collection, just leave.
                    zeroNrOfInstances = true;
                    RemoveLocalLoopVariable(execution, CollectionElementIndexVariable);
                    base.Leave(execution, signalData); // Plan the default leave
                    execution.IsMultiInstanceRoot = false;
                }

                int loopCounter            = GetLoopVariable(execution, CollectionElementIndexVariable).GetValueOrDefault(0);
                int nrOfInstances          = GetLoopVariable(execution, NUMBER_OF_INSTANCES).GetValueOrDefault(0);
                int nrOfCompletedInstances = GetLoopVariable(execution, NUMBER_OF_COMPLETED_INSTANCES).GetValueOrDefault(0) + 1;
                int nrOfActiveInstances    = GetLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES).GetValueOrDefault(0) - 1;

                Context.CommandContext.HistoryManager.RecordActivityEnd(execution, null);
                CallActivityEndListeners(execution);

                if (zeroNrOfInstances)
                {
                    return;
                }

                IExecutionEntity miRootExecution = GetMultiInstanceRootExecution(execution);
                if (miRootExecution != null)
                { // will be null in case of empty collection
                    SetLoopVariable(miRootExecution, NUMBER_OF_COMPLETED_INSTANCES, nrOfCompletedInstances);
                    SetLoopVariable(miRootExecution, NUMBER_OF_ACTIVE_INSTANCES, nrOfActiveInstances < 0 ? 0 : nrOfActiveInstances);
                }

                //ExecuteCompensationBoundaryEvents(execution.CurrentFlowElement, execution);

                LogLoopDetails(execution, "instance completed", loopCounter, nrOfCompletedInstances, nrOfActiveInstances, nrOfActiveInstances < 0 ? 0 : nrOfActiveInstances);

                if (execution.Parent != null)
                {
                    execution.Inactivate();
                    LockFirstParentScope(execution);

                    if (CompletionConditionSatisfied(execution.Parent, signalData) || nrOfCompletedInstances >= nrOfInstances)
                    {
                        IExecutionEntity executionToUse;
                        if (nrOfInstances > 0)
                        {
                            executionToUse = execution.Parent;
                        }
                        else
                        {
                            executionToUse = execution;
                        }

                        bool     hasCompensation = false;
                        Activity activity        = (Activity)execution.CurrentFlowElement;
                        if (activity is Transaction)
                        {
                            hasCompensation = true;
                        }
                        else if (activity is SubProcess subProcess)
                        {
                            foreach (FlowElement subElement in subProcess.FlowElements)
                            {
                                if (subElement is Activity subActivity)
                                {
                                    if (CollectionUtil.IsNotEmpty(subActivity.BoundaryEvents))
                                    {
                                        foreach (BoundaryEvent boundaryEvent in subActivity.BoundaryEvents)
                                        {
                                            if (CollectionUtil.IsNotEmpty(boundaryEvent.EventDefinitions) && boundaryEvent.EventDefinitions[0] is CompensateEventDefinition)
                                            {
                                                hasCompensation = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (hasCompensation)
                        {
                            ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(executionToUse);
                        }

                        if (activity is CallActivity)
                        {
                            IExecutionEntityManager executionEntityManager = Context.CommandContext.ExecutionEntityManager;
                            if (executionToUse != null)
                            {
                                IList <string> callActivityExecutionIds = new List <string>();

                                // Find all execution entities that are at the call activity
                                IList <IExecutionEntity> childExecutions = executionEntityManager.CollectChildren(executionToUse);
                                if (childExecutions != null)
                                {
                                    foreach (IExecutionEntity childExecution in childExecutions)
                                    {
                                        if (activity.Id.Equals(childExecution.CurrentActivityId))
                                        {
                                            callActivityExecutionIds.Add(childExecution.Id);
                                        }
                                    }

                                    // Now all call activity executions have been collected, loop again and check which should be removed
                                    for (int i = childExecutions.Count - 1; i >= 0; i--)
                                    {
                                        IExecutionEntity childExecution = childExecutions[i];
                                        if (!string.IsNullOrWhiteSpace(childExecution.SuperExecutionId) && callActivityExecutionIds.Contains(childExecution.SuperExecutionId))
                                        {
                                            executionEntityManager.DeleteProcessInstanceExecutionEntity(childExecution.Id, activity.Id, "call activity completion condition met", true, false);
                                        }
                                    }
                                }
                            }
                        }

                        DeleteChildExecutions(executionToUse, false, Context.CommandContext);
                        RemoveLocalLoopVariable(executionToUse, CollectionElementIndexVariable);
                        executionToUse.IsScope             = false;
                        executionToUse.IsMultiInstanceRoot = false;
                        Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(executionToUse, true);
                    }
                }
                else
                {
                    RemoveLocalLoopVariable(execution, CollectionElementIndexVariable);
                    execution.IsMultiInstanceRoot = false;
                    base.Leave(execution, signalData);
                }
            }
        }