use of com.redhat.qute.commons.InvalidMethodReason 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.InvalidMethodReason in project quarkus-ls by redhat-developer.
the class QuteSupportForTemplate method getResolvedJavaType.
/**
* Returns the resolved type (fields and methods) for the given Java type.
*
* @param params the Java type to resolve.
* @param utils the JDT LS utility.
* @param monitor the progress monitor.
*
* @return the resolved type (fields and methods) for the given Java type.
*
* @throws CoreException
*/
public ResolvedJavaTypeInfo getResolvedJavaType(QuteResolvedJavaTypeParams params, IJDTUtils utils, IProgressMonitor monitor) throws CoreException {
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
String projectUri = params.getProjectUri();
IJavaProject javaProject = getJavaProjectFromProjectUri(projectUri);
if (javaProject == null) {
return null;
}
String typeName = params.getClassName();
int index = typeName.indexOf('<');
if (index != -1) {
// ex : java.util.List<org.acme.Item>
String iterableClassName = typeName.substring(0, index);
IType iterableType = findType(iterableClassName, javaProject, monitor);
if (iterableType == null) {
return null;
}
boolean iterable = isIterable(iterableType, monitor);
if (!iterable) {
return null;
}
String iterableOf = typeName.substring(index + 1, typeName.length() - 1);
iterableOf = getFullQualifiedName(monitor, javaProject, iterableOf);
iterableClassName = iterableType.getFullyQualifiedName('.');
typeName = iterableClassName + "<" + iterableOf + ">";
return createIterableType(typeName, iterableClassName, iterableOf);
} else if (typeName.endsWith("[]")) {
// ex : org.acme.Item[]
String iterableOf = typeName.substring(0, typeName.length() - 2);
IType iterableOfType = findType(iterableOf, javaProject, monitor);
if (iterableOfType == null) {
return null;
}
iterableOf = getFullQualifiedName(monitor, javaProject, iterableOf);
typeName = iterableOf + "[]";
return createIterableType(typeName, null, iterableOf);
}
// ex : org.acme.Item, java.util.List, ...
IType type = findType(typeName, javaProject, monitor);
if (type == null) {
return null;
}
ITypeResolver typeResolver = createTypeResolver(type);
// 1) Collect fields
List<JavaFieldInfo> fieldsInfo = new ArrayList<>();
// Standard fields
IField[] fields = type.getFields();
for (IField field : fields) {
if (isValidField(field)) {
// Only public fields are available
JavaFieldInfo info = new JavaFieldInfo();
info.setSignature(typeResolver.resolveFieldSignature(field));
fieldsInfo.add(info);
}
}
// Record fields
if (type.isRecord()) {
for (IField field : type.getRecordComponents()) {
// All record components are valid
JavaFieldInfo info = new JavaFieldInfo();
info.setSignature(typeResolver.resolveFieldSignature(field));
fieldsInfo.add(info);
}
}
// 2) Collect methods
List<JavaMethodInfo> methodsInfo = new ArrayList<>();
Map<String, InvalidMethodReason> invalidMethods = new HashMap<>();
IMethod[] methods = type.getMethods();
for (IMethod method : methods) {
if (isValidMethod(method, type.isInterface())) {
try {
InvalidMethodReason invalid = getValidMethodForQute(method, typeName);
if (invalid != null) {
invalidMethods.put(method.getElementName(), invalid);
} else {
JavaMethodInfo info = new JavaMethodInfo();
info.setSignature(typeResolver.resolveMethodSignature(method));
methodsInfo.add(info);
}
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Error while getting method signature of '" + method.getElementName() + "'.", e);
}
}
}
// Collect type extensions
List<String> extendedTypes = null;
if (type.isInterface()) {
IType[] interfaces = findImplementedInterfaces(type, monitor);
if (interfaces != null && interfaces.length > 0) {
extendedTypes = //
Stream.of(interfaces).map(//
interfaceType -> interfaceType.getFullyQualifiedName()).collect(Collectors.toList());
}
} else {
// ex : String implements CharSequence, ....
ITypeHierarchy typeHierarchy = type.newSupertypeHierarchy(monitor);
IType[] allSuperTypes = typeHierarchy.getSupertypes(type);
extendedTypes = //
Stream.of(allSuperTypes).map(//
superType -> superType.getFullyQualifiedName()).collect(Collectors.toList());
}
if (extendedTypes != null) {
extendedTypes.remove(typeName);
}
ResolvedJavaTypeInfo resolvedType = new ResolvedJavaTypeInfo();
String typeSignature = AbstractTypeResolver.resolveJavaTypeSignature(type);
resolvedType.setSignature(typeSignature);
resolvedType.setFields(fieldsInfo);
resolvedType.setMethods(methodsInfo);
resolvedType.setInvalidMethods(invalidMethods);
resolvedType.setExtendedTypes(extendedTypes);
return resolvedType;
}
use of com.redhat.qute.commons.InvalidMethodReason in project quarkus-ls by redhat-developer.
the class TemplateGetResolvedJavaTypeTest method list.
@Test
public void list() throws Exception {
loadMavenProject(QuteMavenProjectName.qute_quickstart);
QuteResolvedJavaTypeParams params = new QuteResolvedJavaTypeParams("java.util.List", QuteMavenProjectName.qute_quickstart);
ResolvedJavaTypeInfo result = QuteSupportForTemplate.getInstance().getResolvedJavaType(params, getJDTUtils(), new NullProgressMonitor());
Assert.assertEquals("java.util.List<E>", result.getSignature());
Assert.assertTrue(result.isIterable());
Assert.assertEquals("java.util.List", result.getIterableType());
Assert.assertEquals("java.lang.Object", result.getIterableOf());
// Invalid method void clear();
JavaMethodInfo clearMethod = findMethod(result, "clear");
Assert.assertNull(clearMethod);
InvalidMethodReason reason = result.getInvalidMethodReason("clear");
Assert.assertEquals(InvalidMethodReason.VoidReturn, reason);
params = new QuteResolvedJavaTypeParams("List", QuteMavenProjectName.qute_quickstart);
result = QuteSupportForTemplate.getInstance().getResolvedJavaType(params, getJDTUtils(), new NullProgressMonitor());
Assert.assertNull(result);
params = new QuteResolvedJavaTypeParams("List<String>", QuteMavenProjectName.qute_quickstart);
Assert.assertNull(result);
params = new QuteResolvedJavaTypeParams("List<java.lang.String>", QuteMavenProjectName.qute_quickstart);
result = QuteSupportForTemplate.getInstance().getResolvedJavaType(params, getJDTUtils(), new NullProgressMonitor());
Assert.assertNull(result);
params = new QuteResolvedJavaTypeParams("java.util.List<java.lang.String>", QuteMavenProjectName.qute_quickstart);
result = QuteSupportForTemplate.getInstance().getResolvedJavaType(params, getJDTUtils(), new NullProgressMonitor());
Assert.assertEquals("java.util.List<java.lang.String>", result.getSignature());
Assert.assertTrue(result.isIterable());
Assert.assertEquals("java.util.List", result.getIterableType());
Assert.assertEquals("java.lang.String", result.getIterableOf());
}
use of com.redhat.qute.commons.InvalidMethodReason in project quarkus-ls by redhat-developer.
the class TemplateGetResolvedJavaTypeTest method item.
@Test
public void item() throws Exception {
loadMavenProject(QuteMavenProjectName.qute_quickstart);
QuteResolvedJavaTypeParams params = new QuteResolvedJavaTypeParams("org.acme.qute.Item", QuteMavenProjectName.qute_quickstart);
ResolvedJavaTypeInfo result = QuteSupportForTemplate.getInstance().getResolvedJavaType(params, getJDTUtils(), new NullProgressMonitor());
Assert.assertNotNull(result);
Assert.assertEquals("org.acme.qute.Item", result.getSignature());
Assert.assertFalse(result.isIterable());
// Fields
Assert.assertNotNull(result.getFields());
Assert.assertEquals(2, result.getFields().size());
Assert.assertEquals("name", result.getFields().get(0).getName());
Assert.assertEquals("java.lang.String", result.getFields().get(0).getType());
Assert.assertEquals("price", result.getFields().get(1).getName());
Assert.assertEquals("java.math.BigDecimal", result.getFields().get(1).getType());
// Methods
Assert.assertNotNull(result.getMethods());
Assert.assertEquals(1, result.getMethods().size());
Assert.assertEquals("getDerivedItems() : org.acme.qute.Item[]", result.getMethods().get(0).getSignature());
// Invalid methods(static method)
JavaMethodInfo discountedPriceMethod = findMethod(result, "staticMethod");
Assert.assertNull(discountedPriceMethod);
InvalidMethodReason reason = result.getInvalidMethodReason("staticMethod");
Assert.assertEquals(InvalidMethodReason.Static, reason);
}
use of com.redhat.qute.commons.InvalidMethodReason in project quarkus-ls by redhat-developer.
the class TemplateGetResolvedJavaTypeTest method object.
@Test
public void object() throws Exception {
loadMavenProject(QuteMavenProjectName.qute_quickstart);
QuteResolvedJavaTypeParams params = new QuteResolvedJavaTypeParams("java.lang.Object", QuteMavenProjectName.qute_quickstart);
ResolvedJavaTypeInfo result = QuteSupportForTemplate.getInstance().getResolvedJavaType(params, getJDTUtils(), new NullProgressMonitor());
Assert.assertNotNull(result);
Assert.assertEquals("java.lang.Object", result.getSignature());
Assert.assertFalse(result.isIterable());
// None valid methods
Assert.assertNotNull(result.getMethods());
Assert.assertTrue(result.getMethods().isEmpty());
// Invalid method codePointAt(int index)
JavaMethodInfo waitMethod = findMethod(result, "wait");
Assert.assertNull(waitMethod);
InvalidMethodReason reason = result.getInvalidMethodReason("wait");
Assert.assertEquals(InvalidMethodReason.FromObject, reason);
}
Aggregations