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

org.sonar.plugins.javascript.bridge.BridgeServer Maven / Gradle / Ivy

/*
 * SonarQube JavaScript Plugin
 * Copyright (C) 2011-2024 SonarSource SA
 * mailto:info AT sonarsource DOT com
 *
 * This program 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 of the License, or (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package org.sonar.plugins.javascript.bridge;

import java.io.IOException;
import java.util.List;
import javax.annotation.Nullable;
import org.sonar.api.Startable;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextRange;
import org.sonar.api.scanner.ScannerSide;
import org.sonar.plugins.javascript.bridge.protobuf.Node;
import org.sonarsource.api.sonarlint.SonarLintSide;

import static org.sonarsource.api.sonarlint.SonarLintSide.INSTANCE;

@ScannerSide
@SonarLintSide(lifespan = INSTANCE)
public interface BridgeServer extends Startable {
  void startServerLazily(BridgeServerConfig context) throws IOException;

  void initLinter(List rules, List environments, List globals, AnalysisMode analysisMode, String baseDir,
    List exclusions) throws IOException;

  AnalysisResponse analyzeJavaScript(JsAnalysisRequest request) throws IOException;

  AnalysisResponse analyzeTypeScript(JsAnalysisRequest request) throws IOException;

  AnalysisResponse analyzeCss(CssAnalysisRequest request) throws IOException;

  AnalysisResponse analyzeYaml(JsAnalysisRequest request) throws IOException;

  AnalysisResponse analyzeHtml(JsAnalysisRequest request) throws IOException;

  void clean();

  String getCommandInfo();

  boolean isAlive();

  boolean newTsConfig();

  TsConfigFile loadTsConfig(String tsConfigAbsolutePath);

  TsProgram createProgram(TsProgramRequest tsProgramRequest) throws IOException;

  boolean deleteProgram(TsProgram tsProgram) throws IOException;

  TsConfigFile createTsConfigFile(String content) throws IOException;

  record JsAnalysisRequest(String filePath, String fileType, String language, @Nullable String fileContent, boolean ignoreHeaderComments,
                           @Nullable List tsConfigs, @Nullable String programId, String linterId, boolean skipAst) {

  }

  record CssAnalysisRequest(String filePath, @Nullable String fileContent, List rules) {
  }

  record BridgeResponse(String json, @Nullable Node ast) {
    public BridgeResponse(String json) {
      this(json, null);
    }
  }
  record AnalysisResponse(@Nullable ParsingError parsingError, List issues, List highlights,
                          List highlightedSymbols, Metrics metrics, List cpdTokens, List ucfgPaths, @Nullable Node ast) {

    public AnalysisResponse(AnalysisResponse response, @Nullable Node ast) {
      this(response.parsingError, response.issues, response.highlights, response.highlightedSymbols,
           response.metrics, response.cpdTokens, response.ucfgPaths, ast);
    }

    public AnalysisResponse() {
      this(null, List.of(), List.of(), List.of(), new Metrics(), List.of(), List.of(), null);
    }

    public AnalysisResponse(@Nullable ParsingError parsingError, @Nullable List issues, @Nullable List highlights,
                            @Nullable List highlightedSymbols, @Nullable Metrics metrics,
                            @Nullable List cpdTokens, List ucfgPaths, @Nullable Node ast) {
      this.parsingError = parsingError;
      this.issues = issues != null ? issues : List.of();
      this.highlights = highlights != null ? highlights : List.of();
      this.highlightedSymbols = highlightedSymbols != null ? highlightedSymbols : List.of();
      this.metrics = metrics != null ? metrics : new Metrics();
      this.cpdTokens = cpdTokens != null ? cpdTokens : List.of();
      this.ucfgPaths = ucfgPaths;
      this.ast = ast;
    }
  }

  record ParsingError(String message, Integer line, ParsingErrorCode code) {
  }

  enum ParsingErrorCode {
    PARSING, FAILING_TYPESCRIPT, GENERAL_ERROR,
  }

  record Issue(Integer line, Integer column, Integer endLine, Integer endColumn, String message, String ruleId,
               List secondaryLocations, Double cost, List quickFixes) {
  }

  record QuickFix(String message, List edits) {
  }

  record QuickFixEdit(String text, IssueLocation loc) {
  }

  record IssueLocation(

    Integer line, Integer column, Integer endLine, Integer endColumn, String message) {
  }

  record Highlight(

    Location location, String textType) {
  }

  record HighlightedSymbol(

    Location declaration, List references) {
  }

  record Location(

    int startLine, int startCol, int endLine, int endCol) {

    public TextRange toTextRange(InputFile inputFile) {
      return inputFile.newRange(this.startLine, this.startCol, this.endLine, this.endCol);
    }

    @Override
    public String toString() {
      return String.format("%d:%d-%d:%d", startLine, startCol, endLine, endCol);
    }
  }

  record Metrics(

    List ncloc, List commentLines, List nosonarLines, List executableLines, int functions,
    int statements, int classes, int complexity, int cognitiveComplexity) {
    public Metrics() {
      this(List.of(), List.of(), List.of(), List.of(), 0, 0, 0, 0, 0);
    }
  }

  record CpdToken(

    Location location, String image) {
  }

  class TsConfigResponse {

    final List files;
    final List projectReferences;
    final String error;
    final ParsingErrorCode errorCode;

    TsConfigResponse(List files, List projectReferences, @Nullable String error, @Nullable ParsingErrorCode errorCode) {
      this.files = files;
      this.projectReferences = projectReferences;
      this.error = error;
      this.errorCode = errorCode;
    }
  }

  record TsProgram(
    @Nullable String programId, @Nullable List files, @Nullable List projectReferences, boolean missingTsConfig,
    @Nullable String error) {

    public TsProgram(String programId, @Nullable List files, @Nullable List projectReferences) {
      this(programId, files, projectReferences, false, null);
    }

    public TsProgram(String programId, List files, List projectReferences, boolean missingTsConfig) {
      this(programId, files, projectReferences, missingTsConfig, null);
    }

    public TsProgram(String error) {
      this(null, null, null, false, error);
    }

    @Override
    public String toString() {
      if (error == null) {
        return ("TsProgram{" + "programId='" + programId + '\'' + ", files=" + files + ", projectReferences=" + projectReferences + '}');
      } else {
        return "TsProgram{ error='" + error + "'}";
      }
    }
  }

  record TsProgramRequest(String tsConfig) {
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy