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

#227 Better code completion proposal for name/key of additional properties #402

Merged
merged 28 commits into from
Oct 6, 2017
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9b18047
#227 - use schema name for code-assist for additionalProperties
tfesenko Sep 26, 2017
e839fab
#227 - code assist: select the schema name for the additionalProperti…
tfesenko Sep 26, 2017
e027674
Fix compilation errors in tests
tfesenko Sep 26, 2017
522b4b3
#227 - generate named schema templates from inline schema templates
tfesenko Sep 26, 2017
1bc87dc
Merge branch 'master' into task/227
tfesenko Sep 27, 2017
833d212
#227 - clean up code for the 'additionalProperties' code assist, cust…
tfesenko Sep 27, 2017
9194da2
Manually merge master into task/227
tfesenko Sep 29, 2017
1a46dc0
Manually merge master into task/227
tfesenko Sep 29, 2017
a3e7351
#227 - use '(schema name)' as a proposal for the elements described b…
tfesenko Oct 2, 2017
6360421
#227 - fix reference type provider for cases when a reference node al…
tfesenko Oct 2, 2017
fd8c537
#227 - fix test failures in CodeTemplateTextTest (named schema templa…
tfesenko Oct 2, 2017
2ee8900
#227 - add dynamic code templates for named schema properties + tests
tfesenko Oct 2, 2017
7da4404
#227 - code templates for named schemas should create schema names in…
tfesenko Oct 3, 2017
4e80a49
#227 - restore cursor position for empty selection - it should be at …
tfesenko Oct 3, 2017
b6d8378
#227 - tests for code assist for component keys
tfesenko Oct 3, 2017
a62a95a
#227 - more tests for code assist for the additionalProperties elements
tfesenko Oct 3, 2017
e43d350
#227 - make getTabWidth() reusable
tfesenko Oct 3, 2017
3931b3c
#227 - remove unneeded JSON Schema customizations
tfesenko Oct 3, 2017
648042a
#227 - Fix code assist proposal for named schema properties in Swagge…
tfesenko Oct 4, 2017
919d64d
#227 - regenerate JSON Schema for OAS3
tfesenko Oct 4, 2017
687efbe
Merge branch 'master' into task/227
tfesenko Oct 4, 2017
3575040
Merge branch 'master' into task/227
tfesenko Oct 4, 2017
6ca2f96
#227 - fix tests for code-assist for media types - they don't need a …
tfesenko Oct 4, 2017
f2251a4
Merge branch 'master' into task/227
tfesenko Oct 5, 2017
3a4675d
#227 - test that an anonymous schema in media types does not have a '…
tfesenko Oct 6, 2017
9f2cd7d
#227 - fix a potential NPE
tfesenko Oct 6, 2017
0baa0ab
[#227] Better code completion proposal for name/key of additional pro…
ghillairet Oct 6, 2017
476b653
Merge branch 'master' into task/227
tfesenko Oct 6, 2017
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 @@ -195,10 +195,17 @@ protected Collection<Proposal> createObjectProposals(ObjectTypeDefinition type,
}
}

if (type.getAdditionalProperties() != null) {
String elementTitle = type.getLabel();
String elementName = elementTitle != null? elementTitle : type.getAdditionalProperties().getLabel();
if (elementName != null) {
elementName = String.format("(%s name)", elementName);
proposals.add(new Proposal(elementName + ":", elementName, null, null, elementName));
}
}
if (proposals.isEmpty()) {
proposals.add(new Proposal("_key_" + ":", "_key_", null, null));
}

