Skip to content

Commit

Permalink
Manage snippet registry to write snippet in JSON
Browse files Browse the repository at this point in the history
Fixes eclipse-lemminx#640

Signed-off-by: azerr <azerr@redhat.com>
  • Loading branch information
angelozerr committed May 7, 2020
1 parent f12cf5d commit 958ab51
Show file tree
Hide file tree
Showing 31 changed files with 1,844 additions and 448 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2020 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lemminx.commons.snippets;

import java.util.Map;

/**
* Snippet context used to filter the snippet.
*
* @author Angelo ZERR
*
* @param <T> the value type waited by the snippet context.
*/
public interface ISnippetContext<T> {

/**
* Return true if the given value match the snippet context and false otherwise.
*
* @param value the value to check.
* @return true if the given value match the snippet context and false
* otherwise.
*/
boolean isMatch(T value, Map<String, String> model);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2020 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lemminx.commons.snippets;

/**
* Loader used to load snippets in a given registry for a language id.
*
* @author Angelo ZERR
*
*/
public interface ISnippetRegistryLoader {

/**
* Register snippets in the given snippet registry.
*
* @param registry
* @throws Exception
*/
void load(SnippetRegistry registry) throws Exception;

/**
* Returns the language id and null otherwise.
*
* @return the language id and null otherwise.
*/
default String getLanguageId() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (c) 2020 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lemminx.commons.snippets;

import java.util.List;
import java.util.Map;
import java.util.function.BiPredicate;

/**
* Snippet description (like vscode snippet).
*
* @author Angelo ZERR
*
*/
public class Snippet {

private List<String> prefixes;

private List<String> body;

private String description;

private String scope;

private ISnippetContext<?> context;

public List<String> getPrefixes() {
return prefixes;
}

public void setPrefixes(List<String> prefixes) {
this.prefixes = prefixes;
}

public List<String> getBody() {
return body;
}

public void setBody(List<String> body) {
this.body = body;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public String getScope() {
return scope;
}

public void setScope(String scope) {
this.scope = scope;
}

public ISnippetContext<?> getContext() {
return context;
}

public void setContext(ISnippetContext<?> context) {
this.context = context;
}

public boolean hasContext() {
return getContext() != null;
}

public boolean match(BiPredicate<ISnippetContext<?>, Map<String, String>> contextFilter,
Map<String, String> model) {
if (!hasContext()) {
return true;
}
return contextFilter.test(getContext(), model);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*******************************************************************************
* Copyright (c) 2020 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lemminx.commons.snippets;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.TypeAdapter;

/**
* GSON deserializer to build Snippet from vscode JSON snippet.
*
* @author Angelo ZERR
*
*/
class SnippetDeserializer implements JsonDeserializer<Snippet> {

private static final String PREFIX_ELT = "prefix";
private static final String DESCRIPTION_ELT = "description";
private static final String SCOPE_ELT = "scope";
private static final String BODY_ELT = "body";
private static final String CONTEXT_ELT = "context";

private final TypeAdapter<? extends ISnippetContext<?>> contextDeserializer;

public SnippetDeserializer(TypeAdapter<? extends ISnippetContext<?>> contextDeserializer) {
this.contextDeserializer = contextDeserializer;
}

@Override
public Snippet deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
Snippet snippet = new Snippet();
JsonObject snippetObj = json.getAsJsonObject();

// prefix
List<String> prefixes = new ArrayList<>();
JsonElement prefixElt = snippetObj.get(PREFIX_ELT);
if (prefixElt != null) {
if (prefixElt.isJsonArray()) {
JsonArray prefixArray = (JsonArray) prefixElt;
prefixArray.forEach(elt -> {
prefixes.add(elt.getAsString());
});
} else if (prefixElt.isJsonPrimitive()) {
prefixes.add(prefixElt.getAsString());
}
}
snippet.setPrefixes(prefixes);

// body
List<String> body = new ArrayList<>();
JsonElement bodyElt = snippetObj.get(BODY_ELT);
if (bodyElt != null) {
if (bodyElt.isJsonArray()) {
JsonArray bodyArray = (JsonArray) bodyElt;
bodyArray.forEach(elt -> {
body.add(elt.getAsString());
});
} else if (bodyElt.isJsonPrimitive()) {
body.add(bodyElt.getAsString());
}
}
snippet.setBody(body);

// description
JsonElement descriptionElt = snippetObj.get(DESCRIPTION_ELT);
if (descriptionElt != null) {
String description = descriptionElt.getAsString();
snippet.setDescription(description);
}

// scope
JsonElement scopeElt = snippetObj.get(SCOPE_ELT);
if (scopeElt != null) {
String scope = scopeElt.getAsString();
snippet.setScope(scope);
}

// context
if (contextDeserializer != null) {
JsonElement contextElt = snippetObj.get(CONTEXT_ELT);
if (contextElt != null) {
ISnippetContext<?> snippetContext = contextDeserializer.fromJsonTree(contextElt);
snippet.setContext(snippetContext);
}
}

return snippet;
}

}
Loading

0 comments on commit 958ab51

Please sign in to comment.