Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include dir support for diagnostics #238

Merged
merged 13 commits into from
Dec 5, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import java.io.File;
import java.util.List;
import java.util.logging.Logger;

import org.eclipse.lemminx.commons.CodeActionFactory;
import org.eclipse.lemminx.dom.DOMDocument;
Expand All @@ -24,6 +25,7 @@
import org.eclipse.lsp4j.jsonrpc.CancelChecker;

public class AddTrailingSlash implements ICodeActionParticipant {
private static final Logger LOGGER = Logger.getLogger(AddTrailingSlash.class.getName());

public static final String CODEACTION_TITLE = "Add trailing slash to specify directory.";

Expand All @@ -37,17 +39,28 @@ public void doCodeAction(ICodeActionRequest request, List<CodeAction> codeAction
try {
String fileSeparator = FORWARD_SLASH;
String locationText = document.findNodeAt(document.offsetAt(diagnostic.getRange().getEnd())).getAttribute("location");
if (locationText.contains(BACK_SLASH) && locationText.contains(FORWARD_SLASH)) {
// if using mismatched slashes, replace all with /
locationText = locationText.replace(BACK_SLASH, FORWARD_SLASH);
} else if (File.separator.equals(BACK_SLASH) && locationText.contains(BACK_SLASH)) {
// if Windows and path using \, continue using it
fileSeparator = BACK_SLASH;
}
String replaceText = "location=\"" + locationText + fileSeparator + "\"";
String replaceText = getReplaceText(fileSeparator, locationText);
codeActions.add(CodeActionFactory.replace(CODEACTION_TITLE, diagnostic.getRange(), replaceText, document.getTextDocument(), diagnostic));
} catch (Exception e) {
// do nothing
LOGGER.warning("Could not generate code action for adding trailing slash." + e);
}
}

/**
* Gets replace text based on OS and slash usage
* @param fileSeparator
* @param locationText
* @return
*/
public static String getReplaceText(String fileSeparator, String locationText) {
if (locationText.contains(BACK_SLASH) && locationText.contains(FORWARD_SLASH)) {
// if using mismatched slashes, replace all with /
locationText = locationText.replace(BACK_SLASH, FORWARD_SLASH);
} else if (File.separator.equals(BACK_SLASH) && locationText.contains(BACK_SLASH)) {
// if Windows and path using \, continue using it
fileSeparator = BACK_SLASH;
}
String replaceText = "location=\"" + locationText + fileSeparator + "\"";
return replaceText;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package io.openliberty.tools.langserver.lemminx.codeactions;
evie-lau marked this conversation as resolved.
Show resolved Hide resolved

import java.util.List;
import java.util.logging.Logger;

import org.eclipse.lemminx.commons.CodeActionFactory;
import org.eclipse.lemminx.dom.DOMDocument;
Expand All @@ -23,6 +24,7 @@
import org.eclipse.lsp4j.jsonrpc.CancelChecker;

public class RemoveTrailingSlash implements ICodeActionParticipant {
private static final Logger LOGGER = Logger.getLogger(RemoveTrailingSlash.class.getName());

public static final String CODEACTION_TITLE = "Remove trailing slash to specify file.";
@Override
Expand All @@ -34,7 +36,7 @@ public void doCodeAction(ICodeActionRequest request, List<CodeAction> codeAction
String replaceText = "location=\"" + locationText.substring(0, locationText.length()-1) + "\"";
codeActions.add(CodeActionFactory.replace(CODEACTION_TITLE, diagnostic.getRange(), replaceText, document.getTextDocument(), diagnostic));
} catch (Exception e) {
// do nothing
LOGGER.warning("Could not generate code action for removing trailing slash." + e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package io.openliberty;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;

import org.junit.jupiter.api.Test;

import io.openliberty.tools.langserver.lemminx.codeactions.AddTrailingSlash;
import io.openliberty.tools.langserver.lemminx.codeactions.IndentUtil;

public class CodeActionUtilitiesTest {
Expand All @@ -30,4 +35,32 @@ public void indentTabsTest() {
String expectedText = System.lineSeparator() + indent + indent + "<feature>test<feature>";
assertEquals(expectedText, IndentUtil.formatText(sampleText, indent, column), "Incorrect whitespace buffer calculation.");
}

/**
* Test that a location string with mismatched slashes will be converted to all to forward slashes
*/
@Test
public void slashConversionTest() {
String fileSeparator = "/";
String locationText = "..\\../test.xml";
String replaceText = AddTrailingSlash.getReplaceText(fileSeparator, locationText);
assertFalse(replaceText.contains("\\"));
assertTrue(replaceText.endsWith("/\"")); // ends with /"
}

/**
* Windows test that backslashes will be retained if it was the only type of slash used
*/
@Test
public void retainWindowsBackSlash() {
if (!File.separator.equals("\\")) {
return;
}
String fileSeparator = "/";
String locationText = "..\\..\\test.xml";
String replaceText = AddTrailingSlash.getReplaceText(fileSeparator, locationText);
assertTrue(replaceText.contains("\\"));
assertFalse(replaceText.contains("/"));
assertTrue(replaceText.endsWith("\\\"")); // ends with \"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ public void testDiagnosticsForInclude() throws IOException {
missing_xml2.setCode("missing_file");
missing_xml2.setMessage("The resource at the specified location could not be found.");

// test dir not file? might be hard to test...
Diagnostic dirIsFile = new Diagnostic();
dirIsFile.setRange(r(8, 13, 8, 42));
dirIsFile.setCode("is_file_not_dir");
Expand All @@ -213,6 +212,43 @@ public void testDiagnosticsForInclude() throws IOException {
dirIsFile, fileIsDir);
}

@Test
public void testDiagnosticsForIncludeWindows() {
if (!File.separator.equals("\\")) { // skip test if not Windows
return;
}
// LibertyWorkspace must be initialized
List<WorkspaceFolder> initList = new ArrayList<WorkspaceFolder>();
initList.add(new WorkspaceFolder(new File("src/test/resources").toURI().toString()));
LibertyProjectsManager.getInstance().setWorkspaceFolders(initList);

String serverXML = String.join(newLine, //
"<server description=\"default server\">", //
" <include location=\"\\empty_server.xml\\\"/>", //
" <include location=\"\\testDir.xml\"/>", //
"</server>"
);

// Diagnostic location1 = new Diagnostic();
File serverXMLFile = new File("src/test/resources/server.xml");
assertFalse(serverXMLFile.exists());
// Diagnostic will not be made if found
assertTrue(new File("src/test/resources/empty_server.xml").exists());

Diagnostic dirIsFile = new Diagnostic();
dirIsFile.setRange(r(1, 13, 1, 42));
dirIsFile.setCode("is_file_not_dir");
dirIsFile.setMessage("Path specified a directory, but resource exists as a file. Please remove the trailing slash.");

Diagnostic fileIsDir = new Diagnostic();
fileIsDir.setRange(r(2, 13, 2, 36));
fileIsDir.setCode("is_dir_not_file");
fileIsDir.setMessage("Path specified a file, but resource exists as a directory. Please add a trailing slash.");

XMLAssert.testDiagnosticsFor(serverXML, null, null, serverXMLFile.toURI().toString(),
evie-lau marked this conversation as resolved.
Show resolved Hide resolved
dirIsFile, fileIsDir);
}

@Test
public void testConfigElementMissingFeatureManager() throws JAXBException {
assertTrue(featureList.exists());
Expand Down