예제 #1
0
        internal static void DeclareParametersInScope(this IArgumentSet args, ExpressionEval eval)
        {
            if (eval == null)
            {
                return;
            }

            // For class method no need to add extra parameters, but first parameter type should be the class.
            // For static and unbound methods do not add or set anything.
            // For regular bound methods add first parameter and set it to the class.

            foreach (var a in args.Arguments)
            {
                if (a.Value is IMember m && !string.IsNullOrEmpty(a.Name))
                {
                    eval.DeclareVariable(a.Name, m, VariableSource.Declaration, a.Location);
                }
            }

            if (args.ListArgument != null && !string.IsNullOrEmpty(args.ListArgument.Name))
            {
                var type = new PythonCollectionType(null, BuiltinTypeId.List, eval.Interpreter, false);
                var list = new PythonCollection(type, args.ListArgument.Values);
                eval.DeclareVariable(args.ListArgument.Name, list, VariableSource.Declaration, args.ListArgument.Location);
            }

            if (args.DictionaryArgument != null)
            {
                foreach (var kvp in args.DictionaryArgument.Arguments)
                {
                    eval.DeclareVariable(kvp.Key, kvp.Value, VariableSource.Declaration, args.DictionaryArgument.Location);
                }
            }
        }
예제 #2
0
        private static void Assign(SequenceExpression seq, ValueEnumerator valueEnum, ExpressionEval eval)
        {
            foreach (var item in seq.Items)
            {
                switch (item)
                {
                case StarredExpression stx when stx.Expression is NameExpression nex && !string.IsNullOrEmpty(nex.Name):
                    eval.DeclareVariable(nex.Name, valueEnum.Next, VariableSource.Declaration, nex);
                    break;

                case ParenthesisExpression pex when pex.Expression is NameExpression nex && !string.IsNullOrEmpty(nex.Name):
                    eval.DeclareVariable(nex.Name, valueEnum.Next, VariableSource.Declaration, nex);
                    break;

                case NameExpression nex when !string.IsNullOrEmpty(nex.Name):
                    eval.DeclareVariable(nex.Name, valueEnum.Next, VariableSource.Declaration, nex);
                    break;

                // Nested sequence expression in sequence, Tuple[Tuple[int, str], int], List[Tuple[int], str]
                // TODO: Because of bug with how collection types are constructed, they don't make nested collection types
                // into instances, meaning we have to create it here
                case SequenceExpression se when valueEnum.Peek is IPythonCollection || valueEnum.Peek is IPythonCollectionType:
                    var collection = valueEnum.Next;
                    var pc         = collection as IPythonCollection;
                    var pct        = collection as IPythonCollectionType;
                    Assign(se, pc ?? pct.CreateInstance(ArgumentSet.Empty(se, eval)), eval);
                    break;

                case SequenceExpression se:
                    Assign(se, valueEnum, eval);
                    break;
                }
            }
        }
        public override Task <bool> WalkAsync(ClassDefinition cd, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var classInfo = CreateClass(cd);

            _eval.DeclareVariable(cd.Name, classInfo, GetLoc(cd));
            _table.Add(new ClassEvaluator(_eval, cd));
            // Open class scope
            _scopes.Push(_eval.OpenScope(cd, out _));
            return(Task.FromResult(true));
        }
예제 #4
0
 public override bool Walk(ClassDefinition cd)
 {
     if (!string.IsNullOrEmpty(cd.NameExpression?.Name))
     {
         var classInfo = CreateClass(cd);
         _eval.DeclareVariable(cd.Name, classInfo, VariableSource.Declaration, GetLoc(cd));
         _table.Add(new ClassEvaluator(_eval, cd));
         // Open class scope
         _scopes.Push(_eval.OpenScope(_eval.Module, cd, out _));
     }
     return(true);
 }
