Пример #1
0
 public ExceptHandler(Exp type, Identifier name, SuiteStatement body, string filename, int start, int end)
     : base(filename, start, end)
 {
     this.type = type;
     this.name = name;
     this.body = body;
 }
Пример #2
0
        public override IEnumerable <string> GetCompatibleMethods(EventDescription eventDescription)
        {
            var            classDef = GetClassForEvents();
            SuiteStatement suite    = classDef.Body as SuiteStatement;

            if (suite != null)
            {
                int requiredParamCount = eventDescription.Parameters.Count() + 1;
                foreach (var methodCandidate in suite.Statements)
                {
                    FunctionDefinition funcDef = methodCandidate as FunctionDefinition;
                    if (funcDef != null)
                    {
                        // Given that event handlers can be given any arbitrary
                        // name, it is important to not rely on the default naming
                        // to detect compatible methods.  Instead we look at the
                        // event parameters. We don't have param types in Python,
                        // so really the only thing that can be done is look at
                        // the method parameter count, which should be one more than
                        // the event parameter count (to account for the self param).
                        if (funcDef.Parameters.Count == requiredParamCount)
                        {
                            yield return(funcDef.Name);
                        }
                    }
                }
            }
        }
Пример #3
0
        public void Xlat(SuiteStatement suite)
        {
            var comments = StatementTranslator.ConvertFirstStringToComments(suite.stmts);

            stmtXlat.Xlat(suite);
            gen.CurrentMemberComments.AddRange(comments);
        }
Пример #4
0
        private void XlatConstructor(SuiteStatement stmt)
        {
            if (stmt == null)
            {
                return;
            }

            var comments = StatementTranslator.ConvertFirstStringToComments(stmt.stmts);

            stmt.Accept(this.stmtXlat);
            if (gen.Scope.Count == 0)
            {
                return;
            }
            gen.Scope[0].ToString();
            if (!(gen.Scope[0] is CodeExpressionStatement expStm))
            {
                return;
            }
            if (!(expStm.Expression is CodeApplicationExpression appl))
            {
                return;
            }
            if (!(appl.Method is CodeFieldReferenceExpression method) || method.FieldName != "__init__")
            {
                return;
            }
            var ctor = (CodeConstructor)gen.CurrentMember !;

            ctor.Comments.AddRange(comments);
            ctor.BaseConstructorArgs.AddRange(appl.Arguments.Skip(1));
            gen.Scope.RemoveAt(0);
        }
