Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
*
* Contributors:
* Pierre-Yves B. - Issue #309 Launch called from the wrong thread
*******************************************************************************/
Expand Down Expand Up @@ -43,6 +43,7 @@
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.wildwebdeveloper.util.FileUtils;

public abstract class AbstractDebugAdapterLaunchShortcut implements ILaunchShortcut2 {

Expand Down Expand Up @@ -156,7 +157,7 @@ private void launch(String mode, ILaunchConfiguration[] configurations, File lau
DebugUITools.launch(configuration, mode);
} else {
if (DebugUIPlugin.openLaunchConfigurationEditDialog(Display.getCurrent().getActiveShell(), configuration, DebugUITools.getLaunchGroup(configuration, mode).getIdentifier(), null, true) == IDialogConstants.OK_ID) {
DebugUITools.launch(configuration, mode);
DebugUITools.launch(configuration, mode);
}
}
});
Expand Down Expand Up @@ -202,15 +203,15 @@ private ILaunchConfigurationWorkingCopy createNewLaunchConfiguration(File file)
String configName = launchManager.generateLaunchConfigurationName(file.getAbsolutePath());
ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, configName);
wc.setAttribute(DebugPlugin.ATTR_WORKING_DIRECTORY, file.getParentFile().getAbsolutePath());
wc.setMappedResources(ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(file.toURI()));
wc.setMappedResources(ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(FileUtils.toUri(file)));
configureLaunchConfiguration(file, wc);
return wc;
}

