예제 #1
0
        internal void AnalyzeDefaultParameters(DDG ddg)
        {
            VariableDef param;

            for (int i = 0; i < Ast.ParametersInternal.Length; ++i)
            {
                var p = Ast.ParametersInternal[i];
                if (p.Annotation != null)
                {
                    var val = ddg._eval.EvaluateAnnotation(p.Annotation);
                    if (val?.Any() == true && Scope.TryGetVariable(p.Name, out param))
                    {
                        param.AddTypes(this, val, false);
                    }
                }

                if (p.DefaultValue != null && p.Kind != ParameterKind.List && p.Kind != ParameterKind.Dictionary &&
                    Scope.TryGetVariable(p.Name, out param))
                {
                    var val = ddg._eval.Evaluate(p.DefaultValue);
                    if (val != null)
                    {
                        param.AddTypes(this, val, false);
                    }
                }
            }
            if (Ast.ReturnAnnotation != null)
            {
                var ann     = ddg._eval.EvaluateAnnotation(Ast.ReturnAnnotation);
                var resType = AnalysisSet.Empty;
                if (Ast.IsGenerator && ann.Split <GeneratorInfo>(out var gens, out resType))
                {
                    var gen = ((FunctionScope)Scope).Generator;
                    foreach (var g in gens)
                    {
                        g.Yields.CopyTo(gen.Yields);
                        g.Sends.CopyTo(gen.Sends);
                        g.Returns.CopyTo(gen.Returns);
                    }
                }

                ((FunctionScope)Scope).AddReturnTypes(
                    Ast.ReturnAnnotation,
                    ddg._unit,
                    resType
                    );
            }
        }
예제 #2
0
        internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel)
        {
            // Resolve default parameters and decorators in the outer scope but
            // continue to associate changes with this unit.
            ddg.Scope = _declUnit.Scope;
            AnalyzeDefaultParameters(ddg);
            if (_decoratorCalls != null)
            {
                ProcessFunctionDecorators(ddg);
            }

            // Set the scope to within the function
            ddg.Scope = Scope;

            Ast.Body.Walk(ddg);
        }
예제 #3
0
        internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel)
        {
            // Resolve default parameters and decorators in the outer scope but
            // continue to associate changes with this unit.
            ddg.Scope = _declUnit.Scope;
            AnalyzeDefaultParameters(ddg);

            var funcType = ProcessFunctionDecorators(ddg);

            EnsureParameterZero();

            _declUnit.Scope.AddLocatedVariable(Ast.Name, Ast.NameExpression, this);

            // Set the scope to within the function
            ddg.Scope = Scope;

            Ast.Body.Walk(ddg);

            _declUnit.Scope.AssignVariable(Ast.Name, Ast.NameExpression, this, funcType);
        }
예제 #4
0
        internal void AnalyzeDefaultParameters(DDG ddg)
        {
            VariableDef param;

            for (int i = 0; i < Ast.Parameters.Count; ++i)
            {
                var p = Ast.Parameters[i];
                ddg._eval.EvaluateMaybeNull(p.Annotation);

                if (p.DefaultValue != null && p.Kind != ParameterKind.List && p.Kind != ParameterKind.Dictionary &&
                    Scope.TryGetVariable(p.Name, out param))
                {
                    var val = ddg._eval.Evaluate(p.DefaultValue);
                    if (val != null)
                    {
                        param.AddTypes(this, val, false);
                    }
                }
            }
            ddg._eval.EvaluateMaybeNull(Ast.ReturnAnnotation);
        }
