use of com.redhat.qute.parser.template.Section in project quarkus-ls by redhat-developer.
the class QuteCompletions method doComplete.
/**
* Returns completion list for the given position
*
* @param template the Qute template
* @param position the position where completion was triggered
* @param completionSettings the completion settings.
* @param formattingSettings the formatting settings.
* @param cancelChecker the cancel checker
* @return completion list for the given position
*/
public CompletableFuture<CompletionList> doComplete(Template template, Position position, QuteCompletionSettings completionSettings, QuteFormattingSettings formattingSettings, CancelChecker cancelChecker) {
CompletionRequest completionRequest = null;
try {
completionRequest = new CompletionRequest(template, position, completionSettings, formattingSettings);
} catch (BadLocationException e) {
LOGGER.log(Level.SEVERE, "Creation of CompletionRequest failed", e);
return EMPTY_FUTURE_COMPLETION;
}
Node node = completionRequest.getNode();
if (node == null) {
return EMPTY_FUTURE_COMPLETION;
}
String text = template.getText();
int offset = completionRequest.getOffset();
if (node.getKind() == NodeKind.Expression || node.getKind() == NodeKind.ExpressionParts || node.getKind() == NodeKind.ExpressionPart) {
Expression expression = null;
Node nodeExpression = null;
if (node.getKind() == NodeKind.Expression) {
expression = (Expression) node;
} else if (node.getKind() == NodeKind.ExpressionParts) {
nodeExpression = node;
expression = ((Parts) node).getParent();
} else if (node.getKind() == NodeKind.ExpressionPart) {
nodeExpression = node;
expression = ((Part) node).getParent().getParent();
}
return completionForExpression.doCompleteExpression(completionRequest, expression, nodeExpression, template, offset, completionSettings, formattingSettings, cancelChecker);
} else if (node.getKind() == NodeKind.Text) {
// The completion is triggered in text node (before node)
Section parent = node.getParentSection();
if (parent != null && (parent.isInEndTagName(offset))) {
// The completion is triggered inside end tag
return EMPTY_FUTURE_COMPLETION;
}
// The completion is triggered in text node
// Check if completion is triggered after a start bracket character and if it's
// a valid expression
int nbBrackets = 0;
int bracketOffset = offset - 1;
char previousChar = text.charAt(bracketOffset);
if (previousChar == '#') {
// {#
bracketOffset--;
}
while (bracketOffset >= 0 && text.charAt(bracketOffset) == '{') {
bracketOffset--;
nbBrackets++;
}
if (nbBrackets > 0) {
if (nbBrackets % 2 != 0) {
// The completion is triggered in text node after bracket '{' character
return completionForExpression.doCompleteExpression(completionRequest, null, node, template, offset, completionSettings, formattingSettings, cancelChecker);
}
return EMPTY_FUTURE_COMPLETION;
}
} else if (node.getKind() == NodeKind.ParameterDeclaration) {
return completionsForParameterDeclaration.doCollectJavaClassesSuggestions((ParameterDeclaration) node, template, offset, completionSettings);
} else if (node.getKind() == NodeKind.Section) {
// {#|}
return completionForTagSection.doCompleteTagSection(completionRequest, completionSettings, formattingSettings, cancelChecker);
}
return collectSnippetSuggestions(completionRequest);
}
use of com.redhat.qute.parser.template.Section in project quarkus-ls by redhat-developer.
the class QuteDiagnostics method validateDataModel.
private void validateDataModel(Node parent, Template template, QuteValidationSettings validationSettings, ResolvingJavaTypeContext resolvingJavaTypeContext, ResolutionContext currentContext, List<Diagnostic> diagnostics) {
ResolutionContext previousContext = currentContext;
List<Node> children = parent.getChildren();
for (Node node : children) {
switch(node.getKind()) {
case ParameterDeclaration:
{
ParameterDeclaration parameter = (ParameterDeclaration) node;
String javaTypeToResolve = parameter.getJavaType();
if (!StringUtils.isEmpty(javaTypeToResolve)) {
String projectUri = template.getProjectUri();
if (projectUri != null) {
List<JavaTypeRangeOffset> classNameRanges = parameter.getJavaTypeNameRanges();
for (RangeOffset classNameRange : classNameRanges) {
String className = template.getText(classNameRange);
ResolvedJavaTypeInfo resolvedJavaType = resolveJavaType(className, projectUri, resolvingJavaTypeContext);
if (resolvedJavaType == null) {
// Java type doesn't exist
Range range = QutePositionUtility.createRange(classNameRange, template);
Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, QuteErrorCode.UnknownType, className);
diagnostics.add(diagnostic);
} else if (!isResolvingJavaType(resolvedJavaType)) {
currentContext.put(javaTypeToResolve, resolvedJavaType);
}
}
}
}
break;
}
case Section:
{
Section section = (Section) node;
if (canChangeContext(section)) {
currentContext = new ResolutionContext(currentContext);
}
List<Parameter> parameters = section.getParameters();
// validate expression parameters
for (Parameter parameter : parameters) {
Expression expression = parameter.getJavaTypeExpression();
if (expression != null) {
ResolvedJavaTypeInfo result = validateExpression(expression, section, template, validationSettings, previousContext, resolvingJavaTypeContext, diagnostics);
switch(section.getSectionKind()) {
case FOR:
case EACH:
String alias = ((LoopSection) section).getAlias();
currentContext.put(alias, result);
break;
case WITH:
currentContext.setWithObject(result);
break;
case LET:
case SET:
currentContext.put(parameter.getName(), result);
break;
default:
}
}
}
switch(section.getSectionKind()) {
case INCLUDE:
validateIncludeSection((IncludeSection) section, diagnostics);
break;
default:
validateSectionTag(section, template, resolvingJavaTypeContext, diagnostics);
}
break;
}
case Expression:
{
validateExpression((Expression) node, null, template, validationSettings, previousContext, resolvingJavaTypeContext, diagnostics);
break;
}
default:
}
validateDataModel(node, template, validationSettings, resolvingJavaTypeContext, currentContext, diagnostics);
}
}
use of com.redhat.qute.parser.template.Section in project quarkus-ls by redhat-developer.
the class QuteDocumentLink method findDocumentLinks.
private void findDocumentLinks(Node node, Template template, List<DocumentLink> links) {
List<Node> children = node.getChildren();
for (Node child : children) {
if (child.getKind() == NodeKind.Section) {
Section section = (Section) child;
if (section.getSectionKind() == SectionKind.INCLUDE) {
// #include section case:
IncludeSection includeSection = (IncludeSection) section;
// {#include base.qute.html}
// In this case 'base.qute.html' is a document link
Parameter includedTemplateId = includeSection.getParameterAtIndex(0);
if (includedTemplateId != null) {
Range range = QutePositionUtility.createRange(includedTemplateId.getStart(), includedTemplateId.getEnd(), template);
if (range != null) {
Path templateFile = includeSection.getReferencedTemplateFile();
if (templateFile != null) {
String target = templateFile.toUri().toString();
links.add(new DocumentLink(range, target != null ? target : ""));
}
}
}
}
}
findDocumentLinks(child, template, links);
}
}
use of com.redhat.qute.parser.template.Section in project quarkus-ls by redhat-developer.
the class QuteHover method doHoverForSection.
private CompletableFuture<Hover> doHoverForSection(Section section, Template template, HoverRequest hoverRequest, CancelChecker cancelChecker) {
if (section.hasTag()) {
// the section defines a tag (e : {#for
String tagName = section.getTag();
if (section.getSectionKind() == SectionKind.CUSTOM) {
// custom tag: search information about user tag
QuteProject project = template.getProject();
if (project != null) {
UserTag userTag = project.findUserTag(tagName);
if (userTag != null) {
Range range = createSectionTagRange(section, hoverRequest);
if (range != null) {
boolean hasMarkdown = hoverRequest.canSupportMarkupKind(MarkupKind.MARKDOWN);
MarkupContent content = DocumentationUtils.getDocumentation(userTag, hasMarkdown);
Hover hover = new Hover(content, range);
return CompletableFuture.completedFuture(hover);
}
}
}
} else {
// core tag like #for, #if, etc: display document hover for the section
Optional<Snippet> snippetSection = //
snippetRegistryProvider.getSnippetRegistry().getSnippets().stream().filter(//
snippet -> tagName.equals(snippet.getLabel())).findFirst();
if (snippetSection.isPresent()) {
Snippet snippet = snippetSection.get();
Range range = createSectionTagRange(section, hoverRequest);
if (range != null) {
boolean hasMarkdown = hoverRequest.canSupportMarkupKind(MarkupKind.MARKDOWN);
MarkupContent content = DocumentationUtils.getDocumentation(snippet, hasMarkdown);
Hover hover = new Hover(content, range);
return CompletableFuture.completedFuture(hover);
}
}
}
}
return NO_HOVER;
}
use of com.redhat.qute.parser.template.Section in project quarkus-ls by redhat-developer.
the class JavaDataModelCache method resolveJavaType.
private CompletableFuture<ResolvedJavaTypeInfo> resolveJavaType(ObjectPart objectPart, String projectUri, boolean nullIfDontMatchWithIterable) {
CompletableFuture<ResolvedJavaTypeInfo> future = null;
JavaTypeInfoProvider javaTypeInfo = objectPart.resolveJavaType();
if (javaTypeInfo == null) {
return RESOLVED_JAVA_TYPE_INFO_NULL_FUTURE;
}
String javaType = javaTypeInfo.getJavaType();
if (StringUtils.isEmpty(javaType)) {
Expression expression = javaTypeInfo.getJavaTypeExpression();
if (expression != null) {
String literalJavaType = expression.getLiteralJavaType();
if (literalJavaType != null) {
future = resolveJavaType(literalJavaType, projectUri);
} else {
Part lastPart = expression.getLastPart();
if (lastPart == null) {
return RESOLVED_JAVA_TYPE_INFO_NULL_FUTURE;
}
future = resolveJavaType(lastPart, projectUri);
}
}
}
if (future == null) {
future = resolveJavaType(javaType, projectUri);
}
Node node = javaTypeInfo.getJavaTypeOwnerNode();
Section section = getOwnerSection(node);
if (section != null) {
if (section.isIterable()) {
future = //
future.thenCompose(resolvedType -> {
if (resolvedType == null) {
return RESOLVED_JAVA_TYPE_INFO_NULL_FUTURE;
}
if (!resolvedType.isIterable()) {
if (resolvedType.isInteger()) {
// {/for}
return resolveJavaType(resolvedType.getName(), projectUri);
}
if (nullIfDontMatchWithIterable) {
// {item.|}
return RESOLVED_JAVA_TYPE_INFO_NULL_FUTURE;
}
}
// valid case
// Ex:
// {@java.util.List<org.acme.Item> items}
// {#for item in items}
// {item.|}
// Here
// - resolvedType = java.util.List<org.acme.Item>
// - iterTypeName = org.acme.Item
// Resolve org.acme.Item
String iterTypeName = resolvedType.getIterableOf();
return resolveJavaType(iterTypeName, projectUri);
});
}
}
return future;
}
Aggregations