/**
* Takes a working copy of a launch configuration and sets the default
* attributes according to provided file
*
*
* @param file
* @param wc
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@
import org.eclipse.wildwebdeveloper.Activator;
import org.eclipse.wildwebdeveloper.debug.chrome.ChromeRunDAPDebugDelegate;
import org.eclipse.wildwebdeveloper.debug.chrome.ChromeRunDebugLaunchShortcut;
import org.eclipse.wildwebdeveloper.util.FileUtils;

public abstract class AbstractRunHTMLDebugTab extends AbstractLaunchConfigurationTab {

private Text programPathText;
private Text argumentsText;
private Text workingDirectoryText;
Expand All @@ -82,8 +83,8 @@ public AbstractRunHTMLDebugTab() {
public void createControl(Composite parent) {
resComposite = new Composite(parent, SWT.NONE);
resComposite.setLayout(new GridLayout(4, false));
fileRadio = createRadioButton(resComposite, Messages.FirefoxDebugTab_File);

fileRadio = createRadioButton(resComposite, Messages.FirefoxDebugTab_File);
fileRadio.setToolTipText(Messages.AbstractRunHTMLDebugTab_fileRadioToolTip);
fileRadio.setLayoutData(new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false));
fileRadio.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
Expand All @@ -96,7 +97,7 @@ public void createControl(Composite parent) {
validateProgramPathAndURL();
updateLaunchConfigurationDialog();
}));

this.programPathText = new Text(resComposite, SWT.BORDER);
this.programPathText.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 2, 1));
fileDecoration = new ControlDecoration(programPathText, SWT.TOP | SWT.LEFT);
Expand All @@ -118,7 +119,7 @@ public void createControl(Composite parent) {
programPathText.setText(path);
}
}));

urlRadio = createRadioButton(resComposite, "URL: ");
urlRadio.setToolTipText(Messages.RunFirefoxDebugTab_URL_Note);
urlRadio.setLayoutData(new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false));
Expand All @@ -142,7 +143,7 @@ public void createControl(Composite parent) {
validateProgramPathAndURL();
updateLaunchConfigurationDialog();
});

new Label(resComposite, SWT.NONE).setText(Messages.AbstractRunHTMLDebugTab_webRoot_folder);
webRootText = new Text(resComposite, SWT.BORDER);
webRootText.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
Expand Down Expand Up @@ -232,7 +233,7 @@ public void createControl(Composite parent) {

private void validateProgramPathAndURL() {
setDirty(true);

setErrorMessage(null);
fileDecoration.hide();
urlDecoration.hide();
Expand All @@ -252,23 +253,23 @@ private void validateProgramPathAndURL() {
} catch (CoreException ex) {
errorMessage = ex.getMessage();
}

if (errorMessage != null) {
setErrorMessage(errorMessage);
fileDecoration.setDescriptionText(errorMessage);
fileDecoration.show();
}

} else if (urlRadio.getSelection()) {
try {
new URL(urlText.getText());
} catch (MalformedURLException ex) {
errorMessage = MessageFormat.format(
Messages.RunProgramTab_error_malformedUR,
Messages.RunProgramTab_error_malformedUR,
ex.getMessage());
urlDecoration.setDescriptionText(errorMessage);
urlDecoration.show();
}
}
boolean showWebRootDecoration = false;
if(webRootText.getText().isBlank()) {
errorMessage = Messages.AbstractRunHTMLDebugTab_cannot_debug_without_webroot;
Expand Down Expand Up @@ -338,9 +339,9 @@ public void initializeFrom(ILaunchConfiguration configuration) {
webRootProjectSelectButton.setEnabled(true);
webRootFilesystemSelectButton.setEnabled(true);
}

validateProgramPathAndURL();

} catch (CoreException e) {
ILog.get().log(e.getStatus());
}
Expand All @@ -357,7 +358,7 @@ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
configuration.setAttribute(AbstractHTMLDebugDelegate.ARGUMENTS, this.argumentsText.getText());
String workingDirectory = this.workingDirectoryText.getText();
configuration.setAttribute(DebugPlugin.ATTR_WORKING_DIRECTORY, workingDirectory);
configuration.setMappedResources(ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(new File(programPath).toURI()));
configuration.setMappedResources(ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(FileUtils.toUri(programPath)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.eclipse.swt.widgets.Text;
import org.eclipse.wildwebdeveloper.debug.LaunchConstants;
import org.eclipse.wildwebdeveloper.debug.Messages;
import org.eclipse.wildwebdeveloper.util.FileUtils;

public class RunProgramTab extends AbstractLaunchConfigurationTab {

Expand Down Expand Up @@ -127,7 +128,7 @@ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
configuration.setAttribute(LaunchConstants.PROGRAM, programPath);
configuration.setAttribute(NodeRunDAPDebugDelegate.ARGUMENTS, this.argumentsText.getText());
configuration.setAttribute(DebugPlugin.ATTR_WORKING_DIRECTORY, this.workingDirectoryText.getText());
configuration.setMappedResources(ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(new File(programPath).toURI()));
configuration.setMappedResources(ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(FileUtils.toUri(programPath)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.eclipse.wildwebdeveloper.debug.AbstractDebugAdapterLaunchShortcut;
import org.eclipse.wildwebdeveloper.debug.AbstractHTMLDebugDelegate;
import org.eclipse.wildwebdeveloper.debug.LaunchConstants;
import org.eclipse.wildwebdeveloper.util.FileUtils;

public class NpmLaunchTab extends AbstractLaunchConfigurationTab {

Expand Down Expand Up @@ -168,7 +169,7 @@ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
configuration.setAttribute(LaunchConstants.PROGRAM, programPath);
configuration.setAttribute(AbstractHTMLDebugDelegate.ARGUMENTS, this.argumentsCombo.getText());
configuration.setAttribute(DebugPlugin.ATTR_WORKING_DIRECTORY, workingDirectory);
configuration.setMappedResources(ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(new File(programPath).toURI()));
configuration.setMappedResources(ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(FileUtils.toUri(programPath)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
*
* Contributors:
* Pierre-Yves Bigourdan - Allow configuring directory of ESLint package
*******************************************************************************/
package org.eclipse.wildwebdeveloper.eslint;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -32,6 +30,7 @@
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.wildwebdeveloper.jsts.ui.preferences.JSTSPreferenceServerConstants;
import org.eclipse.wildwebdeveloper.util.FileUtils;

