Skip to content
Open
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
@@ -0,0 +1,113 @@
/*******************************************************************************
* Copyright (c) 2026 Vogella 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:
* Lars Vogel (Vogella GmbH) - initial implementation
*******************************************************************************/
package org.eclipse.wildwebdeveloper.tests;

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

import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jface.text.IDocument;
import org.eclipse.lsp4e.LSPEclipseUtils;
import org.eclipse.lsp4e.LanguageServers;
import org.eclipse.lsp4e.LanguageServersRegistry;
import org.eclipse.lsp4j.DocumentSymbolParams;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.eclipse.lsp4j.services.LanguageServer;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.tests.harness.util.DisplayHelper;
import org.eclipse.ui.texteditor.AbstractTextEditor;
import org.eclipse.wildwebdeveloper.Activator;
import org.eclipse.wildwebdeveloper.json.JSonLanguageServer;
import org.eclipse.wildwebdeveloper.json.ui.preferences.JSonPreferenceServerConstants;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(AllCleanRule.class)
class TestJSONResultLimitPreference {

private static final int KEYS = 60;
private static final int REDUCED_LIMIT = 5;

private IProject project;

@BeforeEach
void setUpProject() throws Exception {
this.project = ResourcesPlugin.getWorkspace().getRoot().getProject(getClass().getName() + System.nanoTime());
project.create(null);
project.open(null);
}

@AfterEach
void resetPreference() {
Activator.getDefault().getPreferenceStore().setValue(
JSonPreferenceServerConstants.JSON_PREFERENCES_MAXITEMSCOMPUTED,
JSonPreferenceServerConstants.MAXITEMSCOMPUTED_DEFAULT);
}

@Test
void testResultLimitPreferenceAppliesWithoutRestart() throws Exception {
StringBuilder content = new StringBuilder("{\n");
for (int i = 0; i < KEYS; i++) {
content.append(" \"key_").append(i).append("\": ").append(i).append(i == KEYS - 1 ? "\n" : ",\n");
}
content.append("}\n");

IFile file = project.getFile("limit.json");
file.create(content.toString().getBytes(StandardCharsets.UTF_8), true, false, null);

AbstractTextEditor editor = (AbstractTextEditor) IDE.openEditor(
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), file,
"org.eclipse.ui.genericeditor.GenericEditor");
IDocument document = LSPEclipseUtils.getDocument(editor);
DisplayHelper.sleep(2000);

assertEquals(KEYS, countSymbols(document), "Default limit should not truncate this document");

Activator.getDefault().getPreferenceStore()
.setValue(JSonPreferenceServerConstants.JSON_PREFERENCES_MAXITEMSCOMPUTED, REDUCED_LIMIT);
DisplayHelper.sleep(1500); // allow the asynchronous preference broadcast

// exact, so that an empty result does not silently satisfy the assertion
assertEquals(REDUCED_LIMIT, countSymbols(document),
"Lowering the limit should truncate the outline to exactly that many symbols");
}

private static int countSymbols(IDocument document) throws Exception {
DocumentSymbolParams params = new DocumentSymbolParams(
new TextDocumentIdentifier(LSPEclipseUtils.toUri(document).toString()));
return jsonLanguageServer(document).getTextDocumentService().documentSymbol(params).get(10, TimeUnit.SECONDS)
.size();
}

private static LanguageServer jsonLanguageServer(IDocument document) throws Exception {
return LanguageServers.forDocument(document) //
.withCapability(ServerCapabilities::getDocumentSymbolProvider) //
.collectAll((wrapper, ls) -> CompletableFuture.completedFuture( //
LanguageServersRegistry.getInstance()
.getDefinition(JSonLanguageServer.JSON_LANGUAGE_SERVER_ID)
.equals(wrapper.serverDefinition) ? ls : null)) //
.get(10, TimeUnit.SECONDS).stream() //
.filter(Objects::nonNull) //
.findFirst() //
.orElseThrow(() -> new AssertionError("Expected a running JSON language server for the document"));
}
}
4 changes: 3 additions & 1 deletion org.eclipse.wildwebdeveloper/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ Export-Package: org.eclipse.wildwebdeveloper;x-friends:="org.eclipse.wildwebdeve
org.eclipse.wildwebdeveloper.debug.npm;x-internal:=true,
org.eclipse.wildwebdeveloper.markdown;x-friends:="org.eclipse.wildwebdeveloper.tests",
org.eclipse.wildwebdeveloper.jsts;x-friends:="org.eclipse.wildwebdeveloper.tests",
org.eclipse.wildwebdeveloper.jsts.ui.preferences;x-friends:="org.eclipse.wildwebdeveloper.tests"
org.eclipse.wildwebdeveloper.jsts.ui.preferences;x-friends:="org.eclipse.wildwebdeveloper.tests",
org.eclipse.wildwebdeveloper.json;x-friends:="org.eclipse.wildwebdeveloper.tests",
org.eclipse.wildwebdeveloper.json.ui.preferences;x-friends:="org.eclipse.wildwebdeveloper.tests"
2 changes: 2 additions & 0 deletions org.eclipse.wildwebdeveloper/plugin.properties
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ JSTSFormatterPreferencePage.name=Formatter

