1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <basic/codecompletecache.hxx>
21 #include <iostream>
22 #include <rtl/instance.hxx>
23 #include <officecfg/Office/BasicIDE.hxx>
24 
25 namespace
26 {
27     class theCodeCompleteOptions: public ::rtl::Static< CodeCompleteOptions, theCodeCompleteOptions >{};
28 }
29 
30 CodeCompleteOptions::CodeCompleteOptions()
31 {
32     bIsAutoCorrectOn = officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::get();
33     bIsAutoCloseParenthesisOn = officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::get();
34     bIsAutoCloseQuotesOn = officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::get();
35     bIsProcedureAutoCompleteOn = officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::get();
36     bIsCodeCompleteOn = officecfg::Office::BasicIDE::Autocomplete::CodeComplete::get();
37     bExtendedTypeDeclarationOn = officecfg::Office::BasicIDE::Autocomplete::UseExtended::get();
38 }
39 
40 bool CodeCompleteOptions::IsCodeCompleteOn()
41 {
42     return theCodeCompleteOptions::get().aMiscOptions.IsExperimentalMode() && theCodeCompleteOptions::get().bIsCodeCompleteOn;
43 }
44 
45 void CodeCompleteOptions::SetCodeCompleteOn( bool b )
46 {
47     theCodeCompleteOptions::get().bIsCodeCompleteOn = b;
48 }
49 
50 bool CodeCompleteOptions::IsExtendedTypeDeclaration()
51 {
52     return theCodeCompleteOptions::get().aMiscOptions.IsExperimentalMode() && theCodeCompleteOptions::get().bExtendedTypeDeclarationOn;
53 }
54 
55 void CodeCompleteOptions::SetExtendedTypeDeclaration( bool b )
56 {
57     theCodeCompleteOptions::get().bExtendedTypeDeclarationOn = b;
58 }
59 
60 bool CodeCompleteOptions::IsProcedureAutoCompleteOn()
61 {
62     return theCodeCompleteOptions::get().aMiscOptions.IsExperimentalMode() && theCodeCompleteOptions::get().bIsProcedureAutoCompleteOn;
63 }
64 
65 void CodeCompleteOptions::SetProcedureAutoCompleteOn( bool b )
66 {
67     theCodeCompleteOptions::get().bIsProcedureAutoCompleteOn = b;
68 }
69 
70 bool CodeCompleteOptions::IsAutoCloseQuotesOn()
71 {
72     return theCodeCompleteOptions::get().aMiscOptions.IsExperimentalMode() && theCodeCompleteOptions::get().bIsAutoCloseQuotesOn;
73 }
74 
75 void CodeCompleteOptions::SetAutoCloseQuotesOn( bool b )
76 {
77     theCodeCompleteOptions::get().bIsAutoCloseQuotesOn = b;
78 }
79 
80 bool CodeCompleteOptions::IsAutoCloseParenthesisOn()
81 {
82     return theCodeCompleteOptions::get().aMiscOptions.IsExperimentalMode() && theCodeCompleteOptions::get().bIsAutoCloseParenthesisOn;
83 }
84 
85 void CodeCompleteOptions::SetAutoCloseParenthesisOn( bool b )
86 {
87     theCodeCompleteOptions::get().bIsAutoCloseParenthesisOn = b;
88 }
89 
90 bool CodeCompleteOptions::IsAutoCorrectOn()
91 {
92     return theCodeCompleteOptions::get().aMiscOptions.IsExperimentalMode() && theCodeCompleteOptions::get().bIsAutoCorrectOn;
93 }
94 
95 void CodeCompleteOptions::SetAutoCorrectOn( bool b )
96 {
97     theCodeCompleteOptions::get().bIsAutoCorrectOn = b;
98 }
99 
100 std::ostream& operator<< (std::ostream& aStream, const CodeCompleteDataCache& aCache)
101 {
102     aStream << "Global variables" << std::endl;
103     for (auto const& globalVar : aCache.aGlobalVars)
104     {
105         aStream << globalVar.first << "," << globalVar.second << std::endl;
106     }
107     aStream << "Local variables" << std::endl;
108     for (auto const& varScope : aCache.aVarScopes)
109     {
110         aStream << varScope.first << std::endl;
111         CodeCompleteVarTypes aVarTypes = varScope.second;
112         for (auto const& varType : aVarTypes)
113         {
114             aStream << "\t" << varType.first << "," << varType.second << std::endl;
115         }
116     }
117     aStream << "-----------------" << std::endl;
118     return aStream;
119 }
120 
121 void CodeCompleteDataCache::Clear()
122 {
123     aVarScopes.clear();
124     aGlobalVars.clear();
125 }
126 
127 void CodeCompleteDataCache::InsertGlobalVar( const OUString& sVarName, const OUString& sVarType )
128 {
129     aGlobalVars.emplace( sVarName, sVarType );
130 }
131 
132 void CodeCompleteDataCache::InsertLocalVar( const OUString& sProcName, const OUString& sVarName, const OUString& sVarType )
133 {
134     CodeCompleteVarScopes::const_iterator aIt = aVarScopes.find( sProcName );
135     if( aIt == aVarScopes.end() ) //new procedure
136     {
137         CodeCompleteVarTypes aTypes;
138         aTypes.emplace( sVarName, sVarType );
139         aVarScopes.emplace( sProcName, aTypes );
140     }
141     else
142     {
143         CodeCompleteVarTypes aTypes = aVarScopes[ sProcName ];
144         aTypes.emplace( sVarName, sVarType );
145         aVarScopes[ sProcName ] = aTypes;
146     }
147 }
148 
149 OUString CodeCompleteDataCache::GetVarType( const OUString& sVarName ) const
150 {
151     for (auto const& varScope : aVarScopes)
152     {
153         CodeCompleteVarTypes aTypes = varScope.second;
154         for (auto const& elem : aTypes)
155         {
156             if( elem.first.equalsIgnoreAsciiCase( sVarName ) )
157             {
158                 return elem.second;
159             }
160         }
161     }
162     //not a local, search global scope
163     for (auto const& globalVar : aGlobalVars)
164     {
165         if( globalVar.first.equalsIgnoreAsciiCase( sVarName ) )
166             return globalVar.second;
167     }
168     return OUString(); //not found
169 }
170 
171 OUString CodeCompleteDataCache::GetCorrectCaseVarName( const OUString& sVarName, const OUString& sActProcName ) const
172 {
173     for (auto const& varScope : aVarScopes)
174     {
175         CodeCompleteVarTypes aTypes = varScope.second;
176         for (auto const& elem : aTypes)
177         {
178             if( elem.first.equalsIgnoreAsciiCase( sVarName ) && varScope.first.equalsIgnoreAsciiCase( sActProcName ) )
179             {
180                 return elem.first;
181             }
182         }
183     }
184     // search global scope
185     for (auto const& globalVar : aGlobalVars)
186     {
187         if( globalVar.first.equalsIgnoreAsciiCase( sVarName ) )
188             return globalVar.first;
189     }
190     return OUString(); //not found
191 }
192 
193 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
194