return proposals;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class Proposal {
public final String displayString;
public final String type;
public final String description;
private final String selection;

protected final Styler typeStyler = new StyledString.Styler() {
@Override
Expand All @@ -38,11 +39,16 @@ public void applyStyles(TextStyle textStyle) {
}
};

public Proposal(String replacementString, String displayString, String description, String type) {
public Proposal(String replacementString, String displayString, String description, String type, String selection) {
this.replacementString = replacementString;
this.displayString = displayString;
this.type = type;
this.description = description;
this.selection = selection;
}

public Proposal(String replacementString, String displayString, String description, String type) {
this(replacementString, displayString, description, type, "");
}

/**
Expand Down Expand Up @@ -93,9 +99,10 @@ public StyledCompletionProposal asStyledCompletionProposal(String prefix, int of

StyledCompletionProposal proposal = null;
if (Strings.emptyToNull(prefix) == null) {
proposal = new StyledCompletionProposal(replacementString, styledString, null, description, offset);
proposal = new StyledCompletionProposal(replacementString, styledString, null, description, offset,
selection);
} else if (rString.toLowerCase().contains(prefix.toLowerCase())) {
proposal = new StyledCompletionProposal(rString, styledString, prefix, description, offset);
proposal = new StyledCompletionProposal(rString, styledString, prefix, description, offset, selection);
}

return proposal;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ public class StyledCompletionProposal
private final String description;
/** Lower-cased prefix - content assist typeahead should be case-insensitive */
private final String prefix;
private final String selection;

public StyledCompletionProposal(String replacement, StyledString label, String prefix, String description,
int offset) {
int offset, String selection) {
this.label = label;
this.replacementString = replacement;
this.selection = selection == null ? "" : selection;
this.prefix = prefix != null ? prefix.toLowerCase() : null;
this.replacementOffset = offset;
this.description = description;
Expand Down Expand Up @@ -82,10 +84,9 @@ public Point getSelection(IDocument document) {
offset = replacementOffset - prefix.length();
}
}

int cursorPosition = offset + replacementString.length();

return new Point(cursorPosition, 0);
int replacementIndex = !"".equals(selection) ? replacementString.indexOf(selection) : -1;
int selectionStart = offset + (replacementIndex < 0 ? replacementString.length() : replacementIndex);
return new Point(selectionStart, selection.length());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
import java.util.Collection;

import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.JsonNode;
import com.reprezen.swagedit.core.json.references.JsonReference;
import com.reprezen.swagedit.core.model.AbstractNode;
import com.reprezen.swagedit.core.model.Model;
import com.reprezen.swagedit.core.schema.ComplexTypeDefinition;
Expand All @@ -23,13 +23,13 @@

public class ComponentContextType extends ContextType {

private final ObjectNode componentRef;
private final String componentRef;

public ComponentContextType(String value, String label, String componentSchemaPath) {
super(value, label);
componentRef = new ObjectMapper().createObjectNode().put("$ref", "#/definitions/" + componentSchemaPath);
componentRef = "#/definitions/" + componentSchemaPath;
}

protected String getReferencePointerString() {
return "/definitions/reference/properties/$ref";
}
Expand Down Expand Up @@ -73,12 +73,17 @@ protected boolean isReferenceToComponent(Model model, JsonPointer pointer) {
if (parentType instanceof ComplexTypeDefinition) {
Collection<TypeDefinition> types = ((ComplexTypeDefinition) parentType).getComplexTypes();
for (TypeDefinition type : types) {
if (componentRef.equals(type.getContent())) {
if (hasRefToComponent(type.getContent())) {
return true;
}
}
}
return componentRef.equals(parentType.getContent());
return hasRefToComponent(parentType.getContent());
}

private boolean hasRefToComponent(JsonNode content) {
return content.hasNonNull(JsonReference.PROPERTY)
&& componentRef.equals(content.get(JsonReference.PROPERTY).asText());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*******************************************************************************
* Copyright (c) 2016 ModelSolv, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* ModelSolv, Inc. - initial API and implementation and/or initial documentation
*******************************************************************************/
package com.reprezen.swagedit.core.preferences;

import org.dadacoalition.yedit.preferences.PreferenceConstants;
import org.eclipse.jface.preference.IPreferenceStore;

public class KaiZenPreferencesUtils {
public static int getTabWidth() {
IPreferenceStore prefs = org.dadacoalition.yedit.Activator.getDefault().getPreferenceStore();
return prefs.getInt(PreferenceConstants.SPACES_PER_TAB);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
*******************************************************************************/
package com.reprezen.swagedit.core.quickfix;

import static com.reprezen.swagedit.core.preferences.KaiZenPreferencesUtils.getTabWidth;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.dadacoalition.yedit.preferences.PreferenceConstants;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
Expand Down Expand Up @@ -83,10 +83,6 @@ protected String getIndent(IDocument document, int line) throws BadLocationExcep
return definitionIndent + Strings.repeat(" ", getTabWidth());
}

private int getTabWidth() {
IPreferenceStore prefs = org.dadacoalition.yedit.Activator.getDefault().getPreferenceStore();
return prefs.getInt(PreferenceConstants.SPACES_PER_TAB);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.collect.Iterables;
import com.reprezen.swagedit.core.model.AbstractNode;

/**
Expand Down Expand Up @@ -139,4 +140,9 @@ public boolean validate(AbstractNode valueNode) {

return isValid;
}

@Override
public String getLabel() {
return Iterables.getFirst(complexTypes, null).getLabel();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will get a NPE if complexTypes is null here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Addressed in 9f2cd7d

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ protected String baseURI(String href) {
return href.startsWith("#") ? null : href.split("#")[0];
}

protected JsonPointer pointer(String href) {
public static JsonPointer pointer(String href) {
if (href.startsWith("#")) {
return JsonPointer.compile(href.substring(1));
} else if (href.startsWith("/")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*******************************************************************************
* Copyright (c) 2017 ModelSolv, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* ModelSolv, Inc. - initial API and implementation and/or initial documentation
*******************************************************************************/
package com.reprezen.swagedit.core.schema;

import static com.google.common.collect.Iterators.transform;

import java.util.Iterator;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.base.Function;
import com.google.common.base.Joiner;

public class JsonSchemaUtils {
public static String getHumanFriendlyText(JsonNode swaggerSchemaNode, final String defaultValue) {
String schemaTitle = getSchemaTitle(swaggerSchemaNode);
if (schemaTitle != null) {
return schemaTitle;
}
// nested array
if (swaggerSchemaNode.get("items") != null) {
return getHumanFriendlyText(swaggerSchemaNode.get("items"), defaultValue);
}
// "$ref":"#/definitions/headerParameterSubSchema"
JsonNode ref = swaggerSchemaNode.get("$ref");
if (ref != null) {
return getLabelForRef(ref.asText());
}
// Auxiliary oneOf in "oneOf": [ { "$ref": "#/definitions/securityRequirement" }]
JsonNode oneOf = swaggerSchemaNode.get("oneOf");
if (oneOf != null) {
if (oneOf instanceof ArrayNode) {
ArrayNode arrayNode = (ArrayNode) oneOf;
if (arrayNode.size() > 0) {
Iterator<String> labels = transform(arrayNode.elements(), new Function<JsonNode, String>() {

@Override
public String apply(JsonNode el) {
return getHumanFriendlyText(el, defaultValue);
}
});
return "[" + Joiner.on(", ").join(labels) + "]";
}
}
}
return defaultValue;
}

public static String getSchemaTitle(JsonNode swaggerSchemaNode) {
JsonNode title = swaggerSchemaNode.get("title");
if (title != null) {
return title.asText();
}
return null;
}

public static String getLabelForRef(String refValue) {
return refValue.substring(refValue.lastIndexOf("/") + 1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,18 @@ public TypeDefinition getPropertyType(String property) {
public boolean validate(AbstractNode valueNode) {
return resolve().validate(valueNode);
}

@Override
public String getLabel() {
String label = JsonSchemaUtils.getSchemaTitle(content);
if (label != null) {
return label;
}
// $ref=schemaOrReference
if (resolve() instanceof ComplexTypeDefinition) {
return resolve().getLabel();
}
// $ref=schema
return JsonSchemaUtils.getLabelForRef(content.get(JsonReference.PROPERTY).asText());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@ public String getDescription() {
}
return content.get("description").asText();
}

/**
* Human-friendly label which can be used in GUI.
* It does not intent to provide complete information about a type,
* just a concise label.</br>
* Subclasses are welcome to override this method.
* </br>
* Can return null.
*/
public String getLabel() {
if (content == null) {
return null;
}
return JsonSchemaUtils.getHumanFriendlyText(content, null);
}

@Override
public String toString() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2016 ModelSolv, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* ModelSolv, Inc. - initial API and implementation and/or initial documentation
*******************************************************************************/
package com.reprezen.swagedit.core.templates;

import java.util.List;

import org.eclipse.jface.text.templates.TemplateContext;
import org.eclipse.jface.text.templates.TemplateVariable;
import org.eclipse.jface.text.templates.TemplateVariableResolver;

/**
* Standard code template variables can only define values that are valid variables, e.g. no space allowed. </br>
* This template variable resolver provides a way to create and select names with special characters (whitespaces, '(', ')') in code templates. For
* example, `${element_name:element_name('(schema name)')}` creates `(schema name)` and selects it for editing.
*
*/
public class ElementNameResolver extends TemplateVariableResolver {
public ElementNameResolver() {
super("element_name", "Provides human-friendly element name and selects it");
}

@Override
public void resolve(TemplateVariable variable, TemplateContext context) {
List params = variable.getVariableType().getParams();
String[] bindings = new String[params.size()];
for (int i = 0; i < params.size(); i++) {
bindings[i] = params.get(i).toString();
}
if (bindings.length != 0)
variable.setValues(bindings);
variable.setResolved(true);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ private void addGlobalResolvers() {
addResolver(new GlobalTemplateVariables.Year());
addResolver(new GlobalTemplateVariables.Time());
addResolver(new GlobalTemplateVariables.User());
addResolver(new ElementNameResolver());
}

}
Loading