Patch #3375 2012-11-22 03:43

alpha0010

CC: handle local scope
Download
3375-CC_handle_loca.patch (4.5 KB)
Category
Plugin::Refinement
Status
Accepted
Close date
2012-11-23 08:45
Assigned to
mortenmacfly
Index: src/plugins/codecompletion/nativeparser.cpp
===================================================================
--- src/plugins/codecompletion/nativeparser.cpp    (revision 8587)
+++ src/plugins/codecompletion/nativeparser.cpp    (working copy)
@@ -1841,15 +1841,16 @@
     if (blockStart != -1)
     {
         ++blockStart; // skip {
-        const int pos      = (caretPos == -1 ? searchData->control->GetCurrentPos() : caretPos);
-        const int line     = searchData->control->LineFromPosition(pos);
-        const int blockEnd = searchData->control->GetLineEndPosition(line);
-        if (blockEnd < 0 || blockEnd > searchData->control->GetLength())
+        cbStyledTextCtrl* stc = searchData->control;
+        const int pos      = (caretPos == -1 ? stc->GetCurrentPos() : caretPos);
+        const int line     = stc->LineFromPosition(pos);
+        const int blockEnd = stc->GetLineEndPosition(line);
+        if (blockEnd < 0 || blockEnd > stc->GetLength())
         {
             if (s_DebugSmartSense)
             {
                 CCLogger::Get()->DebugLog(F(_T("ParseLocalBlock() ERROR blockEnd=%d and edLength=%d?!"),
-                                            blockEnd, searchData->control->GetLength()));
+                                            blockEnd, stc->GetLength()));
             }
             return false;
         }
@@ -1857,7 +1858,69 @@
         if (blockStart >= blockEnd)
             blockStart = blockEnd;
 
-        wxString buffer = searchData->control->GetTextRange(blockStart, blockEnd);
+        wxString buffer; // = searchData->control->GetTextRange(blockStart, blockEnd);
+        // condense out-of-scope braces {...}
+        int scanPos = blockEnd;
+        for (int curPos = pos; curPos > blockStart; --curPos)
+        {
+            if (stc->GetCharAt(curPos) != wxT('}'))
+                continue;
+            const int style = stc->GetStyleAt(curPos);
+            if (   stc->IsString(style)
+                || stc->IsCharacter(style)
+                || stc->IsComment(style))
+            {
+                continue;
+            }
+            const int scopeStart = stc->BraceMatch(curPos);
+            if (scopeStart < blockStart)
+                break;
+            buffer.Prepend(stc->GetTextRange(curPos, scanPos));
+            int startLn = stc->LineFromPosition(scopeStart);
+            int endLn   = stc->LineFromPosition(curPos);
+            if (startLn < endLn) // maintain correct line numbers for parsed tokens
+                buffer.Prepend( wxString(wxT('\n'), endLn - startLn) );
+            scanPos = scopeStart + 1;
+            curPos  = scopeStart;
+
+            // condense out-of-scope for/if/while declarations
+            int prevCharIdx = scopeStart - 1;
+            for (; prevCharIdx > blockStart; --prevCharIdx)
+            {
+                if (stc->IsComment(stc->GetStyleAt(prevCharIdx)))
+                    continue;
+                if (!wxIsspace(stc->GetCharAt(prevCharIdx)))
+                    break;
+            }
+            if (stc->GetCharAt(prevCharIdx) != wxT(')'))
+                continue;
+            const int paramStart = stc->BraceMatch(prevCharIdx);
+            if (paramStart < blockStart)
+                continue;
+            for (prevCharIdx = paramStart - 1; prevCharIdx > blockStart; --prevCharIdx)
+            {
+                if (stc->IsComment(stc->GetStyleAt(prevCharIdx)))
+                    continue;
+                if (!wxIsspace(stc->GetCharAt(prevCharIdx)))
+                    break;
+            }
+            const wxString text = stc->GetTextRange(stc->WordStartPosition(prevCharIdx, true),
+                                                    stc->WordEndPosition(  prevCharIdx, true));
+            if (text == wxT("for"))
+                buffer.Prepend(wxT("(;;){"));
+            else if (text == wxT("if") || text == wxT("while"))
+                buffer.Prepend(wxT("(0){"));
+            else
+                continue;
+            startLn = stc->LineFromPosition(prevCharIdx);
+            endLn   = stc->LineFromPosition(scopeStart);
+            if (startLn < endLn)
+                buffer.Prepend( wxString(wxT('\n'), endLn - startLn) );
+            curPos  = stc->WordStartPosition(prevCharIdx, true);
+            scanPos = stc->WordEndPosition(  prevCharIdx, true);
+        }
+        buffer.Prepend(stc->GetTextRange(blockStart, scanPos));
+
         buffer.Trim();
         if (   !buffer.IsEmpty()
             && !m_Parser->ParseBuffer(buffer, false, false, true, searchData->file, m_LastFuncTokenIdx, initLine) )