Пример #5
0
        public override bool ShowMethod(EventDescription eventDescription, string methodName)
        {
            var            classDef = GetClassForEvents();
            var            view     = _pythonFileNode.GetTextView();
            SuiteStatement suite    = classDef.Body as SuiteStatement;

            if (suite != null)
            {
                foreach (var methodCandidate in suite.Statements)
                {
                    FunctionDefinition funcDef = methodCandidate as FunctionDefinition;
                    if (funcDef != null)
                    {
                        if (funcDef.Name == methodName)
                        {
                            view.Caret.MoveTo(new VisualStudio.Text.SnapshotPoint(view.TextSnapshot, funcDef.StartIndex));
                            view.Caret.EnsureVisible();
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Пример #6
0
        private static string GetDoc(SuiteStatement node)
        {
            var docExpr = node?.Statements?.FirstOrDefault() as ExpressionStatement;
            var ce      = docExpr?.Expression as ConstantExpression;

            return(ce?.Value as string);
        }
Пример #7
0
        static Statement GetFirstStatement(string code)
        {
            PythonParser   parser         = new PythonParser();
            PythonAst      ast            = parser.CreateAst(@"snippet.py", code);
            SuiteStatement suiteStatement = (SuiteStatement)ast.Body;

            return(suiteStatement.Statements[0]);
        }
Пример #8
0
        ClassDefinition GetClassDefinition(string code)
        {
            PythonParser   parser = new PythonParser();
            PythonAst      ast    = parser.CreateAst(@"test.py", new StringTextBuffer(code));
            SuiteStatement suite  = ast.Body as SuiteStatement;

            return(suite.Statements[0] as ClassDefinition);
        }
Пример #9
0
 public override void PostWalk(SuiteStatement node)
 {
     while (_scope is StatementScope)
     {
         _scope = _scope.OuterScope;
     }
     base.PostWalk(node);
 }
Пример #10
0
 public SuiteTarget(Dictionary <ScopeStatement, int> insertLocations, ScopeStatement[] parents, SuiteStatement suite, SuiteStatement[] followingSuites, Span selectedSpan, int startIndex, int endIndex)
     : base(insertLocations, parents)
 {
     _suite           = suite;
     _start           = startIndex;
     _end             = endIndex;
     _followingSuites = followingSuites;
     _selectedSpan    = selectedSpan;
 }
Пример #11
0
        private static PythonNode Wrap(SuiteStatement stmt, PythonNode parent)
        {
            var result = new SuiteStatementNode(stmt)
            {
                Parent = parent
            };

            foreach (var statement in stmt.Statements)
            {
                result.AddChild(Wrap(statement, result));
            }
            return(result);
        }
Пример #12
0
 public void VisitSuite(SuiteStatement s)
 {
     if (s.stmts.Count == 1)
     {
         s.stmts[0].Accept(this);
     }
     else
     {
         foreach (var stmt in s.stmts)
         {
             stmt.Accept(this);
         }
     }
 }
        private void PostWalkWorker(SuiteStatement node)
        {
            if (_targetNode == null && node.StartIndex <= _start && node.EndIndex >= _end)
            {
                // figure out the range of statements we cover...
                int startIndex = 0, endIndex = node.Statements.Count - 1;
                for (int i = 0; i < node.Statements.Count; i++)
                {
                    if (node.Statements[i].EndIndex >= _start)
                    {
                        startIndex = i;
                        break;
                    }
                }
                for (int i = node.Statements.Count - 1; i >= 0; i--)
                {
                    if (node.Statements[i].StartIndex < _end)
                    {
                        endIndex = i;
                        break;
                    }
                }
                List <SuiteStatement> followingSuites = new List <SuiteStatement>();
                for (int i = _suites.Count - 1; i >= 0; i--)
                {
                    if (_suites[i] == null)
                    {
                        // we hit our marker, this is a function/class boundary
                        // We don't care about any suites which come before the marker
                        // because they live in a different scope.  We insert the marker in
                        // ShouldWalkWorker(Node node) when we have a ScopeStatement.
                        break;
                    }

                    followingSuites.Add(_suites[i]);
                }
                _targetNode = new SuiteTarget(
                    _insertLocations,
                    _parents.ToArray(),
                    node,
                    followingSuites.ToArray(),
                    _end,
                    startIndex,
                    endIndex
                    );
                _insertLocations[_parents[_parents.Count - 1]] = node.Statements.Count == 0 ?
                                                                 node.GetStartIncludingIndentation(_root) :
                                                                 node.Statements[startIndex].GetStartIncludingIndentation(_root);
            }
        }
Пример #14
0
 public SuiteTarget(
     Dictionary <ScopeStatement, SourceLocation> insertLocations,
     ScopeStatement[] parents,
     SuiteStatement suite,
     SuiteStatement[] followingSuites,
     int selectionEnd,
     int startIndex,
     int endIndex
     )
     : base(insertLocations, parents, parents[0] as PythonAst)
 {
     _suite           = suite;
     _start           = startIndex;
     _end             = endIndex;
     _followingSuites = followingSuites;
     _selectionEnd    = selectionEnd;
 }
Пример #15
0
        public override bool Walk(SuiteStatement node)
        {
            var prevSuite = _curSuite;

            _curSuite = node;

            // recursively walk the statements in the suite
            if (node.Statements != null)
            {
                foreach (var innerNode in node.Statements)
                {
                    innerNode.Walk(this);
                }
            }

            _curSuite = prevSuite;

            // then check if we encountered an assert which added an isinstance scope.
            IsInstanceScope isInstanceScope = _scope as IsInstanceScope;

            if (isInstanceScope != null && isInstanceScope._effectiveSuite == node)
            {
                // pop the isinstance scope
                _scope = _scope.OuterScope;
                // transform back into a line number and start the new statement scope on the line
                // after the suite statement.
                var lineNo = _tree.IndexToLocation(node.EndIndex).Line;

                int offset;
                if (_tree.NewLineLocations.Length == 0)
                {
                    // single line input
                    offset = 0;
                }
                else
                {
                    offset = lineNo < _tree.NewLineLocations.Length
                        ? _tree.NewLineLocations[lineNo].EndIndex
                        : _tree.NewLineLocations[_tree.NewLineLocations.Length - 1].EndIndex;
                }
                var closingScope = new StatementScope(offset, _scope);
                _scope.Children.Add(closingScope);
                _scope = closingScope;
            }
            return(false);
        }
        public override bool Walk(SuiteStatement node)
        {
            foreach (var statement in node.Statements)
            {
                switch (statement)
                {
                case ClassDefinition cd:
                    HandleScope(cd);
                    break;

                case FunctionDefinition fd:
                    HandleScope(fd);
                    break;

                case GlobalStatement gs:
                    HandleGlobal(gs);
                    break;

                case NonlocalStatement nls:
                    HandleNonLocal(nls);
                    break;

                case AugmentedAssignStatement augs:
                    _suppressDiagnostics = true;
                    augs.Left?.Walk(new ExpressionWalker(this));
                    _suppressDiagnostics = false;
                    augs.Right?.Walk(new ExpressionWalker(this));
                    break;

                case AssignmentStatement asst:
                    _suppressDiagnostics = true;
                    foreach (var lhs in asst.Left ?? Enumerable.Empty <Expression>())
                    {
                        lhs?.Walk(new ExpressionWalker(this));
                    }
                    _suppressDiagnostics = false;
                    asst.Right?.Walk(new ExpressionWalker(this));
                    break;

                default:
                    statement.Walk(new ExpressionWalker(this));
                    break;
                }
            }
            return(false);
        }
Пример #17
0
        public override bool Walk(SuiteStatement node)
        {
            var prevSuite = _curSuite;
            var prevScope = Scope;

            _curSuite = node;
            if (node.Statements != null)
            {
                foreach (var statement in node.Statements)
                {
                    statement.Walk(this);
                }
            }

            Scope     = prevScope;
            _curSuite = prevSuite;
            return(false);
        }
        /// <summary>
        /// Helper function for calculating all of the drop down entries that are available
        /// in the given suite statement.  Called to calculate both the members of top-level
        /// code and class bodies.
        /// </summary>
        private static ReadOnlyCollection <DropDownEntryInfo> CalculateEntries(SuiteStatement suite)
        {
            List <DropDownEntryInfo> newEntries = new List <DropDownEntryInfo>();

            if (suite != null)
            {
                foreach (Statement stmt in suite.Statements)
                {
                    if (stmt is ClassDefinition || stmt is FunctionDefinition)
                    {
                        newEntries.Add(new DropDownEntryInfo(stmt));
                    }
                }
            }

            newEntries.Sort(ComparisonFunction);
            return(new ReadOnlyCollection <DropDownEntryInfo>(newEntries));
        }
Пример #19
0
            public override bool Walk(SuiteStatement node)
            {
                foreach (var statement in node.Statements)
                {
                    if (statement is BreakStatement || statement is ContinueStatement)
                    {
                        // code after here is unreachable
                        break;
                    }

                    Returns = false;
                    statement.Walk(this);
                    if (Returns)
                    {
                        // rest of the code is unreachable...
                        break;
                    }
                }
                return(false);
            }
Пример #20
0
        public override IEnumerable <string> GetCompatibleMethods(EventDescription eventDescription)
        {
            var            classDef = GetClassForEvents();
            SuiteStatement suite    = classDef.Body as SuiteStatement;

            if (suite != null)
            {
                foreach (var methodCandidate in suite.Statements)
                {
                    FunctionDefinition funcDef = methodCandidate as FunctionDefinition;
                    if (funcDef != null)
                    {
                        if (funcDef.Name.EndsWith("_" + eventDescription.Name))
                        {
                            yield return(funcDef.Name);
                        }
                    }
                }
            }
        }
 private bool ShouldWalkWorker(SuiteStatement node)
 {
     if (ShouldWalkWorker((Node)node))
     {
         _suites.Add(node);
         foreach (var stmt in node.Statements)
         {
             stmt.Walk(this);
             if (_targetNode != null)
             {
                 // we have found our extracted code below this,
                 // we should insert before this statement.
                 _insertLocations[_parents[_parents.Count - 1]] = stmt.GetStartIncludingIndentation(_root);
                 break;
             }
         }
         _suites.Pop();
     }
     return(false);
 }
Пример #22
0
        private static string FindNodeInTree(PythonAst tree, SuiteStatement statement, int line)
        {
            if (statement != null)
            {
                foreach (var node in statement.Statements)
                {
                    FunctionDefinition funcDef = node as FunctionDefinition;
                    if (funcDef != null)
                    {
                        var span = funcDef.GetSpan(tree);
                        if (span.Start.Line <= line && line <= span.End.Line)
                        {
                            var res = FindNodeInTree(tree, funcDef.Body as SuiteStatement, line);
                            if (res != null)
                            {
                                return(funcDef.Name + "." + res);
                            }
                            return(funcDef.Name);
                        }
                        continue;
                    }

                    ClassDefinition classDef = node as ClassDefinition;
                    if (classDef != null)
                    {
                        var span = classDef.GetSpan(tree);
                        if (span.Start.Line <= line && line <= span.End.Line)
                        {
                            var res = FindNodeInTree(tree, classDef.Body as SuiteStatement, line);
                            if (res != null)
                            {
                                return(classDef.Name + "." + res);
                            }
                            return(classDef.Name);
                        }
                    }
                }
            }
            return(null);
        }
Пример #23
0
        internal static IEnumerable <IScopeNode> EnumerateBody(PythonAst ast, Statement body, bool includeAssignments = true)
        {
            SuiteStatement suite = body as SuiteStatement;

            if (suite != null)
            {
                foreach (Statement stmt in suite.Statements)
                {
                    ClassDefinition klass = stmt as ClassDefinition;
                    if (klass != null)
                    {
                        yield return(new ClassScopeNode(klass));

                        continue;
                    }

                    FunctionDefinition func = stmt as FunctionDefinition;
                    if (func != null)
                    {
                        yield return(new FunctionScopeNode(func));

                        continue;
                    }

                    AssignmentStatement assign;
                    if (includeAssignments && (assign = stmt as AssignmentStatement) != null)
                    {
                        foreach (var target in assign.Left)
                        {
                            NameExpression name = target as NameExpression;
                            if (name != null)
                            {
                                yield return(new AssignmentScopeNode(ast, assign, name));
                            }
                        }
                    }
                }
            }
        }
Пример #24
0
        private FunctionDefinition FindMethod(string methodName)
        {
            var            classDef = GetClassForEvents();
            SuiteStatement suite    = classDef.Body as SuiteStatement;

            if (suite != null)
            {
                foreach (var methodCandidate in suite.Statements)
                {
                    FunctionDefinition funcDef = methodCandidate as FunctionDefinition;
                    if (funcDef != null)
                    {
                        if (funcDef.Name == methodName)
                        {
                            return(funcDef);
                        }
                    }
                }
            }

            return(null);
        }
Пример #25
0
        internal static IEnumerable <IScopeNode> EnumerateBody(Statement body)
        {
            SuiteStatement suite = body as SuiteStatement;

            if (suite != null)
            {
                foreach (Statement stmt in suite.Statements)
                {
                    ClassDefinition klass = stmt as ClassDefinition;
                    if (klass != null)
                    {
                        yield return(new ClassScopeNode(klass));
                    }

                    FunctionDefinition func = stmt as FunctionDefinition;
                    if (func != null)
                    {
                        yield return(new FunctionScopeNode(func));
                    }
                }
            }
        }
Пример #26
0
        public DataType VisitSuite(SuiteStatement b)
        {
            // first pass: mark global names
            var globalNames = b.stmts
                              .OfType <GlobalStatement>()
                              .SelectMany(g => g.names)
                              .Concat(b.stmts
                                      .OfType <NonlocalStatement>()
                                      .SelectMany(g => g.names));

            foreach (var id in globalNames)
            {
                scope.AddGlobalName(id.Name);
                ISet <Binding> nb = scope.Lookup(id.Name);
                if (nb != null)
                {
                    analyzer.putRef(id, nb);
                }
            }

            bool     returned = false;
            DataType retType  = DataType.Unknown;

            foreach (var n in b.stmts)
            {
                DataType t = n.Accept(this);
                if (!returned)
                {
                    retType = UnionType.Union(retType, t);
                    if (!UnionType.Contains(t, DataType.Cont))
                    {
                        returned = true;
                        retType  = UnionType.remove(retType, DataType.Cont);
                    }
                }
            }
            return(retType);
        }
Пример #27
0
        public override bool IsExistingMethodName(EventDescription eventDescription, string methodName)
        {
            var            classDef = GetClassForEvents();
            var            view     = _pythonFileNode.GetTextView();
            SuiteStatement suite    = classDef.Body as SuiteStatement;

            if (suite != null)
            {
                foreach (var methodCandidate in suite.Statements)
                {
                    FunctionDefinition funcDef = methodCandidate as FunctionDefinition;
                    if (funcDef != null)
                    {
                        if (funcDef.Name == methodName)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Пример #28
0
        private void XlatConstructor(SuiteStatement stmt)
        {
            if (stmt == null)
                return;

            var comments = StatementTranslator.ConvertFirstStringToComments(stmt.stmts);
            stmt.Accept(this.stmtXlat);
            if (gen.Scope.Count == 0)
                return;
            gen.Scope[0].ToString();
            var expStm = gen.Scope[0] as CodeExpressionStatement;
            if (expStm == null)
                return;
            var appl = expStm.Expression as CodeApplicationExpression;
            if (appl == null)
                return;
            var method = appl.Method as CodeFieldReferenceExpression;
            if (method == null || method.FieldName != "__init__")
                return;
            var ctor = (CodeConstructor) gen.CurrentMethod;
            ctor.Comments.AddRange(comments);
            ctor.BaseConstructorArgs.AddRange(appl.Arguments.Skip(1));
            gen.Scope.RemoveAt(0);
        }
Пример #29
0
 // SuiteStatement
 public override bool Walk(SuiteStatement node) { return false; }
Пример #30
0
 public virtual void PostWalk(SuiteStatement node) { }
Пример #31
0
 // SuiteStatement
 public virtual bool Walk(SuiteStatement node) { return true; }
Пример #32
0
 public void VisitSuite(SuiteStatement s)
 {
     foreach (var stm in s.stmts)
     {
         stm.Accept(this);
         if (!(stm is SuiteStatement))
         {
             w.WriteLine();
         }
     }
 }
Пример #33
0
 // SuiteStatement
 public virtual bool Walk(SuiteStatement node)
 {
     return(true);
 }
Пример #34
0
        //if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
        public IfStatement if_stmt()
        {
            var posStart = Expect(TokenType.If).Start;
            var t = test();
            Expect(TokenType.COLON);
            var ts = suite();
            var stack = new Stack<Tuple<int, Exp, SuiteStatement>>();
            stack.Push(Tuple.Create(posStart, t, ts));
            Token token;
            while (PeekAndDiscard(TokenType.Elif, out token))
            {
                t = test();
                Expect(TokenType.COLON);
                ts = suite();
                stack.Push(Tuple.Create(token.Start, t, ts));
            }
            if (PeekAndDiscard(TokenType.Else, out token))
            {
                Expect(TokenType.COLON);
                ts = suite();
                stack.Push(new Tuple<int, Exp, SuiteStatement>(token.Start, null, ts));
            }

            SuiteStatement es = null;
            if (stack.Peek().Item2 == null)
            {
                es = stack.Pop().Item3;
            }
            IfStatement ifStmt;
            do
            {
                var item = stack.Pop();
                ifStmt = new IfStatement(
                    item.Item2, 
                    item.Item3,
                    es,
                    filename, item.Item1, item.Item3.End);
                es = new SuiteStatement(new List<Statement> { ifStmt }, filename, ifStmt.Start, ifStmt.End);
            } while (stack.Count > 0);
            return ifStmt;
        }
Пример #35
0
 public void VisitSuite(SuiteStatement s)
 {
     if (s.stmts.Count == 1)
     {
         s.stmts[0].Accept(this);
     }
     else
     {
         foreach (var stmt in s.stmts)
         {
             stmt.Accept(this);
         }
     }
 }
Пример #36
0
 // SuiteStatement
 public override bool Walk(SuiteStatement node) { return Location >= node.StartIndex && Location <= node.EndIndex; }
Пример #37
0
 public Module(string moduleName, SuiteStatement body, string filename, int begin, int end)
     : base(filename, begin, end)
 {
     this.Name = moduleName;
     this.body = body;
 }
Пример #38
0
 public override void PostWalk(SuiteStatement node) { }
Пример #39
0
 public virtual void PostWalk(SuiteStatement node)
 {
 }
Пример #40
0
 // SuiteStatement
 public override bool Walk(SuiteStatement node)
 {
     return(Location >= node.StartIndex && Location <= node.EndIndex);
 }
Пример #41
0
 private IfStatement GetElif(SuiteStatement s)
 {
     if (s.stmts.Count != 1)
         return null;
     return s.stmts[0] as IfStatement;
 }
Пример #42
0
        public ExtractMethodResult GetExtractionResult()
        {
            bool   isStaticMethod = false, isClassMethod = false;
            var    parameters = new List <Parameter>();
            string selfParam  = null;

            if (_targetScope is ClassDefinition)
            {
                var fromScope = _scopes[_scopes.Length - 1] as FunctionDefinition;
                Debug.Assert(fromScope != null);  // we don't allow extracting from classes, so we have to be coming from a function
                if (fromScope != null)
                {
                    if (fromScope.Decorators != null)
                    {
                        foreach (var decorator in fromScope.Decorators.Decorators)
                        {
                            NameExpression name = decorator as NameExpression;
                            if (name != null)
                            {
                                if (name.Name == "staticmethod")
                                {
                                    isStaticMethod = true;
                                }
                                else if (name.Name == "classmethod")
                                {
                                    isClassMethod = true;
                                }
                            }
                        }
                    }

                    if (!isStaticMethod)
                    {
                        if (fromScope.Parameters.Count > 0)
                        {
                            selfParam = fromScope.Parameters[0].Name;
                            parameters.Add(new Parameter(selfParam, ParameterKind.Normal));
                        }
                    }
                }
            }

            foreach (var param in _parameters)
            {
                var newParam = new Parameter(param, ParameterKind.Normal);
                if (parameters.Count > 0)
                {
                    newParam.AddPreceedingWhiteSpace(_ast, " ");
                }
                parameters.Add(newParam);
            }

            // include any non-closed over parameters as well...
            foreach (var input in _inputVars)
            {
                var variableScope = input.Scope;
                var parentScope   = _targetScope;

                // are these variables a child of the target scope so we can close over them?
                while (parentScope != null && parentScope != variableScope)
                {
                    parentScope = parentScope.Parent;
                }

                if (parentScope == null && input.Name != selfParam)
                {
                    // we can either close over or pass these in as parameters, add them to the list
                    var newParam = new Parameter(input.Name, ParameterKind.Normal);
                    if (parameters.Count > 0)
                    {
                        newParam.AddPreceedingWhiteSpace(_ast, " ");
                    }
                    parameters.Add(newParam);
                }
            }

            var body        = _target.GetBody(_ast);
            var isCoroutine = IsCoroutine(body);

            // reset leading indentation to single newline + indentation, this
            // strips out any proceeding comments which we don't extract
            var leading = _newline + body.GetIndentationLevel(_ast);

            body.SetLeadingWhiteSpace(_ast, leading);

            if (_outputVars.Count > 0)
            {
                // need to add a return statement
                Expression   retValue;
                Expression[] names       = new Expression[_outputVars.Count];
                int          outputIndex = 0;
                foreach (var name in _outputVars)
                {
                    var nameExpr = new NameExpression(name.Name);
                    nameExpr.AddPreceedingWhiteSpace(_ast, " ");
                    names[outputIndex++] = nameExpr;
                }
                var tuple = new TupleExpression(false, names);
                tuple.RoundTripHasNoParenthesis(_ast);
                retValue = tuple;

                var retStmt = new ReturnStatement(retValue);
                retStmt.SetLeadingWhiteSpace(_ast, leading);

                body = new SuiteStatement(
                    new Statement[] {
                    body,
                    retStmt
                }
                    );
            }
            else
            {
                // we need a SuiteStatement to give us our colon
                body = new SuiteStatement(new Statement[] { body });
            }

            DecoratorStatement decorators = null;

            if (isStaticMethod)
            {
                decorators = new DecoratorStatement(new[] { new NameExpression("staticmethod") });
            }
            else if (isClassMethod)
            {
                decorators = new DecoratorStatement(new[] { new NameExpression("classmethod") });
            }

            var res = new FunctionDefinition(new NameExpression(_name), parameters.ToArray(), body, decorators);

            res.IsCoroutine = isCoroutine;

            StringBuilder newCall = new StringBuilder();

            newCall.Append(_target.IndentationLevel);
            var method = res.ToCodeString(_ast);

            // fix up indentation...
            for (int curScope = 0; curScope < _scopes.Length; curScope++)
            {
                if (_scopes[curScope] == _targetScope)
                {
                    // this is our target indentation level.
                    var indentationLevel = _scopes[curScope].Body.GetIndentationLevel(_ast);
                    var lines            = method.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
                    int minWhiteSpace    = Int32.MaxValue;
                    for (int curLine = decorators == null ? 1 : 2; curLine < lines.Length; curLine++)
                    {
                        var line = lines[curLine];

                        for (int i = 0; i < line.Length; i++)
                        {
                            if (!Char.IsWhiteSpace(line[i]))
                            {
                                minWhiteSpace = Math.Min(minWhiteSpace, i);
                                break;
                            }
                        }
                    }

                    StringBuilder newLines = new StringBuilder();
                    newLines.Append(indentationLevel);
                    newLines.Append(lines[0]);
                    if (decorators != null)
                    {
                        newLines.Append(_newline);
                        newLines.Append(indentationLevel);
                        newLines.Append(lines[1]);
                    }

                    // don't include a bunch of blank lines...
                    int endLine = lines.Length - 1;
                    for (; endLine >= 0 && String.IsNullOrWhiteSpace(lines[endLine]); endLine--)
                    {
                    }

                    newLines.Append(_newline);
                    for (int curLine = decorators == null ? 1 : 2; curLine <= endLine; curLine++)
                    {
                        var line = lines[curLine];

                        newLines.Append(indentationLevel);
                        if (_insertTabs)
                        {
                            newLines.Append('\t');
                        }
                        else
                        {
                            newLines.Append(' ', _indentSize);
                        }

                        if (line.Length > minWhiteSpace)
                        {
                            newLines.Append(line, minWhiteSpace, line.Length - minWhiteSpace);
                        }
                        newLines.Append(_newline);
                    }
                    newLines.Append(_newline);
                    method = newLines.ToString();
                    break;
                }
            }

            string comma;

            if (_outputVars.Count > 0)
            {
                comma = "";
                foreach (var outputVar in _outputVars)
                {
                    newCall.Append(comma);
                    newCall.Append(outputVar.Name);
                    comma = ", ";
                }
                newCall.Append(" = ");
            }
            else if (_target.ContainsReturn)
            {
                newCall.Append("return ");
            }

            if (isCoroutine)
            {
                newCall.Append("await ");
            }

            if (_targetScope is ClassDefinition)
            {
                var fromScope = _scopes[_scopes.Length - 1] as FunctionDefinition;
                Debug.Assert(fromScope != null);  // we don't allow extracting from classes, so we have to be coming from a function

                if (isStaticMethod)
                {
                    newCall.Append(_targetScope.Name);
                    newCall.Append('.');
                }
                else if (fromScope != null && fromScope.Parameters.Count > 0)
                {
                    newCall.Append(fromScope.Parameters[0].Name);
                    newCall.Append('.');
                }
            }

            newCall.Append(_name);
            newCall.Append('(');

            comma = "";
            foreach (var param in parameters)
            {
                if (param.Name != selfParam)
                {
                    newCall.Append(comma);
                    newCall.Append(param.Name);
                    comma = ", ";
                }
            }

            newCall.Append(')');

            return(new ExtractMethodResult(
                       method,
                       newCall.ToString()
                       ));
        }
Пример #43
0
 protected void Xlat(SuiteStatement suite)
 {
     var comments = StatementTranslator.ConvertFirstStringToComments(suite.stmts);
     stmtXlat.Xlat(suite);
     gen.CurrentMethod.Comments.AddRange(comments);
 }