예제 #5
0
        internal void ProcessFunctionDecorators(DDG ddg)
        {
            if (Ast.Decorators != null)
            {
                var        types = Function.SelfSet;
                Expression expr  = Ast.NameExpression;

                foreach (var d in Ast.Decorators.DecoratorsInternal)
                {
                    if (d != null)
                    {
                        var decorator = ddg._eval.Evaluate(d);

                        if (decorator.Contains(State.ClassInfos[BuiltinTypeId.Property]))
                        {
                            Function.IsProperty = true;
                        }
                        else if (decorator.Contains(State.ClassInfos[BuiltinTypeId.StaticMethod]))
                        {
                            // TODO: Warn if IsClassMethod is set
                            Function.IsStatic = true;
                        }
                        else if (decorator.Contains(State.ClassInfos[BuiltinTypeId.ClassMethod]))
                        {
                            // TODO: Warn if IsStatic is set
                            Function.IsClassMethod = true;
                        }
                        else
                        {
                            Expression nextExpr;
                            if (!_decoratorCalls.TryGetValue(d, out nextExpr))
                            {
                                nextExpr = _decoratorCalls[d] = new CallExpression(d, new[] { new Arg(expr) });
                            }
                            expr = nextExpr;
                            var  decorated  = AnalysisSet.Empty;
                            bool anyResults = false;
                            foreach (var ns in decorator)
                            {
                                var fd = ns as FunctionInfo;
                                if (fd != null && Scope.EnumerateTowardsGlobal.Any(s => s.AnalysisValue == fd))
                                {
                                    continue;
                                }
                                decorated  = decorated.Union(ns.Call(expr, this, new[] { types }, ExpressionEvaluator.EmptyNames));
                                anyResults = true;
                            }

                            // If processing decorators, update the current
                            // function type. Otherwise, we are acting as if
                            // each decorator returns the function unmodified.
                            if (ddg.ProjectState.Limits.ProcessCustomDecorators && anyResults)
                            {
                                types = decorated;
                            }
                        }
                    }
                }

                ddg.Scope.AddLocatedVariable(Ast.Name, Ast.NameExpression, this).AddTypes(this, types);
            }

            if (!Function.IsStatic && Ast.ParametersInternal.Length > 0)
            {
                VariableDef  param;
                IAnalysisSet firstParam;
                var          clsScope = ddg.Scope as ClassScope;
                if (clsScope == null)
                {
                    firstParam = Function.IsClassMethod ? State.ClassInfos[BuiltinTypeId.Type].SelfSet : AnalysisSet.Empty;
                }
                else
                {
                    firstParam = Function.IsClassMethod ? clsScope.Class.SelfSet : clsScope.Class.Instance.SelfSet;
                }

                if (Scope.TryGetVariable(Ast.ParametersInternal[0].Name, out param))
                {
                    param.AddTypes(this, firstParam, false);
                }
            }
        }
예제 #6
0
        internal void AnalyzeDefaultParameters(DDG ddg)
        {
            VariableDef param;
            var         scope = (FunctionScope)Scope;

            for (int i = 0; i < Ast.ParametersInternal.Length; ++i)
            {
                var p = Ast.ParametersInternal[i];
                if (p.Annotation != null)
                {
                    var val = ddg._eval.EvaluateAnnotation(p.Annotation);
                    if (val?.Any() == true && Scope.TryGetVariable(p.Name, out param))
                    {
                        param.AddTypes(this, val, false);
                        var vd = scope.GetParameter(p.Name);
                        if (vd != null && vd != param)
                        {
                            vd.AddTypes(this, val, false);
                        }
                    }
                }

                if (p.DefaultValue != null && p.Kind != ParameterKind.List && p.Kind != ParameterKind.Dictionary &&
                    Scope.TryGetVariable(p.Name, out param))
                {
                    var val = ddg._eval.Evaluate(p.DefaultValue);
                    if (val != null)
                    {
                        param.AddTypes(this, val, false);
                        var vd = scope.GetParameter(p.Name);
                        if (vd != null && vd != param)
                        {
                            vd.AddTypes(this, val, false);
                        }
                    }
                }
            }
            if (Ast.ReturnAnnotation != null)
            {
                var ann     = ddg._eval.EvaluateAnnotation(Ast.ReturnAnnotation);
                var resType = ann;
                if (Ast.IsGenerator)
                {
                    if (ann.Split <ProtocolInfo>(out var gens, out resType))
                    {
                        var gen = ((FunctionScope)Scope).Generator;
                        foreach (var g in gens.SelectMany(p => p.GetProtocols <GeneratorProtocol>()))
                        {
                            gen.Yields.AddTypes(ProjectEntry, g.Yielded);
                            gen.Sends.AddTypes(ProjectEntry, g.Sent);
                            gen.Returns.AddTypes(ProjectEntry, g.Returned);
                        }
                    }
                }
                else
                {
                    ((FunctionScope)Scope).AddReturnTypes(
                        Ast.ReturnAnnotation,
                        ddg._unit,
                        resType
                        );
                }
            }
        }
