Changeset View
Changeset View
Standalone View
Standalone View
kdevplatform/outputview/outputfilteringstrategies.cpp
Show All 14 Lines | 1 | /* | |||
---|---|---|---|---|---|
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | 17 | */ | ||
18 | 18 | | |||
19 | #include "outputfilteringstrategies.h" | 19 | #include "outputfilteringstrategies.h" | ||
20 | #include "outputformats.h" | 20 | #include "outputformats.h" | ||
21 | #include "filtereditem.h" | 21 | #include "filtereditem.h" | ||
22 | #include <util/path.h> | 22 | #include <util/path.h> | ||
23 | 23 | #include "debug.h" | |||
24 | #include <KLocalizedString> | 24 | #include <KLocalizedString> | ||
25 | 25 | | |||
26 | #include <QFileInfo> | 26 | #include <QFileInfo> | ||
27 | 27 | | |||
28 | #include <algorithm> | 28 | #include <algorithm> | ||
29 | 29 | | |||
30 | namespace KDevelop | 30 | namespace KDevelop | ||
31 | { | 31 | { | ||
▲ Show 20 Lines • Show All 321 Lines • ▼ Show 20 Line(s) | 310 | for (const auto& curErrFilter : ERROR_FILTERS) { | |||
353 | } | 353 | } | ||
354 | } | 354 | } | ||
355 | return item; | 355 | return item; | ||
356 | } | 356 | } | ||
357 | 357 | | |||
358 | 358 | | |||
359 | /// --- Script error filter strategy --- | 359 | /// --- Script error filter strategy --- | ||
360 | 360 | | |||
361 | ScriptErrorFilterStrategy::ScriptErrorFilterStrategy() | 361 | /// Impl. of ScriptErrorFilterStrategy. | ||
362 | class ScriptErrorFilterStrategyPrivate | ||||
363 | { | ||||
364 | public: | ||||
365 | explicit ScriptErrorFilterStrategyPrivate(const QUrl& scriptDir); | ||||
366 | Path m_scriptDir; | ||||
367 | }; | ||||
368 | | ||||
369 | ScriptErrorFilterStrategyPrivate::ScriptErrorFilterStrategyPrivate(const QUrl& scriptDir) | ||||
370 | : m_scriptDir(scriptDir) | ||||
371 | { | ||||
372 | if( !m_scriptDir.isValid() ) { | ||||
373 | qCDebug(OUTPUTVIEW) << "Invalid scriptDir:" << scriptDir; | ||||
374 | } | ||||
375 | } | ||||
376 | | ||||
377 | ScriptErrorFilterStrategy::~ScriptErrorFilterStrategy() = default; | ||||
378 | | ||||
379 | ScriptErrorFilterStrategy::ScriptErrorFilterStrategy(const QUrl& scriptDir) | ||||
380 | : d_ptr(new ScriptErrorFilterStrategyPrivate(scriptDir)) | ||||
362 | { | 381 | { | ||
363 | } | 382 | } | ||
364 | 383 | | |||
365 | FilteredItem ScriptErrorFilterStrategy::actionInLine(const QString& line) | 384 | FilteredItem ScriptErrorFilterStrategy::actionInLine(const QString& line) | ||
366 | { | 385 | { | ||
367 | return FilteredItem(line); | 386 | return FilteredItem(line); | ||
368 | } | 387 | } | ||
369 | 388 | | |||
370 | FilteredItem ScriptErrorFilterStrategy::errorInLine(const QString& line) | 389 | FilteredItem ScriptErrorFilterStrategy::errorInLine(const QString& line) | ||
371 | { | 390 | { | ||
372 | // A list of filters for possible Python and PHP errors | 391 | // A list of filters for possible Python and PHP errors | ||
373 | static const ErrorFormat SCRIPT_ERROR_FILTERS[] = { | 392 | static const ErrorFormat SCRIPT_ERROR_FILTERS[] = { | ||
393 | // php trigger_error message | ||||
394 | ErrorFormat( QStringLiteral(".*PHP\\s+(.*?):.* in\\s+(/.*) on line ([0-9]+)$"), 2, 3, 1, QStringLiteral("PHP") ), | ||||
395 | // php trigger_error stack trace | ||||
396 | // PHP 2. trigger_error() /home/proyect/yii:6 | ||||
397 | ErrorFormat( QStringLiteral("^(PHP\\s+)[0-9]+\\.\\s+.*\\s+(/.*):([0-9]+)$"), 2, 3, 1, QStringLiteral("PHP") ), | ||||
398 | // PHP Uncaught Error | ||||
399 | ErrorFormat( QStringLiteral("^PHP.*(error):.* in (/.*):([0-9]+)$"), 2, 3, 1, QStringLiteral("PHP") ), | ||||
400 | // General framework rendered Error (Yii2::renderException, etc.) | ||||
401 | ErrorFormat( QStringLiteral("^([Ee]rror):.* in (/.*):([0-9]+)$"), 2, 3, 1, QStringLiteral("PHP") ), | ||||
402 | // PHP Uncaught Error stack trace | ||||
403 | // #0 /home/proyect/yii(6): bad() | ||||
404 | ErrorFormat( QStringLiteral("^\\#[0-9]+\\s+(/.*)\\(([0-9]+)\\):.*$"), 1, 2, -1, QStringLiteral("PHP") ), | ||||
405 | // PHP Uncaught Error stack trace, last thrown | ||||
406 | ErrorFormat( QStringLiteral("^(thrown) in\\s+(/.*) on line ([0-9]+)$"), 2, 3, 1, QStringLiteral("PHP") ), | ||||
407 | // Codeception summary failed tests | ||||
408 | ErrorFormat( QStringLiteral("^\\s*Test\\s+(.*):.*$"), 1, -1, -1, QStringLiteral("CodeCeption") ), | ||||
409 | // Codeception scenario steps | ||||
410 | // 4. $I->grabFixture("model","models0") at tests/functional/ModelsCest.php:43 | ||||
411 | ErrorFormat( QStringLiteral("^.* at (.*):([0-9]+)$"), 1, 2, -1, QStringLiteral("CodeCeption") ), | ||||
412 | // Another stack trace format (seen with CodeCeption) | ||||
413 | // #0 /home/proyect/yii:6 | ||||
414 | ErrorFormat( QStringLiteral("^(\\#[0-9]*\\s)\\s*(/.*):([0-9]+)$"), 2, 3, 0, QStringLiteral("PHP") ), | ||||
415 | // ungreedy with no trailing text, usually the output of the php function trigger_error() | ||||
416 | ErrorFormat( QStringLiteral("^.*\\.\\s+(/.*?):([0-9]+)$"), 1, 2, 0, QStringLiteral("PHP") ), | ||||
417 | // Codeception functional tests response | ||||
418 | ErrorFormat( QStringLiteral("^\\s*(Response:)\\s+(/.*)$"), 2, -1, 1), | ||||
374 | ErrorFormat( QStringLiteral("^ File \"(.*)\", line ([0-9]+)(.*$|, in(.*)$)"), 1, 2, -1 ), | 419 | ErrorFormat( QStringLiteral("^ File \"(.*)\", line ([0-9]+)(.*$|, in(.*)$)"), 1, 2, -1 ), | ||
375 | ErrorFormat( QStringLiteral("^.*(/.*):([0-9]+).*$"), 1, 2, -1 ), | 420 | ErrorFormat( QStringLiteral("^.*(/.*):([0-9]+).*$"), 1, 2, -1 ), | ||
376 | ErrorFormat( QStringLiteral("^.* in (/.*) on line ([0-9]+).*$"), 1, 2, -1 ) | 421 | ErrorFormat( QStringLiteral("^.* in (/.*) on line ([0-9]+).*$"), 1, 2, -1 ), | ||
422 | | ||||
377 | }; | 423 | }; | ||
424 | using Indicator = QPair<QString, FilteredItem::FilteredOutputItemType>; | ||||
425 | static const Indicator INDICATORS[] = { | ||||
426 | // PHP | ||||
427 | // Indicator(QStringLiteral("Notice:"), FilteredItem::InformationItem), | ||||
428 | // Indicator(QStringLiteral("thrown:"), FilteredItem::InformationItem), | ||||
429 | // Indicator(QStringLiteral("PHP "), FilteredItem::InformationItem), | ||||
430 | Indicator(QStringLiteral("Warning"), FilteredItem::WarningItem), | ||||
431 | Indicator(QStringLiteral("error"), FilteredItem::ErrorItem), | ||||
432 | Indicator(QStringLiteral("Error"), FilteredItem::ErrorItem), | ||||
433 | Indicator(QStringLiteral("DEPRECATION"), FilteredItem::WarningItem), | ||||
434 | Indicator(QStringLiteral("Response:"), FilteredItem::WarningItem), | ||||
435 | Indicator(QStringLiteral("#1 "), FilteredItem::WarningItem), | ||||
436 | }; | ||||
437 | FilteredItem item(line); | ||||
438 | for (const auto& curErrFilter : SCRIPT_ERROR_FILTERS) { | ||||
439 | const auto match = curErrFilter.expression.match(line); | ||||
440 | if( match.hasMatch() ) | ||||
441 | { | ||||
442 | QString url; | ||||
443 | if(curErrFilter.fileGroup > 0) { | ||||
444 | url = match.captured( curErrFilter.fileGroup ); | ||||
445 | QFileInfo fi(url); | ||||
446 | if( fi.isRelative() ) { | ||||
447 | item.url = Path(d_ptr->m_scriptDir, url).toUrl(); | ||||
448 | } else { | ||||
449 | item.url = Path(url).toUrl(); | ||||
450 | } | ||||
451 | } | ||||
452 | item.type = FilteredItem::InformationItem; | ||||
453 | initializeFilteredItem(item, curErrFilter, match); | ||||
454 | const QString txt = match.captured(curErrFilter.textGroup); | ||||
378 | 455 | | |||
379 | return match(SCRIPT_ERROR_FILTERS, line); | 456 | // Find the indicator which happens most early. | ||
457 | if( txt.length() ) { | ||||
458 | int earliestIndicatorIdx = txt.length(); | ||||
459 | for (const auto& curIndicator : INDICATORS) { | ||||
460 | int curIndicatorIdx = txt.indexOf(curIndicator.first, 0, Qt::CaseInsensitive); | ||||
461 | if((curIndicatorIdx >= 0) && (earliestIndicatorIdx > curIndicatorIdx)) { | ||||
462 | earliestIndicatorIdx = curIndicatorIdx; | ||||
463 | item.type = curIndicator.second; | ||||
464 | } | ||||
465 | } | ||||
466 | } | ||||
467 | | ||||
468 | // Make the item clickable if it comes with the necessary file information | ||||
469 | if (item.url.isValid()) { | ||||
470 | item.isActivatable = true; | ||||
471 | if(item.type == FilteredItem::InvalidItem) { | ||||
472 | // Okay so we couldn't find anything to indicate an error, but we have file and lineGroup | ||||
473 | // Lets keep this item clickable and indicate this to the user. | ||||
474 | item.type = FilteredItem::InformationItem; | ||||
475 | } | ||||
476 | } | ||||
477 | break; | ||||
478 | } | ||||
479 | } | ||||
480 | return item; | ||||
380 | } | 481 | } | ||
381 | 482 | | |||
382 | /// --- Native application error filter strategy --- | 483 | /// --- Native application error filter strategy --- | ||
383 | 484 | | |||
384 | NativeAppErrorFilterStrategy::NativeAppErrorFilterStrategy() | 485 | NativeAppErrorFilterStrategy::NativeAppErrorFilterStrategy() | ||
385 | { | 486 | { | ||
386 | } | 487 | } | ||
387 | 488 | | |||
▲ Show 20 Lines • Show All 77 Lines • Show Last 20 Lines |