# Markdown
MarkdownPreferencePage.name=Markdown (Wild Web Developer)
JSonPreferencePage.name=JSON (Wild Web Developer)
MarkdownProblem=Markdown Problem

# YAML
Expand All @@ -69,3 +70,4 @@ preferenceKeywords.scss=scss
preferenceKeywords.sass=sass
preferenceKeywords.html=html
preferenceKeywords.markdown=markdown
preferenceKeywords.json=json
14 changes: 14 additions & 0 deletions org.eclipse.wildwebdeveloper/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,19 @@
</contentTypeMapping>
</extension>

<extension point="org.eclipse.ui.preferencePages">
<page class="org.eclipse.wildwebdeveloper.json.ui.preferences.JSonPreferencePage"
id="org.eclipse.wildwebdeveloper.json.ui.preferences.JSonPreferencePage"
name="%JSonPreferencePage.name">
<keywordReference id="org.eclipse.wildwebdeveloper.json" />
</page>
</extension>
<extension point="org.eclipse.core.runtime.preferences"
id="JSonPreferenceInitializer"
name="JSonPreferenceInitializer">
<initializer class="org.eclipse.wildwebdeveloper.json.ui.preferences.JSonPreferenceInitializer" />
</extension>

<!-- Markdown Language -->
<extension point="org.eclipse.lsp4e.languageServer">
<server id="org.eclipse.wildwebdeveloper.markdown"
Expand Down Expand Up @@ -1092,6 +1105,7 @@
</extension>
<extension point="org.eclipse.ui.keywords">
<keyword label="%preferenceKeywords.yaml" id="org.eclipse.wildwebdeveloper.yaml" />
<keyword label="%preferenceKeywords.json" id="org.eclipse.wildwebdeveloper.json" />
<keyword label="%preferenceKeywords.js" id="org.eclipse.wildwebdeveloper.js" />
<keyword label="%preferenceKeywords.ts" id="org.eclipse.wildwebdeveloper.ts" />
<keyword label="%preferenceKeywords.javascript" id="org.eclipse.wildwebdeveloper.javascript" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import org.eclipse.lsp4e.LanguageServers;
import org.eclipse.lsp4e.LanguageServersRegistry;
import org.eclipse.lsp4e.LanguageServersRegistry.LanguageServerDefinition;
import org.eclipse.lsp4e.server.ProcessStreamConnectionProvider;
import org.eclipse.lsp4j.DidChangeConfigurationParams;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.jsonrpc.messages.Message;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
Expand All @@ -46,20 +46,26 @@
import org.eclipse.wildwebdeveloper.SchemaAssociationRegistry;
import org.eclipse.wildwebdeveloper.SchemaAssociationsPreferenceInitializer;
import org.eclipse.wildwebdeveloper.embedder.node.NodeJSManager;
import org.eclipse.wildwebdeveloper.json.ui.preferences.JSonPreferenceServerConstants;
import org.eclipse.wildwebdeveloper.ui.preferences.ProcessStreamConnectionProviderWithPreference;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

