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

com.github._1c_syntax.bsl.languageserver.diagnostics.AbstractFindMethodDiagnostic Maven / Gradle / Ivy

/*
 * This file is a part of BSL Language Server.
 *
 * Copyright (c) 2018-2022
 * Alexey Sosnoviy , Nikita Fedkin  and contributors
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 *
 * BSL Language Server is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3.0 of the License, or (at your option) any later version.
 *
 * BSL Language Server is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with BSL Language Server.
 */
package com.github._1c_syntax.bsl.languageserver.diagnostics;

import com.github._1c_syntax.bsl.parser.BSLParser;
import com.github._1c_syntax.bsl.parser.BSLParserRuleContext;
import lombok.Getter;
import lombok.Setter;
import org.antlr.v4.runtime.tree.ParseTree;

import java.util.regex.Pattern;

/**
 * Абстрактная диагностика, предназначенная для поиска вызова обычных методов и методов глобального контекста
 * с использованием регулярного выражения.
 * {@code AbstractFindMethodDiagnostic} предоставляет для переопределения два метода проверки вызовов и один
 * метод генерации сообщения пользователю.
 * По умолчанию проверяется, что имя вызываемого метода соответствует переданному в конструкторе регулярному выражению.
 * Важно: наследование данной диагностики без переопределения {@code getMessage} подразумевает, что первым
 * параметром сообщения пользователю всегда будет имя найденного метода.
 */
public abstract class AbstractFindMethodDiagnostic extends AbstractVisitorDiagnostic {

  @Getter
  @Setter
  private Pattern methodPattern;

  /**
   * Конструктор по умолчанию
   *
   * @param pattern регулярное выражение для проверки
   */
  AbstractFindMethodDiagnostic(Pattern pattern) {
    methodPattern = pattern;
  }

  /**
   * Проверка контекста глобального метода
   *
   * @param ctx контекст глобального метода
   * @return {@code true} если имя метода соответствует регулярному выражению
   */
  protected boolean checkGlobalMethodCall(BSLParser.GlobalMethodCallContext ctx) {
    return getMethodPattern().matcher(ctx.methodName().getText()).matches();
  }

  /**
   * Проверка контекста обычного метода
   *
   * @param ctx контекст метода
   * @return {@code true} если имя метода соответствует регулярному выражению
   */
  protected boolean checkMethodCall(BSLParser.MethodCallContext ctx) {
    return getMethodPattern().matcher(ctx.methodName().getText()).matches();
  }

  /**
   * Получает сообщение диагностики для пользователя
   *
   * @param ctx контекст узла
   * @return В случае если передан контекст метода, параметризованное сообщение,
   * первым параметром которого всегда будет имя метода.
   * В противном случае возвращается обычное сообщение без параметров.
   */
  protected String getMessage(BSLParserRuleContext ctx) {

    if (ctx instanceof BSLParser.GlobalMethodCallContext) {
      return info.getMessage(((BSLParser.GlobalMethodCallContext) ctx).methodName().getText());
    } else if (ctx instanceof BSLParser.MethodCallContext) {
      return info.getMessage(((BSLParser.MethodCallContext) ctx).methodName().getText());
    } else {
      return info.getMessage();
    }

  }

  /**
   * Обработчик узла глобального метода. Добавляет информацию о сработавшей диагностике
   * в случае если проверка метода {@link AbstractFindMethodDiagnostic#checkGlobalMethodCall(BSLParser.GlobalMethodCallContext)}
   * возвращает {@code true}
   *
   * @param ctx контекст глобального метода
   * @return результат посещения ноды по умолчанию.
   */
  @Override
  public ParseTree visitGlobalMethodCall(BSLParser.GlobalMethodCallContext ctx) {

    if (checkGlobalMethodCall(ctx)) {
      diagnosticStorage.addDiagnostic(ctx.methodName(), getMessage(ctx));
    }

    return super.visitGlobalMethodCall(ctx);
  }

  /**
   * Обработчик узла обычного метода. Добавляет информацию о сработавшей диагностике
   * в случае если проверка метода {@link AbstractFindMethodDiagnostic#checkMethodCall(BSLParser.MethodCallContext)}
   * возвращает {@code true}
   *
   * @param ctx контекст метода
   * @return результат посещения ноды по умолчанию.
   */
  @Override
  public ParseTree visitMethodCall(BSLParser.MethodCallContext ctx) {

    if (checkMethodCall(ctx)) {
      diagnosticStorage.addDiagnostic(ctx.methodName(), getMessage(ctx));
    }

    return super.visitMethodCall(ctx);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy