Warning, file /kdevelop/kdevelop/plugins/astyle/astyle_plugin.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2008 Cédric Pasteur <cedric.pasteur@free.fr> 0003 SPDX-FileCopyrightText: 2001 Matthias Hölzer-Klüpfel <mhk@caldera.de> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "astyle_plugin.h" 0009 0010 #include <KPluginFactory> 0011 0012 #include "astyle_formatter.h" 0013 #include "astyle_stringiterator.h" 0014 #include "astyle_preferences.h" 0015 #include <KLocalizedString> 0016 0017 #include <QMimeType> 0018 #include <QUrl> 0019 0020 namespace { 0021 0022 QString formattingCppSample() 0023 { 0024 return QStringLiteral( 0025 "void func(){\n" 0026 "\tif(isFoo(a,b))\n" 0027 "\tbar(a,b);\n" 0028 "if(isFoo)\n" 0029 "\ta=bar((b-c)*a,*d--);\n" 0030 "if( isFoo( a,b ) )\n" 0031 "\tbar(a, b);\n" 0032 "if (isFoo) {isFoo=false;cat << isFoo <<endl;}\n" 0033 "if(isFoo)DoBar();if (isFoo){\n" 0034 "\tbar();\n" 0035 "}\n" 0036 "\telse if(isBar()){\n" 0037 "\tannotherBar();\n" 0038 "}\n" 0039 "int var = 1;\n" 0040 "int *ptr = &var;\n" 0041 "int& ref = i;\n" 0042 "\n" 0043 "QList<int>::const_iterator it = list.begin();\n" 0044 "}\n" 0045 "namespace A {\n" 0046 "namespace B {\n" 0047 "class someClass {\n" 0048 "void foo() {\n" 0049 " if (true) {\n" 0050 " func();\n" 0051 " } else {\n" 0052 " // bla\n" 0053 " }\n" 0054 "}\n" 0055 "};\n" 0056 "}\n" 0057 "}\n"); 0058 } 0059 0060 QString formattingObjCSample() 0061 { 0062 return QStringLiteral( 0063 "void func(){\n" 0064 "\tif(isFoo(a,b))\n" 0065 "\tbar(a,b);\n" 0066 "if(isFoo)\n" 0067 "\ta=bar((b-c)*a,*d--);\n" 0068 "if( isFoo( a,b ) )\n" 0069 "\tbar(a, b);\n" 0070 "if (isFoo) {isFoo=false;cat << isFoo <<endl;}\n" 0071 "if(isFoo)DoBar();if (isFoo){\n" 0072 "\tbar();\n" 0073 "}\n" 0074 "\telse if(isBar()){\n" 0075 "\tannotherBar();\n" 0076 "}\n" 0077 "int var = 1;\n" 0078 "int *ptr = &var;\n" 0079 "\n" 0080 "}\n" 0081 "@implementation someClass \n" 0082 "+ (someClass*) someClassWithFoo:(int)foo\n" 0083 "{\n" 0084 " someClass *this;\n" 0085 " if (foo) {\n" 0086 " this = [[someClass alloc] initWith:foo];\n" 0087 " } else {\n" 0088 " // bla\n" 0089 " }\n" 0090 " return self;\n" 0091 "}\n" 0092 "@end\n"); 0093 } 0094 0095 QString indentingCppSample() 0096 { 0097 return QStringLiteral( 0098 "#define foobar(A)\\\n" 0099 "{Foo();Bar();}\n" 0100 "#define anotherFoo(B)\\\n" 0101 "return Bar()\n" 0102 "\n" 0103 "namespace Bar\n" 0104 "{\n" 0105 "class Foo\n" 0106 "{public:\n" 0107 "Foo();\n" 0108 "virtual ~Foo();\n" 0109 "};\n" 0110 "void bar(int foo)\n" 0111 "{\n" 0112 "switch (foo)\n" 0113 "{\n" 0114 "case 1:\n" 0115 "a+=1;\n" 0116 "break;\n" 0117 "case 2:\n" 0118 "{\n" 0119 "a += 2;\n" 0120 " break;\n" 0121 "}\n" 0122 "}\n" 0123 "if (isFoo)\n" 0124 "{\n" 0125 "bar();\n" 0126 "}\n" 0127 "else\n" 0128 "{\n" 0129 "anotherBar();\n" 0130 "}\n" 0131 "}\n" 0132 "int foo()\n" 0133 "\twhile(isFoo)\n" 0134 "\t\t{\n" 0135 "\t\t\t// ...\n" 0136 "\t\t\tgoto error;\n" 0137 "\t\t/* .... */\n" 0138 "\t\terror:\n" 0139 "\t\t\t//...\n" 0140 "\t\t}\n" 0141 "\t}\n" 0142 "fooArray[]={ red,\n" 0143 "\tgreen,\n" 0144 "\tdarkblue};\n" 0145 "fooFunction(barArg1,\n" 0146 "\tbarArg2,\n" 0147 "\tbarArg3);\n" 0148 "struct foo{ int bar() {} };\n"); 0149 } 0150 0151 QString indentingObjCSample() 0152 { 0153 return QStringLiteral( 0154 "#import <objc/Object.h>\n" 0155 "\n" 0156 "#define foobar(A)\\\n" 0157 "\t{Foo();Bar();}\n" 0158 "#define anotherFoo(B)\\\n" 0159 "\treturn Bar()\n" 0160 "\n" 0161 "@interface Foo : Bar {\n" 0162 "@private\n" 0163 "\tid Baz;\n" 0164 "}\n" 0165 "- (void) init;\n" 0166 "- (NSString*) description;\n" 0167 "@property (retain) id Baz;\n" 0168 "@end\n" 0169 "\n" 0170 "@interface Foo (Bar)\n" 0171 "- (void)bar:(int) foo;\n" 0172 "@end\n" 0173 "\n" 0174 "@implementation Foo (Bar)\n" 0175 "\n" 0176 "- (void) bar:(int) foo\n" 0177 "{\n" 0178 "\tswitch (foo) {\n" 0179 "case 1:\n" 0180 "a += 1;\n" 0181 "break;\n" 0182 "case 2: {\n" 0183 "a += 2;\n" 0184 "break;\n" 0185 "}\n" 0186 "}\n" 0187 "if (isFoo) {\n" 0188 "bar();\n" 0189 "} else {\n" 0190 "[anotherBar withFoo:self];\n" 0191 "}\n" 0192 "}\n" 0193 "\n" 0194 "@end\n" 0195 "int foo()\n" 0196 "while (isFoo)\n" 0197 "{\n" 0198 "\t// ...\n" 0199 "\tgoto error;\n" 0200 "\t/* .... */\n" 0201 "error:\n" 0202 "\t//...\n" 0203 "}\n" 0204 "\n" 0205 "fooArray[] = { red,\n" 0206 "\tgreen,\n" 0207 "\tdarkblue};\n" 0208 "fooFunction(barArg1,\n" 0209 "\tbarArg2,\n" 0210 "\tbarArg3);\n" 0211 "struct foo { int bar() {} };\n"); 0212 } 0213 0214 QString previewText(const QString& indentingSample, const QString& formattingSample) 0215 { 0216 return QLatin1String("// Indentation\n") + indentingSample + QLatin1String("\t// Formatting\n") + formattingSample; 0217 } 0218 0219 } // unnamed namespace 0220 0221 using namespace KDevelop; 0222 0223 K_PLUGIN_FACTORY_WITH_JSON(AStyleFactory, "kdevastyle.json", registerPlugin<AStylePlugin>();) 0224 0225 AStylePlugin::AStylePlugin(QObject *parent, const QVariantList&) 0226 : IPlugin(QStringLiteral("kdevastyle"), parent) 0227 , m_formatter(new AStyleFormatter()) 0228 { 0229 } 0230 0231 AStylePlugin::~AStylePlugin() 0232 { 0233 } 0234 0235 QString AStylePlugin::name() const 0236 { 0237 // This needs to match the X-KDE-PluginInfo-Name entry from the .desktop file! 0238 return QStringLiteral("kdevastyle"); 0239 } 0240 0241 QString AStylePlugin::caption() const 0242 { 0243 return QStringLiteral("Artistic Style"); 0244 } 0245 0246 QString AStylePlugin::description() const 0247 { 0248 return i18n( 0249 "<b>Artistic Style</b> is a source code indenter, formatter," 0250 " and beautifier for the C, C++, C# and Java programming languages." 0251 // Use <p> to prevent a line break within the link in QWhatsThis. Apparently the following excerpt 0252 // from QToolTip class documentation applies to QWhatsThis too: "Rich text displayed in a tool tip 0253 // is implicitly word-wrapped unless specified differently with <p style='white-space:pre'>." 0254 "<p style='margin-top:0;white-space:pre'>" 0255 "Home Page: <a href=\"http://astyle.sourceforge.net/\">http://astyle.sourceforge.net</a></p>"); 0256 } 0257 0258 QString AStylePlugin::formatSourceWithStyle(const SourceFormatterStyle& style, 0259 const QString& text, 0260 const QUrl& /*url*/, 0261 const QMimeType& mime, 0262 const QString& leftContext, 0263 const QString& rightContext) const 0264 { 0265 if(mime.inherits(QStringLiteral("text/x-java"))) 0266 m_formatter->setJavaStyle(); 0267 else if(mime.inherits(QStringLiteral("text/x-csharp"))) 0268 m_formatter->setSharpStyle(); 0269 else 0270 m_formatter->setCStyle(); 0271 0272 if (style.content().isEmpty()) { 0273 m_formatter->predefinedStyle(style.name()); 0274 } else { 0275 m_formatter->loadStyle(style.content()); 0276 } 0277 0278 return m_formatter->formatSource(text, leftContext, rightContext); 0279 } 0280 0281 static SourceFormatterStyle createPredefinedStyle(const QString& name, const QString& caption = QString()) 0282 { 0283 SourceFormatterStyle st = SourceFormatterStyle( name ); 0284 st.setCaption( caption.isEmpty() ? name : caption ); 0285 AStyleFormatter fmt; 0286 fmt.predefinedStyle( name ); 0287 st.setContent( fmt.saveStyle() ); 0288 st.setMimeTypes(ISourceFormatter::mimeTypesSupportedByBuiltInStyles()); 0289 st.setUsePreview(true); 0290 return st; 0291 } 0292 0293 QVector<SourceFormatterStyle> AStylePlugin::predefinedStyles() const 0294 { 0295 static const QVector<SourceFormatterStyle> list = { 0296 createPredefinedStyle(QStringLiteral("ANSI")), 0297 createPredefinedStyle(QStringLiteral("GNU")), 0298 createPredefinedStyle(QStringLiteral("Java")), 0299 createPredefinedStyle(QStringLiteral("K&R"), QStringLiteral("Kernighan & Ritchie")), 0300 createPredefinedStyle(QStringLiteral("Linux")), 0301 createPredefinedStyle(QStringLiteral("Stroustrup")), 0302 createPredefinedStyle(QStringLiteral("Horstmann")), 0303 createPredefinedStyle(QStringLiteral("Whitesmith")), 0304 createPredefinedStyle(QStringLiteral("Banner")), 0305 createPredefinedStyle(QStringLiteral("1TBS")), 0306 createPredefinedStyle(QStringLiteral("KDELibs"), QStringLiteral("KDE Frameworks")), 0307 createPredefinedStyle(QStringLiteral("Qt")), 0308 }; 0309 return list; 0310 } 0311 0312 bool AStylePlugin::hasEditStyleWidget() const 0313 { 0314 return true; 0315 } 0316 0317 SettingsWidgetPtr AStylePlugin::editStyleWidget(const QMimeType& mime) const 0318 { 0319 AStylePreferences::Language lang = AStylePreferences::CPP; 0320 if (mime.inherits(QStringLiteral("text/x-java"))) 0321 lang = AStylePreferences::Java; 0322 else if (mime.inherits(QStringLiteral("text/x-csharp"))) 0323 lang = AStylePreferences::CSharp; 0324 else if (mime.inherits(QStringLiteral("text/x-objcsrc")) || mime.inherits(QStringLiteral("text/x-objc++src"))) { 0325 // x-objc++src *should* inherit x-objcsrc but that is not always the case in practice 0326 lang = AStylePreferences::ObjC; 0327 } 0328 return SettingsWidgetPtr{new AStylePreferences(lang)}; 0329 } 0330 0331 QString AStylePlugin::previewText(const SourceFormatterStyle& /*style*/, const QMimeType& mime) const 0332 { 0333 if (mime.inherits(QStringLiteral("text/x-objcsrc")) || mime.inherits(QStringLiteral("text/x-objc++src"))) { 0334 static const QString text = ::previewText(indentingObjCSample(), formattingObjCSample()); 0335 return text; 0336 } else { 0337 static const QString text = ::previewText(indentingCppSample(), formattingCppSample()); 0338 return text; 0339 } 0340 // TODO: add previews for the other supported languages 0341 } 0342 0343 AStylePlugin::Indentation AStylePlugin::indentation(const SourceFormatterStyle& style, const QUrl& url, 0344 const QMimeType& mime) const 0345 { 0346 // Call formatSourceWithStyle() first to initialize the m_formatter data structures according to the arguments. 0347 formatSourceWithStyle(style, QString(), url, mime, QString(), QString()); 0348 0349 Indentation ret; 0350 0351 ret.indentWidth = m_formatter->option(QStringLiteral("FillCount")).toInt(); 0352 0353 QString s = m_formatter->option(QStringLiteral("Fill")).toString(); 0354 if(s == QLatin1String("Tabs")) 0355 { 0356 // Do tabs-only indentation 0357 ret.indentationTabWidth = ret.indentWidth; 0358 }else{ 0359 // Don't use tabs at all 0360 ret.indentationTabWidth = -1; 0361 } 0362 0363 return ret; 0364 } 0365 0366 QString AStylePlugin::formattingSample(AStylePreferences::Language lang) 0367 { 0368 switch (lang) { 0369 case AStylePreferences::ObjC: 0370 return formattingObjCSample(); 0371 default: 0372 return formattingCppSample(); 0373 } 0374 Q_UNREACHABLE(); 0375 } 0376 0377 QString AStylePlugin::indentingSample(AStylePreferences::Language lang) 0378 { 0379 switch (lang) { 0380 case AStylePreferences::ObjC: 0381 return indentingObjCSample(); 0382 default: 0383 return indentingCppSample(); 0384 } 0385 Q_UNREACHABLE(); 0386 } 0387 0388 #include "astyle_plugin.moc" 0389 #include "moc_astyle_plugin.cpp"