use of com.redhat.qute.commons.JavaMethodInfo 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.JavaMethodInfo in project quarkus-ls by redhat-developer.
the class QuteProjectRegistry method findMethod.
/**
* Returns the member method retrieved by the given property or method name and
* null otherwise.
*
* @param baseType the Java base type.
* @param propertyOrMethodName property or method name
*
* @return the member field retrieved by the given property or method name and
* null otherwise.
*/
protected static JavaMethodInfo findMethod(ResolvedJavaTypeInfo baseType, String propertyOrMethodName) {
List<JavaMethodInfo> methods = baseType.getMethods();
if (methods == null || methods.isEmpty() || isEmpty(propertyOrMethodName)) {
return null;
}
String getterMethodName = computeGetterName(propertyOrMethodName);
String booleanGetterName = computeBooleanGetterName(propertyOrMethodName);
for (JavaMethodInfo method : methods) {
if (isMatchMethod(method, propertyOrMethodName, getterMethodName, booleanGetterName)) {
return method;
}
}
return null;
}
use of com.redhat.qute.commons.JavaMethodInfo in project quarkus-ls by redhat-developer.
the class MockQuteProject method registerMethod.
protected static JavaMemberInfo registerMethod(String methodSignature, ResolvedJavaTypeInfo resolvedType) {
JavaMethodInfo member = new JavaMethodInfo();
member.setSignature(methodSignature);
resolvedType.getMethods().add(member);
return member;
}
use of com.redhat.qute.commons.JavaMethodInfo in project quarkus-ls by redhat-developer.
the class DocumentationUtils method createDocumentation.
private static StringBuilder createDocumentation(JavaMemberInfo member, ResolvedJavaTypeInfo iterableOfResolvedType, boolean markdown) {
StringBuilder documentation = new StringBuilder();
// Title
if (markdown) {
documentation.append("```java");
documentation.append(System.lineSeparator());
}
documentation.append(getSimpleType(member.resolveJavaElementType(iterableOfResolvedType)));
documentation.append(" ");
String sourceType = member.getSourceType();
if (sourceType != null) {
documentation.append(sourceType);
documentation.append(".");
}
documentation.append(member.getName());
if (member.getJavaElementKind() == JavaElementKind.METHOD) {
documentation.append('(');
JavaMethodInfo methodInfo = (JavaMethodInfo) member;
boolean virtualMethod = methodInfo.isVirtual();
List<JavaParameterInfo> parameters = methodInfo.getParameters();
int start = virtualMethod ? 1 : 0;
for (int i = start; i < parameters.size(); i++) {
JavaParameterInfo parameter = parameters.get(i);
String type = parameter.getJavaElementSimpleType();
String name = parameter.getName();
if (i > start) {
documentation.append(", ");
}
documentation.append(type);
documentation.append(' ');
documentation.append(name);
}
documentation.append(')');
}
if (markdown) {
documentation.append(System.lineSeparator());
documentation.append("```");
}
if (member.getDocumentation() != null) {
documentation.append(System.lineSeparator());
documentation.append(member.getDocumentation());
}
return documentation;
}
use of com.redhat.qute.commons.JavaMethodInfo 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;
}
Aggregations