// ***************************************************************************** // Copyright (C) 2019 Ericsson and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: GNU General Public License, version 2 // with the GNU Classpath Exception which is available at // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** import { AbstractLineMatcher } from './task-abstract-line-matcher'; import { ProblemMatcher, ProblemMatch, WatchingPattern } from '../common/problem-matcher-protocol'; export class StartStopLineMatcher extends AbstractLineMatcher { constructor(matcher: ProblemMatcher) { super(matcher); } /** * Finds the problem identified by this line matcher. * * @param line the line of text to find the problem from * @return the identified problem. If the problem is not found, `undefined` is returned. */ match(line: string): ProblemMatch | undefined { if (!this.activePattern) { this.resetActivePatternIndex(); } if (this.activePattern) { const originalProblemData = Object.assign(this.getEmptyProblemData(), this.cachedProblemData); const foundMatch = this.doOneLineMatch(line); if (foundMatch) { if (this.isUsingTheLastPattern()) { const matchResult = this.getMarkerMatch(this.cachedProblemData); if (this.isLastPatternLoop()) { this.cachedProblemData = originalProblemData; } else { this.resetCachedProblemData(); this.resetActivePatternIndex(); } return matchResult; } else { this.nextProblemPattern(); } } else { this.resetCachedProblemData(); if (this.activePatternIndex !== 0) { // if no match, use the first pattern to parse the same line this.resetActivePatternIndex(); return this.match(line); } } } return undefined; } } export class WatchModeLineMatcher extends StartStopLineMatcher { private beginsPattern: WatchingPattern; private endsPattern: WatchingPattern; activeOnStart: boolean = false; constructor(matcher: ProblemMatcher) { super(matcher); this.beginsPattern = matcher.watching!.beginsPattern; this.endsPattern = matcher.watching!.endsPattern; this.activeOnStart = matcher.watching!.activeOnStart === true; this.resetActivePatternIndex(this.activeOnStart ? 0 : -1); } /** * Finds the problem identified by this line matcher. * * @param line the line of text to find the problem from * @return the identified problem. If the problem is not found, `undefined` is returned. */ override match(line: string): ProblemMatch | undefined { if (this.activeOnStart) { this.activeOnStart = false; this.resetActivePatternIndex(0); this.resetCachedProblemData(); return super.match(line); } if (this.matchBegin(line)) { const beginsPatternMatch = this.getMarkerMatch(this.cachedProblemData); this.resetCachedProblemData(); return beginsPatternMatch; } if (this.matchEnd(line)) { this.resetCachedProblemData(); return undefined; } if (this.activePattern) { return super.match(line); } return undefined; } matchBegin(line: string): boolean { const beginRegexp = new RegExp(this.beginsPattern.regexp); const regexMatches = beginRegexp.exec(line); if (regexMatches) { this.fillProblemData(this.cachedProblemData, this.beginsPattern, regexMatches); this.resetActivePatternIndex(0); return true; } return false; } matchEnd(line: string): boolean { const endRegexp = new RegExp(this.endsPattern.regexp); const match = endRegexp.exec(line); if (match) { this.resetActivePatternIndex(-1); return true; } return false; } }