Example #1
0
        protected void EmitUsed(List <AphidExpression> args, List <AphidExpression> body)
        {
            var argIds = args
                         .Select(x => x.ToIdentifier())
                         .ToArray();

            var parentVariables = Scope
                                  .SelectMany(x => x)
                                  .Select(DeclarationHelper.GetDeclaredIdentifier)
                                  .Where(x => x != null && !argIds.Any(y => x.Identifier == y.Identifier))
                                  .Distinct()
                                  .ToArray();

            var locals = new LocalFinder()
                         .Find(body)
                         .Where(x => !parentVariables.Any(y => x.Identifier == y.Identifier))
                         .ToArray();

            var used = new PhpUseIdFinder()
                       .Find(body)
                       .Cast <IdentifierExpression>()
                       .Select(x => x.Identifier)
                       .Distinct()
                       .Where(x =>
                              !argIds
                              .Concat(locals)
                              .Any(y => y.Identifier == x) &&
                              !IsBuildInFunction(x))
                       .Select(x => new IdentifierExpression(x))
                       .ToArray();

            if (used.Length > 0)
            {
                Append("use (");
                EmitTuple(used, prefix: "&");
                Append(") ");
            }
        }
Example #2
0
        // For the first assignment to a local variable in a block before a control statement is hit,
        // if the local variable is not mentioned previously, we turn this assignment into a local declaration.
        private void AddDeclarationsWithInitialValues(IEnumerable <ILocalDefinition> localVariables, BasicBlock block)
        {
            List <ILocalDefinition> topLevelLocals = new List <ILocalDefinition>(localVariables);
            List <ILocalDefinition> localsMet      = new List <ILocalDefinition>();

            for (int i = 0; i < block.Statements.Count; i++)
            {
                if (topLevelLocals.Count == 0)
                {
                    break;
                }
                IExpressionStatement expressionStatement = block.Statements[i] as IExpressionStatement;
                if (expressionStatement != null)
                {
                    IAssignment assignment = expressionStatement.Expression as IAssignment;
                    if (assignment != null)
                    {
                        ILocalDefinition localDef = assignment.Target.Definition as ILocalDefinition;
                        if (localDef != null && topLevelLocals.Contains(localDef) && !localsMet.Contains(localDef) && !this.declaredLocals.ContainsKey(localDef))
                        {
                            LocalDeclarationStatement localDecl = new LocalDeclarationStatement()
                            {
                                LocalVariable = localDef, InitialValue = assignment.Source, Locations = new List <ILocation>(expressionStatement.Locations),
                            };
                            this.declaredLocals.Add(localDef, true);
                            block.Statements[i] = localDecl;
                            topLevelLocals.Remove(localDef);
                            localsMet.Add(localDef);
                        }
                    }
                }
                LocalFinder finder = new LocalFinder();
                finder.Traverse(block.Statements[i]);
                foreach (ILocalDefinition local in finder.FoundLocals)
                {
                    if (!localsMet.Contains(local))
                    {
                        localsMet.Add(local);
                    }
                }
                //Once we see a statement that can transfer control somewhere else, we
                //no longer know that any subsequent assignment dominates all references
                //and hence cannot postpone adding the declaration until we can unify it with the assignment.
                IGotoStatement gotoStatement = block.Statements[i] as IGotoStatement;
                if (gotoStatement != null)
                {
                    break;
                }
                IConditionalStatement conditionalStatement = block.Statements[i] as IConditionalStatement;
                if (conditionalStatement != null)
                {
                    break;
                }
                ISwitchStatement switchStatement = block.Statements[i] as ISwitchStatement;
                if (switchStatement != null)
                {
                    break;
                }
                IForEachStatement foreachStatement = block.Statements[i] as IForEachStatement;
                if (foreachStatement != null)
                {
                    break;
                }
                IForStatement forStatement = block.Statements[i] as IForStatement;
                if (forStatement != null)
                {
                    break;
                }
                ITryCatchFinallyStatement tryStatement = block.Statements[i] as ITryCatchFinallyStatement;
                if (tryStatement != null)
                {
                    break;
                }
            }
        }