예제 #7
0
        internal IAnalysisSet ProcessFunctionDecorators(DDG ddg)
        {
            var types = Function.SelfSet;

            if (Ast.Decorators != null)
            {
                Expression expr = Ast.NameExpression;

                foreach (var d in Ast.Decorators.DecoratorsInternal)
                {
                    if (d != null)
                    {
                        var decorator = ddg._eval.Evaluate(d);

                        if (decorator.Contains(State.ClassInfos[BuiltinTypeId.Property]))
                        {
                            Function.IsProperty = true;
                        }
                        else if (decorator.Contains(State.ClassInfos[BuiltinTypeId.StaticMethod]))
                        {
                            // TODO: Warn if IsClassMethod is set
                            Function.IsStatic = true;
                        }
                        else if (decorator.Contains(State.ClassInfos[BuiltinTypeId.ClassMethod]))
                        {
                            // TODO: Warn if IsStatic is set
                            Function.IsClassMethod = true;
                        }
                        else if (ProcessAbstractDecorators(decorator))
                        {
                            // No-op
                        }
                        else
                        {
                            Expression nextExpr;
                            if (!_decoratorCalls.TryGetValue(d, out nextExpr))
                            {
                                nextExpr = _decoratorCalls[d] = new CallExpression(d, new[] { new Arg(expr) });
                                nextExpr.SetLoc(d.IndexSpan);
                            }
                            expr = nextExpr;
                            var  decorated  = AnalysisSet.Empty;
                            bool anyResults = false;
                            foreach (var ns in decorator)
                            {
                                var fd = ns as FunctionInfo;
                                if (fd != null && Scope.EnumerateTowardsGlobal.Any(s => s.AnalysisValue == fd))
                                {
                                    continue;
                                }
                                decorated  = decorated.Union(ns.Call(expr, this, new[] { types }, ExpressionEvaluator.EmptyNames));
                                anyResults = true;
                            }

                            // If processing decorators, update the current
                            // function type. Otherwise, we are acting as if
                            // each decorator returns the function unmodified.
                            if (ddg.ProjectState.Limits.ProcessCustomDecorators && anyResults)
                            {
                                types = decorated;
                            }
                        }
                    }
                }
            }

            return(types);
        }
        internal void ProcessFunctionDecorators(DDG ddg)
        {
            if (Ast.Decorators != null)
            {
                var        types = Function.SelfSet;
                Expression expr  = Ast.NameExpression;

                foreach (var d in Ast.Decorators.Decorators)
                {
                    if (d != null)
                    {
                        var decorator = ddg._eval.Evaluate(d);

                        if (decorator.Contains(ProjectState.ClassInfos[BuiltinTypeId.Property]))
                        {
                            Function.IsProperty = true;
                        }
                        else if (decorator.Contains(ProjectState.ClassInfos[BuiltinTypeId.StaticMethod]))
                        {
                            // TODO: Warn if IsClassMethod is set
                            Function.IsStatic = true;
                        }
                        else if (decorator.Contains(ProjectState.ClassInfos[BuiltinTypeId.ClassMethod]))
                        {
                            // TODO: Warn if IsStatic is set
                            Function.IsClassMethod = true;
                        }
                        else
                        {
                            Expression nextExpr;
                            if (!_decoratorCalls.TryGetValue(d, out nextExpr))
                            {
                                nextExpr = _decoratorCalls[d] = new CallExpression(d, new[] { new Arg(expr) });
                            }
                            expr  = nextExpr;
                            types = decorator.Call(expr, this, new[] { types }, ExpressionEvaluator.EmptyNames);
                        }
                    }
                }

                ddg.Scope.AddLocatedVariable(Ast.Name, Ast.NameExpression, this).AddTypes(this, types);
            }

            if (!Function.IsStatic && Ast.Parameters.Count > 0)
            {
                VariableDef  param;
                IAnalysisSet firstParam;
                var          clsScope = ddg.Scope as ClassScope;
                if (clsScope == null)
                {
                    firstParam = Function.IsClassMethod ? ProjectState.ClassInfos[BuiltinTypeId.Type].SelfSet : AnalysisSet.Empty;
                }
                else
                {
                    firstParam = Function.IsClassMethod ? clsScope.Class.SelfSet : clsScope.Class.Instance.SelfSet;
                }

                if (Scope.Variables.TryGetValue(Ast.Parameters[0].Name, out param))
                {
                    param.AddTypes(this, firstParam, false);
                }
            }
        }