[Libreoffice-commits] core.git: Branch 'feature/gsoc-basic-ide-completion-and-other-bits' - basctl/source basic/source include/basic

Gergo Mocsi gmocsi91 at gmail.com
Sun Jul 7 10:52:33 PDT 2013


 basctl/source/basicide/baside2.hxx  |    4 -
 basctl/source/basicide/baside2b.cxx |  125 +++++++++++++++++++++++++-----------
 basic/source/classes/sbxmod.cxx     |    9 +-
 basic/source/comp/codegen.cxx       |   18 +++++
 basic/source/comp/parser.cxx        |    9 ++
 basic/source/inc/codegen.hxx        |    2 
 basic/source/inc/parser.hxx         |    5 +
 include/basic/sbmod.hxx             |   11 +++
 8 files changed, 143 insertions(+), 40 deletions(-)

New commits:
commit e83dd7cb1598b7567c3c4f5822c6132d8054d181
Author: Gergo Mocsi <gmocsi91 at gmail.com>
Date:   Sun Jul 7 19:43:05 2013 +0200

    GSOC work week 5, some recent fixes
    
    This week I've managed to fix the ListBox appearance. Also, I've modified the code: it gets the data on insert/remove/change, and gets updated only when the dot is pressed. This makes the data to be up-to-date. Next, I wrote a Split(OUString , char) function to do the nested reflection (It works, but it will need some tweaks later). Also, code generation is disabled for code completition (just a boolean value, maybe it could be done in a more "elegant" way, like the error supression).
    
    Change-Id: I43d250c0a065351950ac6424dcd88266d70bcef3

diff --git a/basctl/source/basicide/baside2.hxx b/basctl/source/basicide/baside2.hxx
index 179a223..e949a19 100644
--- a/basctl/source/basicide/baside2.hxx
+++ b/basctl/source/basicide/baside2.hxx
@@ -113,6 +113,8 @@ private:
     GetComponentInterface(sal_Bool bCreate = true);
     std::vector< CodeCompleteData > aCodeCompleteCache;
     CodeCompleteListBox* aListBox;
+    OUString GetActualSubName( sal_uLong nLine ); // gets the actual subroutine name according to line number
+    std::vector< OUString > Split( const OUString& sStr, const sal_Unicode& aChar );
 
 protected:
     virtual void    Paint( const Rectangle& );
@@ -471,11 +473,11 @@ class CodeCompleteListBox: public ListBox
 {
 private:
     EditorWindow* pParent; // parent window
-    DECL_LINK(ImplSelectHdl, void*);
 
 public:
     CodeCompleteListBox(EditorWindow* pPar);
     virtual ~CodeCompleteListBox();
+    DECL_LINK(ImplSelectHdl, void*);
 };
 
 } // namespace basctl
diff --git a/basctl/source/basicide/baside2b.cxx b/basctl/source/basicide/baside2b.cxx
index 1804888..e62bf60 100644
--- a/basctl/source/basicide/baside2b.cxx
+++ b/basctl/source/basicide/baside2b.cxx
@@ -480,6 +480,25 @@ bool EditorWindow::ImpCanModify()
     return bCanModify;
 }
 
