All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.hm.hafner.analysis.parser.DrMemoryParser Maven / Gradle / Ivy

Go to download

This library provides a Java object model to read, aggregate, filter, and query static analysis reports. It is used by Jenkins' warnings next generation plug-in to visualize the warnings of individual builds. Additionally, this library is used by a GitHub action to autograde student software projects based on a given set of metrics (unit tests, code and mutation coverage, static analysis warnings).

There is a newer version: 12.9.1
Show newest version
package edu.hm.hafner.analysis.parser;

import java.util.Locale;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

import edu.hm.hafner.analysis.Issue;
import edu.hm.hafner.analysis.IssueBuilder;
import edu.hm.hafner.analysis.LookaheadParser;
import edu.hm.hafner.analysis.ParsingException;
import edu.hm.hafner.analysis.Severity;
import edu.hm.hafner.util.LookaheadStream;

import static edu.hm.hafner.analysis.util.IntegerParser.*;

/**
 * A parser for the Dr. Memory Errors.
 *
 * @author Wade Penson
 */
public class DrMemoryParser extends LookaheadParser {
    private static final long serialVersionUID = 7195239138601238590L;
    private static final String DR_MEMORY_WARNING_PATTERN = "Error #\\d+: (.*)";

    /** Regex pattern to extract the file path from a line. */
    private static final Pattern FILE_PATH_PATTERN = Pattern.compile(
            "#\\s*\\d+.*?\\[(?.*/?.*):(?\\d+)]");

    /** Regex pattern to extract the jenkins path from file path. */
    private static final Pattern JENKINS_PATH_PATTERN = Pattern
            .compile(".*?(/jobs/.*?/workspace/|workspace/)");

    /**
     * Creates a new instance of {@link DrMemoryParser}.
     */
    public DrMemoryParser() {
        super(DR_MEMORY_WARNING_PATTERN);
    }

    @Override
    protected Optional createIssue(final Matcher matcher, final LookaheadStream lookahead,
            final IssueBuilder builder)
            throws ParsingException {
        String header = matcher.group(1);

        StringBuilder messageBuilder = new StringBuilder(header);
        while (lookahead.hasNext("Elapsed time")) {
            messageBuilder.append("
"); messageBuilder.append(lookahead.next()); } StringBuilder stacktraceBuilder = new StringBuilder(); while (lookahead.hasNext("^#.*")) { String stackTrace = lookahead.next(); stacktraceBuilder.append(stackTrace); stacktraceBuilder.append("
"); messageBuilder.append("
"); messageBuilder.append(stackTrace); } while (lookahead.hasNext("^Note:")) { messageBuilder.append("
"); messageBuilder.append(lookahead.next()); } if (StringUtils.isNotBlank(header)) { assignCategoryAndSeverity(builder, header.toLowerCase(Locale.ENGLISH)); } findOriginatingErrorLocation(stacktraceBuilder.toString(), builder); if (messageBuilder.length() == 0) { messageBuilder.append("Unknown Dr. Memory Error"); } return builder.setMessage(messageBuilder.toString()).buildOptional(); } @SuppressWarnings("PMD.CyclomaticComplexity") private void assignCategoryAndSeverity(final IssueBuilder builder, final String header) { builder.setCategory("Unknown"); builder.setSeverity(Severity.WARNING_NORMAL); if (header.startsWith("unaddressable access")) { builder.setCategory("Unaddressable Access"); builder.setSeverity(Severity.WARNING_HIGH); } else if (header.startsWith("uninitialized read")) { builder.setCategory("Uninitialized Read"); builder.setSeverity(Severity.WARNING_HIGH); } else if (header.startsWith("invalid heap argument")) { builder.setCategory("Invalid Heap Argument"); builder.setSeverity(Severity.WARNING_HIGH); } else if (header.startsWith("reachable leak")) { builder.setCategory("Reachable Leak"); builder.setSeverity(Severity.WARNING_HIGH); } else if (header.startsWith("leak")) { builder.setCategory("Leak"); builder.setSeverity(Severity.WARNING_HIGH); } else if (header.startsWith("possible leak")) { builder.setCategory("Possible Leak"); } else if (header.startsWith("gdi usage error")) { builder.setCategory("GDI Usage Error"); } else if (header.startsWith("handle leak")) { builder.setCategory("Handle Leak"); } else if (header.startsWith("warning")) { builder.setCategory("Warning"); } } /** * Looks through each line of the stack trace to try and determine the file path and line number where the error * originates from within the user's code. This assumes that the user's code is within the Jenkins workspace folder. * Otherwise, the file path and line number is obtained from the top of the stack trace. * * @param stackTrace * the stack trace in the correct order * @param builder * the issue builder */ private void findOriginatingErrorLocation(final String stackTrace, final IssueBuilder builder) { builder.setFileName("-"); builder.setLineStart(0); for (String line : stackTrace.split("
", -1)) { Matcher pathMatcher = FILE_PATH_PATTERN.matcher(line); if (pathMatcher.find()) { String path = pathMatcher.group("file"); builder.setFileName(path); builder.setLineStart(parseInt(pathMatcher.group("line"))); Matcher jenkinsPathMatcher = JENKINS_PATH_PATTERN.matcher(path); if (jenkinsPathMatcher.find()) { return; } } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy