use of org.springframework.ide.vscode.boot.metadata.types.Type in project sts4 by spring-projects.
the class TypeUtilTest method testGetEnumKeyedProperties.
@Test
public void testGetEnumKeyedProperties() throws Exception {
useProject("enums-boot-1.3.2-app");
Type data = TypeParser.parse("java.util.Map<demo.Color,Something>");
assertType("Something", getPropertyType(data, "red"));
assertType("Something", getPropertyType(data, "green"));
assertType("Something", getPropertyType(data, "blue"));
assertType("Something", getPropertyType(data, "RED"));
assertType("Something", getPropertyType(data, "GREEN"));
assertType("Something", getPropertyType(data, "BLUE"));
assertNull(getPropertyType(data, "not-a-color"));
}
use of org.springframework.ide.vscode.boot.metadata.types.Type in project sts4 by spring-projects.
the class PropertiesCompletionProposalsCalculator method getFuzzyCompletions.
protected Collection<ICompletionProposal> getFuzzyCompletions() {
final String prefix = fuzzySearchPrefix.getPrefix(doc, offset);
if (prefix != null) {
Collection<Match<PropertyInfo>> matches = findMatches(prefix);
if (matches != null && !matches.isEmpty()) {
ArrayList<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>(matches.size());
for (final Match<PropertyInfo> match : matches) {
DocumentEdits docEdits;
try {
docEdits = LazyProposalApplier.from(() -> {
try {
Type type = TypeParser.parse(match.data.getType());
DocumentEdits edits = new DocumentEdits(doc);
edits.delete(offset - prefix.length(), offset);
edits.insert(offset, match.data.getId() + propertyCompletionPostfix(typeUtil, type));
return edits;
} catch (Throwable t) {
Log.log(t);
return new DocumentEdits(doc);
}
});
proposals.add(completionFactory.property(doc, docEdits, match, typeUtil));
} catch (Throwable e) {
Log.log(e);
}
}
return proposals;
}
}
return Collections.emptyList();
}
use of org.springframework.ide.vscode.boot.metadata.types.Type in project sts4 by spring-projects.
the class PropertiesHoverCalculator method getValueHover.
private Tuple2<Renderable, IRegion> getValueHover(Value value) {
DocumentRegion valueRegion = createRegion(doc, value).trimStart(SPACES).trimEnd(SPACES);
if (valueRegion.getStart() <= offset && offset < valueRegion.getEnd()) {
String valueString = valueRegion.toString();
String propertyName = value.getParent().getKey().decode();
Type type = getValueType(index, typeUtil, propertyName);
if (TypeUtil.isSequencable(type)) {
// It is useful to provide content assist for the values in the list when entering a list
type = TypeUtil.getDomainType(type);
}
if (TypeUtil.isClass(type)) {
// Special case. We want to provide hoverinfos more liberally than what's suggested for completions (i.e. even class names
// that are not suggested by the hints because they do not meet subtyping constraints should be hoverable and linkable!
StsValueHint hint = StsValueHint.className(valueString, typeUtil);
if (hint != null) {
return Tuples.of(createRenderable(hint), valueRegion.asRegion());
}
}
// Hack: pretend to invoke content-assist at the end of the value text. This should provide hints applicable to that value
// then show hoverinfo based on that. That way we can avoid duplication a lot of similar logic to compute hoverinfos and hyperlinks.
Collection<StsValueHint> hints = getValueHints(index, typeUtil, valueString, propertyName, EnumCaseMode.ALIASED);
if (hints != null) {
Optional<StsValueHint> hint = hints.stream().filter(h -> valueString.equals(h.getValue())).findFirst();
if (hint.isPresent()) {
return Tuples.of(createRenderable(hint.get()), valueRegion.asRegion());
}
}
}
return null;
}
use of org.springframework.ide.vscode.boot.metadata.types.Type in project sts4 by spring-projects.
the class PropertyNavigator method bracketNavigate.
/**
* Handle bracket navigation into given type, after a bracket at
* was found at given offset. Assumes the type has already been checked to
* be 'bracketable'.
*/
private Type bracketNavigate(int offset, Type type) {
int lbrack = offset;
int rbrack = indexOf(']', lbrack);
if (rbrack < 0) {
problemCollector.accept(problem(ApplicationPropertiesProblemType.PROP_NO_MATCHING_RBRACK, "No matching ']'", offset, 1));
} else {
String indexStr = textBetween(lbrack + 1, rbrack);
if (!indexStr.contains("${")) {
try {
Integer.parseInt(indexStr);
} catch (Exception e) {
problemCollector.accept(problem(ApplicationPropertiesProblemType.PROP_NON_INTEGER_IN_BRACKETS, "Expecting 'Integer' for '[...]' notation '" + textBetween(region.getStart(), lbrack) + "'", lbrack + 1, rbrack - lbrack - 1));
}
}
Type domainType = TypeUtil.getDomainType(type);
return navigate(rbrack + 1, domainType);
}
return null;
}
use of org.springframework.ide.vscode.boot.metadata.types.Type in project sts4 by spring-projects.
the class SpringPropertiesReconcileEngine method reconcile.
@Override
public void reconcile(IDocument doc, IProblemCollector problemCollector) {
FuzzyMap<PropertyInfo> index = fIndexProvider.getIndex(doc);
problemCollector.beginCollecting();
try {
ParseResults results = parser.parse(doc.get());
DuplicateNameChecker duplicateNameChecker = new DuplicateNameChecker(problemCollector);
results.syntaxErrors.forEach(syntaxError -> {
problemCollector.accept(problem(PROP_SYNTAX_ERROR, syntaxError.getMessage(), syntaxError.getOffset(), syntaxError.getLength()));
});
if (index == null || index.isEmpty()) {
// some problem putting information about properties into the index.
return;
}
results.ast.getNodes(KeyValuePair.class).forEach(pair -> {
try {
DocumentRegion propertyNameRegion = createRegion(doc, pair.getKey());
String keyName = PropertiesFileEscapes.unescape(propertyNameRegion.toString());
duplicateNameChecker.check(propertyNameRegion);
PropertyInfo validProperty = SpringPropertyIndex.findLongestValidProperty(index, keyName);
if (validProperty != null) {
// in PropertyNavigator (probably these changes are also for the better making it simpler as well)
if (validProperty.isDeprecated()) {
problemCollector.accept(problemDeprecated(propertyNameRegion, validProperty));
}
int offset = validProperty.getId().length() + propertyNameRegion.getStart();
PropertyNavigator navigator = new PropertyNavigator(doc, problemCollector, typeUtilProvider.getTypeUtil(doc), propertyNameRegion);
Type valueType = navigator.navigate(offset, TypeParser.parse(validProperty.getType()));
if (valueType != null) {
reconcileType(doc, valueType, pair.getValue(), problemCollector);
}
} else {
// validProperty==null
// The name is invalid, with no 'prefix' of the name being a valid property name.
PropertyInfo similarEntry = index.findLongestCommonPrefixEntry(propertyNameRegion.toString());
CharSequence validPrefix = commonPrefix(similarEntry.getId(), keyName);
problemCollector.accept(problemUnkownProperty(propertyNameRegion, similarEntry, validPrefix));
}
// end: validProperty==null
} catch (Exception e) {
Log.log(e);
}
});
} catch (Throwable e2) {
Log.log(e2);
} finally {
problemCollector.endCollecting();
}
}
Aggregations