Skip to content

Commit

Permalink
Migrate code base to Java 11 (#91)
Browse files Browse the repository at this point in the history
* Use local variable type inference when appropriate

* Use List.of when applicable

* Use Map.of when appropriate

* Remove more use of Guava, use Predicate.not when appropriate

* Simplify Stream<Optional> expressions

* Apply PR feedback

* Use local variable type inference in tests also
  • Loading branch information
jblievremont authored Oct 21, 2021
1 parent 99b3d28 commit c4a70ea
Show file tree
Hide file tree
Showing 68 changed files with 1,337 additions and 1,502 deletions.
121 changes: 57 additions & 64 deletions src/main/java/org/sonarsource/sonarlint/ls/AnalysisManager.java

Large diffs are not rendered by default.

113 changes: 54 additions & 59 deletions src/main/java/org/sonarsource/sonarlint/ls/CommandManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,12 @@
package org.sonarsource.sonarlint.ls;

import com.google.gson.JsonPrimitive;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.eclipse.lsp4j.CodeAction;
Expand All @@ -53,9 +50,7 @@
import org.sonarsource.sonarlint.core.client.api.common.QuickFix;
import org.sonarsource.sonarlint.core.client.api.common.RuleDetails;
import org.sonarsource.sonarlint.core.client.api.common.TextRange;
import org.sonarsource.sonarlint.core.client.api.common.analysis.Issue;
import org.sonarsource.sonarlint.core.client.api.connected.ConnectedRuleDetails;
import org.sonarsource.sonarlint.core.client.api.connected.ConnectedSonarLintEngine;
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneRuleDetails;
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneRuleParam;
import org.sonarsource.sonarlint.core.util.StringUtils;
Expand All @@ -80,7 +75,7 @@ public class CommandManager {
static final String SONARLINT_UPDATE_ALL_BINDINGS_COMMAND = "SonarLint.UpdateAllBindings";
static final String SONARLINT_BROWSE_TAINT_VULNERABILITY = "SonarLint.BrowseTaintVulnerability";
static final String SONARLINT_SHOW_TAINT_VULNERABILITY_FLOWS = "SonarLint.ShowTaintVulnerabilityFlows";
static final List<String> SONARLINT_SERVERSIDE_COMMANDS = Arrays.asList(
static final List<String> SONARLINT_SERVERSIDE_COMMANDS = List.of(
SONARLINT_QUICK_FIX_APPLIED,
SONARLINT_UPDATE_ALL_BINDINGS_COMMAND,
SONARLINT_OPEN_RULE_DESCRIPTION_FROM_CODE_ACTION_COMMAND,
Expand Down Expand Up @@ -110,56 +105,56 @@ public class CommandManager {
}

public List<Either<Command, CodeAction>> computeCodeActions(CodeActionParams params, CancelChecker cancelToken) {
List<Either<Command, CodeAction>> codeActions = new ArrayList<>();
URI uri = create(params.getTextDocument().getUri());
Optional<ProjectBindingWrapper> binding = bindingManager.getBinding(uri);
for (Diagnostic d : params.getContext().getDiagnostics()) {
var codeActions = new ArrayList<Either<Command, CodeAction>>();
var uri = create(params.getTextDocument().getUri());
var binding = bindingManager.getBinding(uri);
for (var diagnostic: params.getContext().getDiagnostics()) {
cancelToken.checkCanceled();
if (SONARLINT_SOURCE.equals(d.getSource())) {
String ruleKey = d.getCode().getLeft();
if (SONARLINT_SOURCE.equals(diagnostic.getSource())) {
var ruleKey = diagnostic.getCode().getLeft();
cancelToken.checkCanceled();
Optional<Issue> issueForDiagnostic = analysisManager.getIssueForDiagnostic(uri, d);
var issueForDiagnostic = analysisManager.getIssueForDiagnostic(uri, diagnostic);
issueForDiagnostic.ifPresent(issue -> issue.quickFixes().forEach(fix -> {
CodeAction newCodeAction = new CodeAction(SONARLINT_ACTION_PREFIX + fix.message());
var newCodeAction = new CodeAction(SONARLINT_ACTION_PREFIX + fix.message());
newCodeAction.setKind(CodeActionKind.QuickFix);
newCodeAction.setDiagnostics(Collections.singletonList(d));
newCodeAction.setDiagnostics(List.of(diagnostic));
newCodeAction.setEdit(newWorkspaceEdit(fix, analysisManager.getAnalyzedVersion(uri)));
newCodeAction.setCommand(new Command(fix.message(), SONARLINT_QUICK_FIX_APPLIED, Collections.singletonList(ruleKey)));
newCodeAction.setCommand(new Command(fix.message(), SONARLINT_QUICK_FIX_APPLIED, List.of(ruleKey)));
codeActions.add(Either.forRight(newCodeAction));
}));
addRuleDescriptionCodeAction(params, codeActions, d, ruleKey);
addRuleDescriptionCodeAction(params, codeActions, diagnostic, ruleKey);
issueForDiagnostic.ifPresent(issue -> {
if (!issue.flows().isEmpty()) {
String titleShowAllLocations = String.format("Show all locations for issue '%s'", ruleKey);
codeActions.add(newQuickFix(d, titleShowAllLocations, ShowAllLocationsCommand.ID, Collections.singletonList(ShowAllLocationsCommand.params(issue))));
var titleShowAllLocations = String.format("Show all locations for issue '%s'", ruleKey);
codeActions.add(newQuickFix(diagnostic, titleShowAllLocations, ShowAllLocationsCommand.ID, List.of(ShowAllLocationsCommand.params(issue))));
}
});
if (!binding.isPresent()) {
String titleDeactivate = String.format("Deactivate rule '%s'", ruleKey);
codeActions.add(newQuickFix(d, titleDeactivate, SONARLINT_DEACTIVATE_RULE_COMMAND, Collections.singletonList(ruleKey)));
if (binding.isEmpty()) {
var titleDeactivate = String.format("Deactivate rule '%s'", ruleKey);
codeActions.add(newQuickFix(diagnostic, titleDeactivate, SONARLINT_DEACTIVATE_RULE_COMMAND, List.of(ruleKey)));
}
} else if (SONARQUBE_TAINT_SOURCE.equals(d.getSource())) {
ProjectBindingWrapper actualBinding = binding.orElseThrow(() -> new IllegalStateException("Binding not found for taint vulnerability"));
String ruleKey = d.getCode().getLeft();
addRuleDescriptionCodeAction(params, codeActions, d, ruleKey);
analysisManager.getTaintVulnerabilityForDiagnostic(uri, d).ifPresent(issue -> {
} else if (SONARQUBE_TAINT_SOURCE.equals(diagnostic.getSource())) {
var actualBinding = binding.orElseThrow(() -> new IllegalStateException("Binding not found for taint vulnerability"));
var ruleKey = diagnostic.getCode().getLeft();
addRuleDescriptionCodeAction(params, codeActions, diagnostic, ruleKey);
analysisManager.getTaintVulnerabilityForDiagnostic(uri, diagnostic).ifPresent(issue -> {
if (!issue.getFlows().isEmpty()) {
String titleShowAllLocations = String.format("Show all locations for taint vulnerability '%s'", ruleKey);
codeActions.add(newQuickFix(d, titleShowAllLocations, SONARLINT_SHOW_TAINT_VULNERABILITY_FLOWS, Arrays.asList(issue.key(), actualBinding.getConnectionId())));
var titleShowAllLocations = String.format("Show all locations for taint vulnerability '%s'", ruleKey);
codeActions.add(newQuickFix(diagnostic, titleShowAllLocations, SONARLINT_SHOW_TAINT_VULNERABILITY_FLOWS, List.of(issue.key(), actualBinding.getConnectionId())));
}
String title = String.format("Open taint vulnerability '%s' on '%s'", ruleKey, actualBinding.getConnectionId());
String serverUrl = settingsManager.getCurrentSettings().getServerConnections().get(actualBinding.getConnectionId()).getServerUrl();
String projectKey = StringUtils.urlEncode(actualBinding.getBinding().projectKey());
String issueUrl = String.format("%s/project/issues?id=%s&issues=%s&open=%s", serverUrl, projectKey, issue.key(), issue.key());
codeActions.add(newQuickFix(d, title, SONARLINT_BROWSE_TAINT_VULNERABILITY, Collections.singletonList(issueUrl)));
var title = String.format("Open taint vulnerability '%s' on '%s'", ruleKey, actualBinding.getConnectionId());
var serverUrl = settingsManager.getCurrentSettings().getServerConnections().get(actualBinding.getConnectionId()).getServerUrl();
var projectKey = StringUtils.urlEncode(actualBinding.getBinding().projectKey());
var issueUrl = String.format("%s/project/issues?id=%s&issues=%s&open=%s", serverUrl, projectKey, issue.key(), issue.key());
codeActions.add(newQuickFix(diagnostic, title, SONARLINT_BROWSE_TAINT_VULNERABILITY, List.of(issueUrl)));
});
}
}
return codeActions;
}

private static WorkspaceEdit newWorkspaceEdit(QuickFix fix, @Nullable Integer documentVersion) {
WorkspaceEdit edit = new WorkspaceEdit();
var edit = new WorkspaceEdit();
edit.setDocumentChanges(
fix.inputFileEdits().stream()
.map(fileEdit -> newLspDocumentEdit(fileEdit, documentVersion))
Expand All @@ -168,7 +163,7 @@ private static WorkspaceEdit newWorkspaceEdit(QuickFix fix, @Nullable Integer do
}

private static Either<TextDocumentEdit, ResourceOperation> newLspDocumentEdit(ClientInputFileEdit fileEdit, @Nullable Integer documentVersion) {
TextDocumentEdit documentEdit = new TextDocumentEdit();
var documentEdit = new TextDocumentEdit();
documentEdit.setTextDocument(new VersionedTextDocumentIdentifier(fileEdit.target().uri().toString(), documentVersion));
documentEdit.setEdits(fileEdit.textEdits().stream()
.map(CommandManager::newLspTextEdit)
Expand All @@ -177,9 +172,9 @@ private static Either<TextDocumentEdit, ResourceOperation> newLspDocumentEdit(Cl
}

private static TextEdit newLspTextEdit(org.sonarsource.sonarlint.core.client.api.common.TextEdit textEdit) {
TextEdit lspEdit = new TextEdit();
var lspEdit = new TextEdit();
lspEdit.setNewText(textEdit.newText());
Range lspRange = newLspRange(textEdit.range());
var lspRange = newLspRange(textEdit.range());
lspEdit.setRange(lspRange);
return lspEdit;
}
Expand All @@ -189,30 +184,30 @@ private static Range newLspRange(TextRange range) {
checkNotNull(range.getStartLineOffset());
checkNotNull(range.getEndLine());
checkNotNull(range.getEndLineOffset());
Range lspRange = new Range();
var lspRange = new Range();
lspRange.setStart(new Position(range.getStartLine() - 1, range.getStartLineOffset()));
lspRange.setEnd(new Position(range.getEndLine() - 1, range.getEndLineOffset()));
return lspRange;
}

private static void addRuleDescriptionCodeAction(CodeActionParams params, List<Either<Command, CodeAction>> codeActions, Diagnostic d, String ruleKey) {
String titleShowRuleDesc = String.format("Open description of rule '%s'", ruleKey);
codeActions.add(newQuickFix(d, titleShowRuleDesc, SONARLINT_OPEN_RULE_DESCRIPTION_FROM_CODE_ACTION_COMMAND, Arrays.asList(ruleKey, params.getTextDocument().getUri())));
var titleShowRuleDesc = String.format("Open description of rule '%s'", ruleKey);
codeActions.add(newQuickFix(d, titleShowRuleDesc, SONARLINT_OPEN_RULE_DESCRIPTION_FROM_CODE_ACTION_COMMAND, List.of(ruleKey, params.getTextDocument().getUri())));
}

private static Either<Command, CodeAction> newQuickFix(Diagnostic diag, String title, String command, List<Object> params) {
CodeAction newCodeAction = new CodeAction(SONARLINT_ACTION_PREFIX + title);
var newCodeAction = new CodeAction(SONARLINT_ACTION_PREFIX + title);
newCodeAction.setCommand(new Command(title, command, params));
newCodeAction.setKind(CodeActionKind.QuickFix);
newCodeAction.setDiagnostics(Collections.singletonList(diag));
newCodeAction.setDiagnostics(List.of(diag));
return Either.forRight(newCodeAction);
}

public Map<String, List<Rule>> listAllStandaloneRules() {
Map<String, List<Rule>> result = new HashMap<>();
var result = new HashMap<String, List<Rule>>();
standaloneEngineManager.getOrCreateStandaloneEngine().getAllRuleDetails()
.forEach(d -> {
String languageName = d.getLanguage().getLabel();
var languageName = d.getLanguage().getLabel();
result.computeIfAbsent(languageName, k -> new ArrayList<>()).add(Rule.of(d));
});
return result;
Expand All @@ -226,17 +221,17 @@ private void openRuleDescription(@Nullable ProjectBindingWrapper binding, String
.orElseThrow(() -> unknownRule(ruleKey));
paramDetails = ((StandaloneRuleDetails) ruleDetails).paramDetails();
} else {
ConnectedSonarLintEngine engine = binding.getEngine();
var engine = binding.getEngine();
try {
ruleDetails = engine.getActiveRuleDetails(ruleKey, binding.getBinding().projectKey());
} catch (IllegalArgumentException e) {
throw unknownRule(ruleKey);
}
}
String ruleName = ruleDetails.getName();
String htmlDescription = getHtmlDescription(ruleDetails);
String type = ruleDetails.getType();
String severity = ruleDetails.getSeverity();
var ruleName = ruleDetails.getName();
var htmlDescription = getHtmlDescription(ruleDetails);
var type = ruleDetails.getType();
var severity = ruleDetails.getSeverity();
client.showRuleDescription(new ShowRuleDescriptionParams(ruleKey, ruleName, htmlDescription, type, severity, paramDetails));
}

Expand Down Expand Up @@ -270,26 +265,26 @@ public void executeCommand(ExecuteCommandParams params, CancelChecker cancelToke
}

private void handleOpenStandaloneRuleDescriptionCommand(ExecuteCommandParams params) {
String ruleKey = getAsString(params.getArguments().get(0));
var ruleKey = getAsString(params.getArguments().get(0));
openRuleDescription(null, ruleKey);
}

private void handleOpenRuleDescriptionFromCodeActionCommand(ExecuteCommandParams params) {
String ruleKey = getAsString(params.getArguments().get(0));
URI uri = create(getAsString(params.getArguments().get(1)));
Optional<ProjectBindingWrapper> binding = bindingManager.getBinding(uri);
var ruleKey = getAsString(params.getArguments().get(0));
var uri = create(getAsString(params.getArguments().get(1)));
var binding = bindingManager.getBinding(uri);
openRuleDescription(binding.orElse(null), ruleKey);
}

private void handleBrowseTaintVulnerability(ExecuteCommandParams params) {
String taintUrl = getAsString(params.getArguments().get(0));
var taintUrl = getAsString(params.getArguments().get(0));
telemetry.taintVulnerabilitiesInvestigatedRemotely();
client.browseTo(taintUrl);
}

private void handleShowTaintVulnerabilityFlows(ExecuteCommandParams params) {
String issueKey = getAsString(params.getArguments().get(0));
String connectionId = getAsString(params.getArguments().get(1));
var issueKey = getAsString(params.getArguments().get(0));
var connectionId = getAsString(params.getArguments().get(1));
analysisManager.getTaintVulnerabilityByKey(issueKey)
.ifPresent(issue -> {
telemetry.taintVulnerabilitiesInvestigatedLocally();
Expand All @@ -304,9 +299,9 @@ private static String getAsString(Object jsonPrimitive) {

// visible for testing
static String getHtmlDescription(RuleDetails ruleDetails) {
String htmlDescription = ruleDetails.getHtmlDescription();
var htmlDescription = ruleDetails.getHtmlDescription();
if (ruleDetails instanceof ConnectedRuleDetails) {
String extendedDescription = ((ConnectedRuleDetails) ruleDetails).getExtendedDescription();
var extendedDescription = ((ConnectedRuleDetails) ruleDetails).getExtendedDescription();
if (!extendedDescription.isEmpty()) {
htmlDescription += "<div>" + extendedDescription + "</div>";
}
Expand Down
21 changes: 11 additions & 10 deletions src/main/java/org/sonarsource/sonarlint/ls/EnginesFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@

import java.net.URL;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.CheckForNull;
Expand Down Expand Up @@ -68,7 +68,8 @@ public class EnginesFactory {
private final ModulesProvider modulesProvider;
private final Collection<URL> extraAnalyzers;

public EnginesFactory(Collection<URL> standaloneAnalyzers, LanguageClientLogOutput lsLogOutput, NodeJsRuntime nodeJsRuntime, ModulesProvider modulesProvider, Collection<URL> extraAnalyzers) {
public EnginesFactory(Collection<URL> standaloneAnalyzers, LanguageClientLogOutput lsLogOutput, NodeJsRuntime nodeJsRuntime, ModulesProvider modulesProvider,
Collection<URL> extraAnalyzers) {
this.standaloneAnalyzers = standaloneAnalyzers;
this.lsLogOutput = lsLogOutput;
this.nodeJsRuntime = nodeJsRuntime;
Expand All @@ -81,17 +82,17 @@ public StandaloneSonarLintEngine createStandaloneEngine() {
LOG.debug("Using {} analyzers", standaloneAnalyzers.size());

try {
StandaloneGlobalConfiguration configuration = StandaloneGlobalConfiguration.builder()
var configuration = StandaloneGlobalConfiguration.builder()
.setExtraProperties(prepareExtraProps())
.addEnabledLanguages(STANDALONE_LANGUAGES)
.setNodeJs(nodeJsRuntime.getNodeJsPath(), nodeJsRuntime.getNodeJsVersion())
.addPlugins(standaloneAnalyzers.toArray(new URL[0]))
.addPlugins(extraAnalyzers.toArray(new URL[0]))
.addPlugins(standaloneAnalyzers.toArray(URL[]::new))
.addPlugins(extraAnalyzers.toArray(URL[]::new))
.setModulesProvider(modulesProvider)
.setLogOutput(lsLogOutput)
.build();

StandaloneSonarLintEngine engine = newStandaloneEngine(configuration);
var engine = newStandaloneEngine(configuration);
LOG.debug("Standalone SonarLint engine started");
return engine;
} catch (Exception e) {
Expand All @@ -105,7 +106,7 @@ StandaloneSonarLintEngine newStandaloneEngine(StandaloneGlobalConfiguration conf
}

public ConnectedSonarLintEngine createConnectedEngine(String connectionId) {
ConnectedGlobalConfiguration.Builder builder = ConnectedGlobalConfiguration.builder()
var builder = ConnectedGlobalConfiguration.builder()
.setConnectionId(connectionId)
.setExtraProperties(prepareExtraProps())
.addEnabledLanguages(STANDALONE_LANGUAGES)
Expand All @@ -115,7 +116,7 @@ public ConnectedSonarLintEngine createConnectedEngine(String connectionId) {
.setLogOutput(lsLogOutput);

extraAnalyzers.forEach(analyzer-> builder.addExtraPlugin(guessPluginKey(analyzer.getPath()), analyzer));
ConnectedSonarLintEngine engine = newConnectedEngine(builder.build());
var engine = newConnectedEngine(builder.build());

LOG.debug("SonarLint engine started for connection '{}'", connectionId);
return engine;
Expand All @@ -129,7 +130,7 @@ static String guessPluginKey(String pluginUrl) {
}

private Map<String, String> prepareExtraProps() {
Map<String, String> extraProperties = new HashMap<>();
var extraProperties = new HashMap<String, String>();
if (typeScriptPath != null) {
extraProperties.put(AnalysisManager.TYPESCRIPT_PATH_PROP, typeScriptPath.toString());
}
Expand All @@ -145,7 +146,7 @@ public void initialize(@Nullable Path typeScriptPath) {
}

public static Set<Language> getStandaloneLanguages() {
return EnumSet.copyOf(Arrays.asList(STANDALONE_LANGUAGES));
return EnumSet.copyOf(List.of(STANDALONE_LANGUAGES));
}

}
Loading

0 comments on commit c4a70ea

Please sign in to comment.