예제 #5
0
        private void TryReplaceMember(IVariable v, IPythonType sourceType, IPythonType stubType, CancellationToken cancellationToken)
        {
            // If type does not exist in module, but exists in stub, declare it unless it is an import.
            // If types are the classes, take class from the stub, then add missing members.
            // Otherwise, replace type by one from the stub.
            switch (sourceType)
            {
            case null:
                // Nothing in source, but there is type in the stub. Declare it.
                if (v.Source == VariableSource.Declaration || v.Source == VariableSource.Generic)
                {
                    _eval.DeclareVariable(v.Name, v.Value, v.Source);
                }
                break;

            case IPythonClassType sourceClass:
                MergeMembers(v, sourceClass, stubType, cancellationToken);
                break;

            case PythonFunctionType sourceFunction:
                MergeMembers(v, sourceFunction, stubType, cancellationToken);
                break;

            case PythonPropertyType sourceProperty:
                MergeMembers(v, sourceProperty, stubType, cancellationToken);
                break;

            case IPythonModule _:
                // We do not re-declare modules.
                break;

            default:
                var stubModule = stubType.DeclaringModule;
                if (stubType is IPythonModule || stubModule.ModuleType == ModuleType.Builtins)
                {
                    // Modules members that are modules should remain as they are, i.e. os.path
                    // should remain library with its own stub attached.
                    break;
                }
                // We do not re-declaring variables that are imported.
                if (v.Source == VariableSource.Declaration)
                {
                    TransferDocumentationAndLocation(sourceType, stubType);
                    // Re-declare variable with the data from the stub.
                    var source = _eval.CurrentScope.Variables[v.Name]?.Source ?? v.Source;
                    _eval.DeclareVariable(v.Name, v.Value, source);
                }

                break;
            }
        }
 public override bool Walk(ClassDefinition cd)
 {
     if (!string.IsNullOrEmpty(cd.NameExpression?.Name))
     {
         var classInfo = CreateClass(cd);
         // The variable is transient (non-user declared) hence it does not have location.
         // Class type is tracking locations for references and renaming.
         _eval.DeclareVariable(cd.Name, classInfo, VariableSource.Declaration);
         _table.Add(new ClassEvaluator(_eval, cd));
         // Open class scope
         _scopes.Push(_eval.OpenScope(_eval.Module, cd, out _));
     }
     return(true);
 }
예제 #7
0
        private static void Assign(IEnumerable <Expression> items, ValueEnumerator valueEnum, ExpressionEval eval)
        {
            foreach (var item in items)
            {
                switch (item)
                {
                case StarredExpression stx when stx.Expression is NameExpression nex && !string.IsNullOrEmpty(nex.Name):
                    eval.DeclareVariable(nex.Name, valueEnum.Next, VariableSource.Declaration, nex);
                    break;

                case NameExpression nex when !string.IsNullOrEmpty(nex.Name):
                    eval.DeclareVariable(nex.Name, valueEnum.Next, VariableSource.Declaration, nex);
                    break;

                case TupleExpression te:
                    Assign(te.Items, valueEnum, eval);
                    break;
                }
            }
        }
        private static void AssignTuple(TupleExpression tex, ValueEnumerator valueEnum, ExpressionEval eval)
        {
            foreach (var item in tex.Items)
            {
                switch (item)
                {
                case NameExpression nex when !string.IsNullOrEmpty(nex.Name):
                    eval.DeclareVariable(nex.Name, valueEnum.Next, VariableSource.Declaration, nex);
                    break;

                case TupleExpression te:
                    AssignTuple(te, valueEnum, eval);
                    break;
                }
            }
        }
예제 #9
0
        internal static void Assign(IEnumerable <Expression> lhs, TupleExpression rhs, ExpressionEval eval)
        {
            var names  = NamesFromSequenceExpression(lhs).ToArray();
            var values = ValuesFromSequenceExpression(rhs.Items, eval).ToArray();

            for (var i = 0; i < names.Length; i++)
            {
                IMember value = null;
                if (values.Length > 0)
                {
                    value = i < values.Length ? values[i] : values[values.Length - 1];
                }

                if (!string.IsNullOrEmpty(names[i]?.Name))
                {
                    eval.DeclareVariable(names[i].Name, value ?? eval.UnknownType, VariableSource.Declaration, names[i]);
                }
            }
        }
        internal static void AssignTuple(TupleExpression lhs, TupleExpression rhs, ExpressionEval eval)
        {
            var returnedExpressions = rhs.Items.ToArray();
            var names = lhs.Items.OfType <NameExpression>().Select(x => x.Name).ToArray();

            for (var i = 0; i < names.Length; i++)
            {
                Expression e = null;
                if (returnedExpressions.Length > 0)
                {
                    e = i < returnedExpressions.Length ? returnedExpressions[i] : returnedExpressions[returnedExpressions.Length - 1];
                }

                if (e != null && !string.IsNullOrEmpty(names[i]))
                {
                    var v = eval.GetValueFromExpression(e);
                    eval.DeclareVariable(names[i], v ?? eval.UnknownType, VariableSource.Declaration, e);
                }
            }
        }