+std::vector< OUString > EditorWindow::Split( const OUString& sStr, const sal_Unicode& aChar )
+{
+    std::vector< OUString > aRet;
+    OUString sTmp;
+    for( sal_Int32 i = 0; i < sStr.getLength(); ++i )
+    {
+        if( sStr[i] != aChar)
+            sTmp += OUString(sStr[i]);
+        else
+        {
+            aRet.push_back(sTmp);
+            sTmp = OUString("");
+        }
+    }
+    if(sTmp != OUString(""))
+        aRet.push_back(sTmp);
+    return aRet;
+}
+
 void EditorWindow::KeyInput( const KeyEvent& rKEvt )
 {
     SvtMiscOptions aMiscOptions;
@@ -496,44 +515,64 @@ void EditorWindow::KeyInput( const KeyEvent& rKEvt )
     bool const bWasModified = pEditEngine->IsModified();
     // see if there is an accelerator to be processed first
     bool bDone = SfxViewShell::Current()->KeyInput( rKEvt );
-    if( rKEvt.GetKeyCode().GetCode() == KEY_POINT && aMiscOptions.IsExperimentalMode())
+
+    if( rKEvt.GetKeyCode().GetCode() == KEY_POINT && aMiscOptions.IsExperimentalMode() )
     {
+        rModulWindow.UpdateModule();
         TextSelection aSel = GetEditView()->GetSelection();
         sal_uLong nLine =  aSel.GetStart().GetPara();
         OUString aLine( pEditEngine->GetText( nLine ) ); // the line being modified
-
-        OUString aStr = aLine.copy( std::max(aLine.lastIndexOf(" "), aLine.lastIndexOf("\t"))+1 );
-
-        for( unsigned int j = 0; j < aCodeCompleteCache.size(); ++j)
+        OUString aStr = aLine.copy( std::max(aLine.lastIndexOf(" "), aLine.lastIndexOf("\t"))+1 ); // variable name
+        OUString sActSub = GetActualSubName( nLine );
+        std::vector< OUString > aVect = Split( aStr, '.' );
+        OUString sBaseName = aVect[0];
+        for( unsigned int i = 0; i < aCodeCompleteCache.size(); ++i)
         {
-            if( aCodeCompleteCache[j].sVarName == aStr )
+            if( aCodeCompleteCache[i].sVarName.equalsIgnoreAsciiCase( sBaseName ) &&
+                ( aCodeCompleteCache[i].sVarParent == sActSub || aCodeCompleteCache[i].IsGlobal() ) )
             {
                 Reference< lang::XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory(), UNO_SET_THROW );
                 Reference< reflection::XIdlReflection > xRefl( xFactory->createInstance("com.sun.star.reflection.CoreReflection"), UNO_QUERY_THROW );
+
                 if( xRefl.is() )
                 {
-                    Reference< reflection::XIdlClass > xClass = xRefl->forName(aCodeCompleteCache[j].sVarType);
-                    if( xClass != NULL  )
+                    Reference< reflection::XIdlClass > xClass = xRefl->forName(aCodeCompleteCache[i].sVarType);//get the base class for reflection
+                    if( xClass != NULL )
                     {
+                        unsigned int j = 1;
+                        OUString sMethName;
+                        while( j != aVect.size() )
+                        {
+                            sMethName = aVect[j];
+                            Reference< reflection::XIdlMethod> xMethod = xClass->getMethod( sMethName );
+                            if( xMethod != NULL ) //method OK
+                            {
+                                xClass = xMethod->getReturnType();
+                                if( xClass == NULL )
+                                    break;
+                            }
+                            else
+                            {
+                                break;
+                            }
+                            j++;
+                        }
                         Sequence< Reference< reflection::XIdlMethod > > aMethods = xClass->getMethods();
-                        aListBox->Clear();
+                        if( aMethods.getLength() != 0 )
+                        {
+                            Rectangle aRect = ( (TextEngine*) GetEditEngine() )->PaMtoEditCursor( aSel.GetEnd() , false );
+                            aListBox->SetPosPixel( aRect.TopLeft() );
+                            aListBox->SetSizePixel( Size(150,150) );
 
-                        Rectangle aRect = ( (TextEngine*) GetEditEngine() )->PaMtoEditCursor(aSel.GetEnd() , false);
-                        aListBox->SetPosPixel( aRect.TopLeft() );
-                        aListBox->SetSizePixel( Size(150,150) );
+                            for(sal_Int32 l = 0; l < aMethods.getLength(); ++l)
+                            {
+                                aListBox->InsertEntry( OUString(aMethods[l]->getName()) );
+                                std::cerr << aMethods[l]->getName() << std::endl;
+                            }
 
-                        for(sal_Int32 i = 0; i < aMethods.getLength(); ++i)
-                        {
-                            aListBox->InsertEntry( OUString(aMethods[i]->getName()) );
-                            SAL_WARN("method information", aMethods[i]->getName());
+                            aListBox->GetFocus();
+                            aListBox->ToggleDropDown();
                         }
-
-                        aListBox->GetFocus();
-                        aListBox->ToggleDropDown();
-                    }
-                    else
-                    {
-                        SAL_WARN("Type does not exist", aCodeCompleteCache[j].sVarType);
                     }
                 }
                 break;
@@ -799,26 +838,17 @@ void EditorWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
         {
             ParagraphInsertedDeleted( rTextHint.GetValue(), true );
             DoDelayedSyntaxHighlight( rTextHint.GetValue() );
-            OUString sMod = rModulWindow.GetSbModule()->GetSource();
-            OUString sActLine = pEditEngine->GetText( rTextHint.GetValue() );
-            std::vector< CodeCompleteData > aData = rModulWindow.GetSbModule()->GetCodeCompleteDataFromParse();
-            aCodeCompleteCache = aData;
+            rModulWindow.UpdateModule();
+            aCodeCompleteCache = rModulWindow.GetSbModule()->GetCodeCompleteDataFromParse();
         }
         else if( rTextHint.GetId() == TEXT_HINT_PARAREMOVED )
         {
             ParagraphInsertedDeleted( rTextHint.GetValue(), false );
-            OUString sMod = rModulWindow.GetSbModule()->GetSource();
-            OUString sActLine = pEditEngine->GetText( rTextHint.GetValue() );
-            std::vector< CodeCompleteData > aData = rModulWindow.GetSbModule()->GetCodeCompleteDataFromParse();
-            aCodeCompleteCache = aData;
+            aCodeCompleteCache = rModulWindow.GetSbModule()->GetCodeCompleteDataFromParse();
         }
         else if( rTextHint.GetId() == TEXT_HINT_PARACONTENTCHANGED )
         {
             DoDelayedSyntaxHighlight( rTextHint.GetValue() );
-            OUString sMod = rModulWindow.GetSbModule()->GetSource();
-            OUString sActLine = pEditEngine->GetText( rTextHint.GetValue() );
-            std::vector< CodeCompleteData > aData = rModulWindow.GetSbModule()->GetCodeCompleteDataFromParse();
-            aCodeCompleteCache = aData;
         }
         else if( rTextHint.GetId() == TEXT_HINT_VIEWSELECTIONCHANGED )
         {
@@ -828,7 +858,32 @@ void EditorWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
                 pBindings->Invalidate( SID_COPY );
             }
         }
+        else if( rTextHint.GetId() == TEXT_HINT_MODIFIED )
+        {
+            aCodeCompleteCache = rModulWindow.GetSbModule()->GetCodeCompleteDataFromParse();
+        }
+    }
+}
+
+OUString EditorWindow::GetActualSubName( sal_uLong nLine )
+{
+    SbxArrayRef pMethods = rModulWindow.GetSbModule()->GetMethods();
+    for( sal_uInt16 i=0; i < pMethods->Count(); i++ )
+    {
+        SbxVariable* p = PTR_CAST( SbMethod, pMethods->Get( i ) );
+        OUString sName = p->GetName();
+        SbMethod* pMeth = p ? PTR_CAST( SbMethod, p ) : NULL;
+        if( pMeth )
+        {
+            sal_uInt16 l1,l2;
+            pMeth->GetLineRange(l1,l2);
+            if( (l1 <= nLine+1) && (nLine+1 <= l2) )
+            {
+                return sName;
+            }
+        }
     }
+    return OUString("");
 }
 
 void EditorWindow::SetScrollBarRanges()
diff --git a/basic/source/classes/sbxmod.cxx b/basic/source/classes/sbxmod.cxx
index c5608a8..7f85be2 100644
--- a/basic/source/classes/sbxmod.cxx
+++ b/basic/source/classes/sbxmod.cxx
@@ -1781,12 +1781,10 @@ IMPL_LINK( ErrorHdlResetter, BasicErrorHdl, StarBASIC *, /*pBasic*/)
 std::vector< CodeCompleteData > SbModule::GetCodeCompleteDataFromParse()
 {
     ErrorHdlResetter aErrHdl;
-    StarBASIC* pBasic = PTR_CAST(StarBASIC,GetParent());
     SbxBase::ResetError();
-    SbModule* pOld = GetSbData()->pCompMod;
-    GetSbData()->pCompMod = this;
 
     SbiParser* pParser = new SbiParser( (StarBASIC*) GetParent(), this );
+    pParser->SetCodeCompleting(true);
 
     while( pParser->Parse() ) {}
     SbiSymPool* pPool = pParser->pPool;
@@ -1823,6 +1821,11 @@ std::vector< CodeCompleteData > SbModule::GetCodeCompleteDataFromParse()
     return aRet;
 }
 
+SbxArrayRef SbModule::GetMethods()
+{
+    return pMethods;
+}
+
 bool SbModule::HasExeCode()
 {
     // And empty Image always has the Global Chain set up
diff --git a/basic/source/comp/codegen.cxx b/basic/source/comp/codegen.cxx
index 32b1d84..abbbce9 100644
--- a/basic/source/comp/codegen.cxx
+++ b/basic/source/comp/codegen.cxx
@@ -46,6 +46,9 @@ sal_uInt32 SbiCodeGen::GetPC()
 
 void SbiCodeGen::Statement()
 {
+    if( aMiscOptions.IsExperimentalMode() && pParser->IsCodeCompleting() )
+        return;
+
     bStmnt = true;
 
     nLine = pParser->GetLine();
@@ -60,6 +63,9 @@ void SbiCodeGen::Statement()
 
 void SbiCodeGen::GenStmnt()
 {
+    if( aMiscOptions.IsExperimentalMode() && pParser->IsCodeCompleting() )
+        return;
+
     if( bStmnt )
     {
         bStmnt = false;
@@ -72,6 +78,9 @@ void SbiCodeGen::GenStmnt()
 
 sal_uInt32 SbiCodeGen::Gen( SbiOpcode eOpcode )
 {
+    if( aMiscOptions.IsExperimentalMode() && pParser->IsCodeCompleting() )
+        return 0;
+
 #ifdef DBG_UTIL
     if( eOpcode < SbOP0_START || eOpcode > SbOP0_END )
         pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE1" );
@@ -83,6 +92,9 @@ sal_uInt32 SbiCodeGen::Gen( SbiOpcode eOpcode )
 
 sal_uInt32 SbiCodeGen::Gen( SbiOpcode eOpcode, sal_uInt32 nOpnd )
 {
+    if( aMiscOptions.IsExperimentalMode() && pParser->IsCodeCompleting() )
+        return 0;
+
 #ifdef DBG_UTIL
     if( eOpcode < SbOP1_START || eOpcode > SbOP1_END )
         pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE2" );
@@ -96,6 +108,9 @@ sal_uInt32 SbiCodeGen::Gen( SbiOpcode eOpcode, sal_uInt32 nOpnd )
 
 sal_uInt32 SbiCodeGen::Gen( SbiOpcode eOpcode, sal_uInt32 nOpnd1, sal_uInt32 nOpnd2 )
 {
+    if( aMiscOptions.IsExperimentalMode() && pParser->IsCodeCompleting() )
+        return 0;
+
 #ifdef DBG_UTIL
     if( eOpcode < SbOP2_START || eOpcode > SbOP2_END )
         pParser->Error( SbERR_INTERNAL_ERROR, "OPCODE3" );
@@ -112,6 +127,9 @@ sal_uInt32 SbiCodeGen::Gen( SbiOpcode eOpcode, sal_uInt32 nOpnd1, sal_uInt32 nOp
 
 void SbiCodeGen::Save()
 {
+    if( aMiscOptions.IsExperimentalMode() && pParser->IsCodeCompleting() )
+        return;
+
     SbiImage* p = new SbiImage;
     rMod.StartDefinitions();
     // OPTION BASE-Value:
diff --git a/basic/source/comp/parser.cxx b/basic/source/comp/parser.cxx
index 80d0523..348b908 100644
--- a/basic/source/comp/parser.cxx
+++ b/basic/source/comp/parser.cxx
@@ -133,6 +133,7 @@ SbiParser::SbiParser( StarBASIC* pb, SbModule* pm )
     bGblDefs =
     bNewGblDefs =
     bSingleLineIf =
+    bCodeCompleting =
     bExplicit = false;
     bClassModule = ( pm->GetModuleType() == com::sun::star::script::ModuleType::CLASS );
     OSL_TRACE("Parser - %s, bClassModule %d", OUStringToOString( pm->GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), bClassModule );
@@ -314,7 +315,15 @@ void SbiParser::StmntBlock( SbiToken eEnd )
     }
 }
 
+void SbiParser::SetCodeCompleting( const bool& b )
+{
+    bCodeCompleting = b;
+}
 
+bool SbiParser::IsCodeCompleting() const
+{
+    return bCodeCompleting;
+}
 
 bool SbiParser::Parse()
 {
diff --git a/basic/source/inc/codegen.hxx b/basic/source/inc/codegen.hxx
index 246ff16..3cdd27c 100644
--- a/basic/source/inc/codegen.hxx
+++ b/basic/source/inc/codegen.hxx
@@ -24,6 +24,7 @@ class SbiParser;
 class SbModule;
 #include "opcodes.hxx"
 #include "buffer.hxx"
+#include <svtools/miscopt.hxx>
 
 class SbiCodeGen {
     SbiParser* pParser;         // for error messages, line, column etc.
@@ -32,6 +33,7 @@ class SbiCodeGen {
     short  nLine, nCol;         // for stmnt command
     short  nForLevel;           // #29955
     bool bStmnt;            // true: statement-opcode is pending
+    SvtMiscOptions aMiscOptions;
 public:
     SbiCodeGen( SbModule&, SbiParser*, short );
     SbiParser* GetParser() { return pParser; }
diff --git a/basic/source/inc/parser.hxx b/basic/source/inc/parser.hxx
index 0ab6bcb..a6f3751 100644
--- a/basic/source/inc/parser.hxx
+++ b/basic/source/inc/parser.hxx
@@ -42,6 +42,7 @@ class SbiParser : public SbiTokenizer
     bool        bGblDefs;           // true: global definitions general
     bool        bNewGblDefs;        // true: globale definitions before sub
     bool        bSingleLineIf;
+    bool        bCodeCompleting;
 
     SbiSymDef*  VarDecl( SbiDimList**, bool, bool );
     SbiProcDef* ProcDecl(bool bDecl);
@@ -57,7 +58,7 @@ class SbiParser : public SbiTokenizer
     void DefEnum( bool bPrivate );  // Parse enum declaration
     void DefDeclare( bool bPrivate );
     void EnableCompatibility();
-    bool IsUnoInterface(const OUString& sTypeName);
+    bool IsUnoInterface( const OUString& sTypeName );
 public:
     SbxArrayRef   rTypeArray;
     SbxArrayRef   rEnumArray;
@@ -80,6 +81,8 @@ public:
 
     SbiParser( StarBASIC*, SbModule* );
     bool Parse();
+    void SetCodeCompleting( const bool& b );
+    bool IsCodeCompleting() const;
     SbiExprNode* GetWithVar();
 
     // from 31.3.1996, search symbol in the runtime-library
diff --git a/include/basic/sbmod.hxx b/include/basic/sbmod.hxx
index 4463977..65dab93 100644
--- a/include/basic/sbmod.hxx
+++ b/include/basic/sbmod.hxx
@@ -49,6 +49,16 @@ struct CodeCompleteData
     OUString sVarName;
     OUString sVarParent;
     OUString sVarType;
+
+    inline bool operator==( const CodeCompleteData& aOther )
+    {
+        return (sVarName == aOther.sVarName && sVarParent == aOther.sVarParent);
+    }
+
+    inline bool IsGlobal() const
+    {
+        return ( sVarParent == OUString("") );
+    }
 };
 
 class BASIC_DLLPUBLIC SbModule : public SbxObject, private ::boost::noncopyable
@@ -141,6 +151,7 @@ public:
     ::com::sun::star::uno::Reference< ::com::sun::star::script::XInvocation > GetUnoModule();
     bool createCOMWrapperForIface( ::com::sun::star::uno::Any& o_rRetAny, SbClassModuleObject* pProxyClassModuleObject );
     std::vector< CodeCompleteData > GetCodeCompleteDataFromParse();
+    SbxArrayRef GetMethods();
 };
 
 SV_DECL_IMPL_REF(SbModule)


More information about the Libreoffice-commits mailing list