Example #1
0
        protected override void VisitRoutineCall(BoundRoutineCall x)
        {
            var invocation = (IInvocationExpression)x;

            if (invocation.TargetMethod != null)
            {
                if (!invocation.TargetMethod.IsImplicitlyDeclared || invocation.TargetMethod is IErrorMethodSymbol)
                {
                    Span span;
                    if (x.PhpSyntax is FunctionCall)
                    {
                        span = ((FunctionCall)x.PhpSyntax).NameSpan;
                        _result.Add(new SymbolStat(_tctx, span, x, invocation.TargetMethod));
                    }
                }
            }

            //
            base.VisitRoutineCall(x);
        }
Example #2
0
        public bool EnqueueRoutine(IPhpRoutineSymbol routine, T caller, BoundRoutineCall callExpression)
        {
            Contract.ThrowIfNull(routine);

            if (routine.ControlFlowGraph == null)
            {
                var routine2 = routine is SynthesizedMethodSymbol sr
                    ? sr.ForwardedCall
                    : routine.OriginalDefinition as IPhpRoutineSymbol;

                if (routine2 != null && !ReferenceEquals(routine, routine2))
                {
                    return(EnqueueRoutine(routine2, caller, callExpression));
                }

                // library (sourceless) function
                return(false);
            }

            var sourceRoutine = (SourceRoutineSymbol)routine;

            if (sourceRoutine.SyntaxReturnType != null)
            {
                // we don't have to wait for return type,
                // nor reanalyse itself when routine analyses
                return(false);
            }

            _callGraph.AddEdge(caller.FlowState.Routine, sourceRoutine, new CallSite(caller, callExpression));

            // ensure caller is subscribed to routine's ExitBlock
            ((ExitBlock)routine.ControlFlowGraph.Exit).Subscribe(caller);

            // TODO: check if routine has to be reanalyzed => enqueue routine's StartBlock

            // Return whether the routine exit block will certainly be analysed in the future
            return(!sourceRoutine.IsReturnAnalysed);
        }
Example #3
0
 protected override object VisitRoutineCall(BoundRoutineCall x)
 {
     // It must be updated in the visits of non-abstract subclassess
     return(x);
 }
 public CallSite(BoundBlock block, BoundRoutineCall callExpression)
 {
     Block          = block;
     CallExpression = callExpression;
 }