@SuppressWarnings("restriction")
public class JSonLanguageServer extends ProcessStreamConnectionProvider {
public class JSonLanguageServer extends ProcessStreamConnectionProviderWithPreference {

public final static String SCHEMA_EXT = "org.eclipse.wildwebdeveloper.json.schema"; //$NON-NLS-1$
public final static String PATTERN_ATTR = "pattern"; //$NON-NLS-1$
public final static String URL_ATTR = "url"; //$NON-NLS-1$

public static final String JSON_LANGUAGE_SERVER_ID = "org.eclipse.wildwebdeveloper.json"; //$NON-NLS-1$

private static final String[] SUPPORTED_SECTIONS = { "json" }; //$NON-NLS-1$

private static final IPreferenceStore PREFERENCE_STORE = Activator.getDefault().getPreferenceStore();
private static final LanguageServerDefinition JSON_LS_DEFINITION = LanguageServersRegistry.getInstance()
.getDefinition("org.eclipse.wildwebdeveloper.json");
.getDefinition(JSON_LANGUAGE_SERVER_ID);
private static final IPropertyChangeListener PROPERTY_CHANGE_LISTENER = new IPropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
Expand All @@ -74,6 +80,7 @@ public void propertyChange(PropertyChangeEvent event) {
};

public JSonLanguageServer() {
super(JSON_LANGUAGE_SERVER_ID, PREFERENCE_STORE, SUPPORTED_SECTIONS);
List<String> commands = new ArrayList<>();
commands.add(NodeJSManager.getNodeJsLocation().getAbsolutePath());
try {
Expand All @@ -96,10 +103,16 @@ public void handleMessage(Message message, LanguageServer languageServer, URI ro
// Language server side.
JSonLanguageServerInterface server = (JSonLanguageServerInterface) languageServer;
server.sendJSonchemaAssociations(getSchemaAssociations());
server.getWorkspaceService().didChangeConfiguration(new DidChangeConfigurationParams(createSettings()));
}
}
}

@Override
protected Object createSettings() {
return JSonPreferenceServerConstants.getGlobalSettings();
}

private static Map<String, List<String>> getSchemaAssociations() {
Map<String, List<String>> associations = new HashMap<>();
fillSchemaAssociationsFromPreferenceStore(associations);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2026 Vogella 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:
* Lars Vogel (Vogella GmbH) - initial implementation
*******************************************************************************/
package org.eclipse.wildwebdeveloper.json.ui;

import org.eclipse.osgi.util.NLS;

/**
* JSON messages keys.
*
*/
public class Messages extends NLS {

// --------- JSON Main preference page
public static String JSonPreferencePage_maxItemsComputed;

static {
NLS.initializeMessages("org.eclipse.wildwebdeveloper.json.ui.messages", Messages.class); //$NON-NLS-1$
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#/*******************************************************************************
# * Copyright (c) 2026 Vogella 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:
# * Lars Vogel (Vogella GmbH) - initial implementation
# *******************************************************************************/

# Preference main page
JSonPreferencePage_maxItemsComputed=The maximum number of outline symbols and folding\nregions computed (limited for performance reasons, 0 means no limit).
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2026 Vogella 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:
* Lars Vogel (Vogella GmbH) - initial implementation
*******************************************************************************/
package org.eclipse.wildwebdeveloper.json.ui.preferences;

import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;

/**
* JSON preference initializer.
*
*/
public class JSonPreferenceInitializer extends AbstractPreferenceInitializer {

@Override
public void initializeDefaultPreferences() {
JSonPreferenceServerConstants.initializeDefaultPreferences();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*******************************************************************************
* Copyright (c) 2026 Vogella 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:
* Lars Vogel (Vogella GmbH) - initial implementation
*******************************************************************************/
package org.eclipse.wildwebdeveloper.json.ui.preferences;

import static org.eclipse.wildwebdeveloper.json.ui.preferences.JSonPreferenceServerConstants.JSON_PREFERENCES_MAXITEMSCOMPUTED;

import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IntegerFieldEditor;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.wildwebdeveloper.Activator;
import org.eclipse.wildwebdeveloper.json.ui.Messages;

/**
* JSON main preference page.
*
*/
public class JSonPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {

public JSonPreferencePage() {
super(GRID);
}

@Override
public void init(IWorkbench workbench) {
setPreferenceStore(Activator.getDefault().getPreferenceStore());
}

@Override
protected void createFieldEditors() {
IntegerFieldEditor maxItemsComputed = new IntegerFieldEditor(JSON_PREFERENCES_MAXITEMSCOMPUTED,
Messages.JSonPreferencePage_maxItemsComputed, getFieldEditorParent());
maxItemsComputed.setValidRange(0, Integer.MAX_VALUE);
addField(maxItemsComputed);
}

}
Loading