public class ESLintClientImpl extends LanguageClientImpl implements ESLintLanguageServerExtension {

Expand All @@ -43,7 +42,7 @@ public CompletableFuture<Integer> confirmESLintExecution(Object param) {
@Override
public CompletableFuture<List<Object>> configuration(ConfigurationParams configurationParams) {
ConfigurationItem configurationItem = configurationParams.getItems().get(0);

Map<String, Object> config = new HashMap<>(6, 1.f);

// search first for the highest directory that has a package.json file
Expand All @@ -52,29 +51,24 @@ public CompletableFuture<List<Object>> configuration(ConfigurationParams configu
// until the workspaceFolder which folder is best suited for its workingDirectoy (where the config files are in)
// also this workspaceFolder is also used to find the node models (eslint module)
// because we set the nodePath below to this same directory.
File highestPackageJsonDir = null;
try {
highestPackageJsonDir = new File(new URI(configurationItem.getScopeUri())).getParentFile();
File parentFile = highestPackageJsonDir;
while (parentFile != null) {
if (new File(parentFile, "package.json").exists()) highestPackageJsonDir = parentFile;
parentFile = parentFile.getParentFile();
}
} catch (URISyntaxException e) {
// shouldn't happen else what to do here?
File highestPackageJsonDir = FileUtils.fromUri(configurationItem.getScopeUri()).getParentFile();
File parentFile = highestPackageJsonDir;
while (parentFile != null) {
if (new File(parentFile, "package.json").exists()) highestPackageJsonDir = parentFile;
parentFile = parentFile.getParentFile();
}
// `pre-release/2.3.0`: Disable using experimental Flat Config system

// `pre-release/2.3.0`: Disable using experimental Flat Config system
config.put("experimental", Collections.emptyMap());

// `pre-release/2.3.0`: Add stub `problems` settings due to:
// ESLint: Cannot read properties of undefined (reading \u0027shortenToSingleLine\u0027). Please see the \u0027ESLint\u0027 output channel for details.
config.put("problems", Collections.emptyMap());

config.put("workspaceFolder", Collections.singletonMap("uri", highestPackageJsonDir.toURI().toString()));
config.put("workspaceFolder", Collections.singletonMap("uri", FileUtils.toUri(highestPackageJsonDir).toString()));

// if you set a workspaceFolder and then the working dir in auto mode eslint will try to get to the right config location.
config.put("workingDirectory", Collections.singletonMap("mode", "auto"));
config.put("workingDirectory", Collections.singletonMap("mode", "auto"));

// this should not point to a nodejs executable but to a parent directory containing the ESLint package
config.put("nodePath",getESLintPackageDir(highestPackageJsonDir));
Expand All @@ -83,7 +77,7 @@ public CompletableFuture<List<Object>> configuration(ConfigurationParams configu
config.put("run", "onType");
config.put("rulesCustomizations", Collections.emptyList());

config.put("codeAction", Map.of("disableRuleComment", Map.of("enable", "true", "location", "separateLine"),
config.put("codeAction", Map.of("disableRuleComment", Map.of("enable", "true", "location", "separateLine"),
"showDocumentation", Collections.singletonMap("enable", "true")));
return CompletableFuture.completedFuture(Collections.singletonList(config));
}
Expand Down Expand Up @@ -112,7 +106,7 @@ public CompletableFuture<Void> eslintStatus(Object o) {
// ignore for now
return CompletableFuture.completedFuture(null);
}

@Override
public CompletableFuture<Void> openDoc(Map<String,String> data) {
if (data.containsKey("url")) {
Expand All @@ -127,7 +121,7 @@ public CompletableFuture<Void> openDoc(Map<String,String> data) {
}
return CompletableFuture.completedFuture(null);
}

@Override
public CompletableFuture<Void> noLibrary(Map<String,Map<String,String>> data) {
MessageParams params = new MessageParams(MessageType.Info, "No ES Library found for file: " + data.get("source").get("uri"));
Expand All @@ -137,7 +131,7 @@ public CompletableFuture<Void> noLibrary(Map<String,Map<String,String>> data) {

@Override
public CompletableFuture<Void> noConfig(Map<String, Map<String, String>> data) {
MessageParams params = new MessageParams(MessageType.Info, "No ES Configuration found for file: " + data.get("source").get("uri")
MessageParams params = new MessageParams(MessageType.Info, "No ES Configuration found for file: " + data.get("source").get("uri")
+ ": " + data.get("message"));
logMessage(params);
return CompletableFuture.completedFuture(null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*******************************************************************************
* Copyright (c) 2025 Vegard IT GmbH and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Sebastian Thomschke (Vegard IT GmbH) - initial implementation
*******************************************************************************/
package org.eclipse.wildwebdeveloper.util;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Paths;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.wildwebdeveloper.Activator;

public class FileUtils {
private static final String FILE_SCHEME = "file"; //$NON-NLS-1$

public static File fromUri(String uri) {
// not using `new File(new URI(uri))` here which does not support Windows UNC paths
// and instead throws IllegalArgumentException("URI has an authority component")
return Paths.get(URI.create(uri)).toFile();
}

public static URI toUri(String filePath) {
return toUri(new File(filePath));
}

public static URI toUri(File file) {
// copied from org.eclipse.lsp4e.LSPEclipseUtils#toUri(File)

// URI scheme specified by language server protocol and LSP
try {
final var path = file.getAbsoluteFile().toURI().getPath();
if (path.startsWith("//")) { // UNC path like //localhost/c$/Windows/ //$NON-NLS-1$
// split: authority = "localhost", absPath = "/c$/Windows/"
final int slash = path.indexOf('/', 2);
final String authority = slash > 2 ? path.substring(2, slash) : path.substring(2);
final String absPath = slash > 2 ? path.substring(slash) : "/"; //$NON-NLS-1$
return new URI(FILE_SCHEME, authority, absPath, null);
}
return new URI(FILE_SCHEME, "", path, null); //$NON-NLS-1$
} catch (URISyntaxException ex) {
Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, ex.getMessage(), ex));
return file.getAbsoluteFile().toURI();
}
}

}