use of com.redhat.qute.commons.ResolvedJavaTypeInfo in project quarkus-ls by redhat-developer.
the class QuteDiagnostics method validateMethodPart.
/**
* Validate the given method part.
*
* @param part the method part to validate.
* @param ownerSection the owner section and null otherwise.
* @param template the template.
* @param projectUri the project Uri.
* @param resolutionContext the resolution context.
* @param baseType the base object type.
* @param iterableOfType the iterable of type.
* @param diagnostics the diagnostic list to fill.
* @param resolvingJavaTypeContext the resolving Java type context.
*
* @return the Java type returned by the member part and null otherwise.
*/
private ResolvedJavaTypeInfo validateMethodPart(MethodPart methodPart, Section ownerSection, Template template, String projectUri, QuteValidationSettings validationSettings, ResolutionContext resolutionContext, ResolvedJavaTypeInfo resolvedJavaType, ResolvedJavaTypeInfo iter, List<Diagnostic> diagnostics, ResolvingJavaTypeContext resolvingJavaTypeContext) {
// Validate parameters of the method part
boolean undefinedType = false;
List<ResolvedJavaTypeInfo> parameterTypes = new ArrayList<>();
for (Parameter parameter : methodPart.getParameters()) {
ResolvedJavaTypeInfo result = null;
Expression expression = parameter.getJavaTypeExpression();
if (expression != null) {
result = validateExpression(expression, ownerSection, template, validationSettings, resolutionContext, resolvingJavaTypeContext, diagnostics);
}
if (result == null) {
undefinedType = true;
}
parameterTypes.add(result);
}
if (undefinedType) {
// One of parameter cannot be resolved as type, teh validation is stopped
return null;
}
// All parameters are resolved, validate the existing of method name according
// to the computed parameter types
String methodName = methodPart.getPartName();
String namespace = methodPart.getNamespace();
JavaMemberResult result = javaCache.findMethod(resolvedJavaType, namespace, methodName, parameterTypes, projectUri);
JavaMethodInfo method = (JavaMethodInfo) result.getMember();
if (method == null) {
QuteErrorCode errorCode = QuteErrorCode.UnknownMethod;
String arg = null;
if (namespace != null) {
// ex :{config.getXXXX()}
errorCode = QuteErrorCode.UnknownNamespaceResolverMethod;
arg = namespace;
} else {
// ex : {@org.acme.Item item}
// {item.getXXXX()}
arg = resolvedJavaType.getSignature();
InvalidMethodReason reason = javaCache.getInvalidMethodReason(methodName, resolvedJavaType, projectUri);
if (reason != null) {
switch(reason) {
case VoidReturn:
errorCode = QuteErrorCode.InvalidMethodVoid;
break;
case Static:
errorCode = QuteErrorCode.InvalidMethodStatic;
break;
case FromObject:
errorCode = QuteErrorCode.InvalidMethodFromObject;
break;
default:
}
}
}
Range range = QutePositionUtility.createRange(methodPart);
Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, errorCode, methodName, arg);
diagnostics.add(diagnostic);
return null;
}
boolean matchVirtualMethod = result.isMatchVirtualMethod();
if (!matchVirtualMethod) {
Range range = QutePositionUtility.createRange(methodPart);
Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, //
QuteErrorCode.InvalidVirtualMethod, //
method.getName(), //
method.getSimpleSourceType(), resolvedJavaType.getJavaElementSimpleType());
diagnostics.add(diagnostic);
return null;
}
boolean matchParameters = result.isMatchParameters();
if (!matchParameters) {
// The method codePointAt(int) in the type String is not applicable for the
// arguments ()
StringBuilder expectedSignature = new StringBuilder("(");
boolean ignoreParameter = method.isVirtual();
for (JavaParameterInfo parameter : method.getParameters()) {
if (!ignoreParameter) {
if (expectedSignature.length() > 1) {
expectedSignature.append(", ");
}
expectedSignature.append(parameter.getJavaElementSimpleType());
}
ignoreParameter = false;
}
expectedSignature.append(")");
expectedSignature.insert(0, method.getName());
StringBuilder actualSignature = new StringBuilder("(");
for (ResolvedJavaTypeInfo parameterType : parameterTypes) {
if (actualSignature.length() > 1) {
actualSignature.append(", ");
}
actualSignature.append(parameterType != null ? parameterType.getJavaElementSimpleType() : parameterType);
}
actualSignature.append(")");
Range range = QutePositionUtility.createRange(methodPart);
Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, //
QuteErrorCode.InvalidMethodParameter, //
expectedSignature.toString(), //
method.getSimpleSourceType(), /* String */
actualSignature.toString());
diagnostics.add(diagnostic);
return null;
}
String memberType = method.resolveJavaElementType(iter);
return validateJavaTypePart(methodPart, ownerSection, projectUri, diagnostics, resolvingJavaTypeContext, memberType);
}
use of com.redhat.qute.commons.ResolvedJavaTypeInfo 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.commons.ResolvedJavaTypeInfo in project quarkus-ls by redhat-developer.
the class QuteDiagnostics method validateExpression.
private ResolvedJavaTypeInfo validateExpression(Expression expression, Section ownerSection, Template template, QuteValidationSettings validationSettings, ResolutionContext resolutionContext, ResolvingJavaTypeContext resolvingJavaTypeContext, List<Diagnostic> diagnostics) {
try {
String projectUri = template.getProjectUri();
String literalJavaType = expression.getLiteralJavaType();
if (literalJavaType != null) {
// The expression is a literal:
// - {'abcd'} : string literal
// - {true} : boolean literal
// - {null} : null literal
// - {123} : integer literal
ResolvedJavaTypeInfo resolvedLiteralType = javaCache.resolveJavaType(literalJavaType, projectUri).getNow(null);
if (resolvedLiteralType == null) {
return null;
}
return validateIterable(expression.getLastPart(), ownerSection, resolvedLiteralType, resolvedLiteralType.getName(), diagnostics);
}
// The expression reference Java data model (ex : {item})
ResolvedJavaTypeInfo resolvedJavaType = null;
List<Node> expressionChildren = expression.getExpressionContent();
for (Node expressionChild : expressionChildren) {
if (expressionChild.getKind() == NodeKind.ExpressionParts) {
Parts parts = (Parts) expressionChild;
resolvedJavaType = validateExpressionParts(parts, ownerSection, template, projectUri, validationSettings, resolutionContext, resolvingJavaTypeContext, diagnostics);
}
}
return resolvedJavaType;
} catch (CancellationException e) {
throw e;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Error while validating expression '" + expression.getContent() + "' in '" + template.getUri() + "'.", e);
return null;
}
}
use of com.redhat.qute.commons.ResolvedJavaTypeInfo in project quarkus-ls by redhat-developer.
the class QuteProjectRegistry method resolveJavaType.
public CompletableFuture<ResolvedJavaTypeInfo> resolveJavaType(String javaTypeName, String projectUri) {
CompletableFuture<ResolvedJavaTypeInfo> primitiveType = javaPrimitiveTypes.get(javaTypeName);
if (primitiveType != null) {
// It's a primitive type like boolean, double, float, etc
return primitiveType;
}
if (StringUtils.isEmpty(javaTypeName) || StringUtils.isEmpty(projectUri)) {
return RESOLVED_JAVA_CLASSINFO_NULL_FUTURE;
}
QuteProject project = getProject(projectUri);
if (project == null) {
return RESOLVED_JAVA_CLASSINFO_NULL_FUTURE;
}
CompletableFuture<ResolvedJavaTypeInfo> future = project.getResolvedJavaType(javaTypeName);
if (future == null || future.isCancelled() || future.isCompletedExceptionally()) {
QuteResolvedJavaTypeParams params = new QuteResolvedJavaTypeParams(javaTypeName, projectUri);
future = //
getResolvedJavaType(params).thenCompose(c -> {
if (c != null) {
// Update members with the resolved class
c.getFields().forEach(f -> {
f.setJavaType(c);
});
c.getMethods().forEach(m -> {
m.setJavaType(c);
});
// Load extended Java types
if (c.getExtendedTypes() != null) {
List<CompletableFuture<ResolvedJavaTypeInfo>> resolvingExtendedFutures = new ArrayList<>();
for (String extendedType : c.getExtendedTypes()) {
CompletableFuture<ResolvedJavaTypeInfo> extendedFuture = resolveJavaType(extendedType, projectUri);
if (!extendedFuture.isDone()) {
resolvingExtendedFutures.add(extendedFuture);
}
}
if (!resolvingExtendedFutures.isEmpty()) {
CompletableFuture<Void> allFutures = CompletableFuture.allOf(resolvingExtendedFutures.toArray(new CompletableFuture[resolvingExtendedFutures.size()]));
return //
allFutures.thenApply(a -> c);
}
}
}
return CompletableFuture.completedFuture(c);
});
project.registerResolvedJavaType(javaTypeName, future);
}
return future;
}
use of com.redhat.qute.commons.ResolvedJavaTypeInfo in project quarkus-ls by redhat-developer.
the class QuteProjectRegistry method isMatchParameters.
private boolean isMatchParameters(JavaMethodInfo method, List<ResolvedJavaTypeInfo> parameterTypes, String projectUri) {
boolean virtualMethod = method.isVirtual();
if (parameterTypes.size() != (method.getParameters().size() - (virtualMethod ? 1 : 0))) {
return false;
}
for (int i = 0; i < parameterTypes.size(); i++) {
JavaParameterInfo parameterInfo = method.getParameters().get(i + (virtualMethod ? 1 : 0));
ResolvedJavaTypeInfo result = parameterTypes.get(i);
String parameterType = parameterInfo.getType();
if (!isMatchType(result, parameterType, projectUri)) {
return false;
}
}
return true;
}
Aggregations