diff --git a/org.eclipse.xtend.core/src/org/eclipse/xtend/core/validation/XtendJvmGenericTypeValidator.java b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/validation/XtendJvmGenericTypeValidator.java index db80b74cfda..69856315329 100644 --- a/org.eclipse.xtend.core/src/org/eclipse/xtend/core/validation/XtendJvmGenericTypeValidator.java +++ b/org.eclipse.xtend.core/src/org/eclipse/xtend/core/validation/XtendJvmGenericTypeValidator.java @@ -18,6 +18,7 @@ import java.util.Set; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.xtend.core.xtend.XtendField; import org.eclipse.xtend.core.xtend.XtendFunction; import org.eclipse.xtend.core.xtend.XtendMember; @@ -130,4 +131,12 @@ protected void doCheckFunctionOverrides(EObject sourceElement, IResolvedOperatio } } } + + @Override + protected EStructuralFeature returnTypeFeature(EObject member, IResolvedOperation resolved) { + var returnTypeFeature = super.returnTypeFeature(member, resolved); + if (returnTypeFeature == null && member instanceof XtendField) // e.g., for an active annotation like @Accessors + return XTEND_FIELD__TYPE; + return returnTypeFeature; + } } diff --git a/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/validation/JvmGenericTypeValidator.java b/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/validation/JvmGenericTypeValidator.java index 3a4ef100038..ff6ad70104b 100644 --- a/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/validation/JvmGenericTypeValidator.java +++ b/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/validation/JvmGenericTypeValidator.java @@ -803,42 +803,41 @@ protected void doCheckFunctionOverrides(EObject sourceElement, IResolvedOperatio protected void createExceptionMismatchError(IResolvedOperation operation, EObject sourceElement, List exceptionMismatch) { List exceptions = operation.getIllegallyDeclaredExceptions(); - StringBuilder message = new StringBuilder(100); - message.append("The declared exception"); - if (exceptions.size() > 1) { - message.append('s'); - } - message.append(' '); - for(int i = 0; i < exceptions.size(); i++) { - if (i != 0) { - if (i != exceptions.size() - 1) - message.append(", "); - else - message.append(" and "); - } - message.append(exceptions.get(i).getHumanReadableName()); - } - if (exceptions.size() > 1) { - message.append(" are"); - } else { - message.append(" is"); - } - message.append(" not compatible with throws clause in "); - for(int i = 0; i < exceptionMismatch.size(); i++) { + + var suffixMessage = new StringBuilder(); + suffixMessage.append(" not compatible with the throws clause in "); + + for (int i = 0; i < exceptionMismatch.size(); i++) { if (i != 0) { if (i != exceptionMismatch.size() - 1) - message.append(", "); + suffixMessage.append(", "); else - message.append(" and "); + suffixMessage.append(" and "); } IResolvedOperation resolvedOperation = exceptionMismatch.get(i); - message.append(getDeclaratorName(resolvedOperation)); - message.append('.'); - message.append(exceptionMismatch.get(i).getSimpleSignature()); + suffixMessage.append(getDeclaratorName(resolvedOperation)); + suffixMessage.append('.'); + suffixMessage.append(exceptionMismatch.get(i).getSimpleSignature()); + } + + List resolvedExceptions = operation.getResolvedExceptions(); + JvmOperation sourceOperation = operation.getDeclaration(); + for (LightweightTypeReference exception : exceptions) { + var message = new StringBuilder(100); + message.append("The declared exception "); + message.append(exception.getHumanReadableName()); + message.append(" is"); + message.append(suffixMessage); + var exceptionIndex = resolvedExceptions.indexOf(exception); + JvmTypeReference exceptionType = sourceOperation.getExceptions().get(exceptionIndex); + EObject sourceExceptionType = associations.getPrimarySourceElement(exceptionType); + EStructuralFeature feature = null; + if (sourceExceptionType != null) + feature = sourceExceptionType.eContainingFeature(); + error(message.toString(), + sourceElement, feature, + exceptionIndex, INCOMPATIBLE_THROWS_CLAUSE); } - // TODO: maybe put an error on each mismatching exception? - // TODO: currently we mark the first exception as in Xtend - error(message.toString(), sourceElement, exceptionsFeature(sourceElement, operation), INCOMPATIBLE_THROWS_CLAUSE); } protected String typeLabel(JvmExecutable executable) { @@ -867,21 +866,12 @@ protected EStructuralFeature returnTypeFeature(EObject member, IResolvedOperatio JvmOperation operation = resolved.getDeclaration(); JvmTypeReference returnType = operation.getReturnType(); EObject sourceReturnType = associations.getPrimarySourceElement(returnType); + // it can be null in Xtend due to a field with @Accessors active annotation if (sourceReturnType != null) return sourceReturnType.eContainingFeature(); return null; } - protected EStructuralFeature exceptionsFeature(EObject member, IResolvedOperation resolved) { - // This mimics the current Xtend that marks the first exception - JvmOperation operation = resolved.getDeclaration(); - JvmTypeReference exceptionType = operation.getExceptions().get(0); - EObject sourceExceptionType = associations.getPrimarySourceElement(exceptionType); - if (sourceExceptionType != null) - return sourceExceptionType.eContainingFeature(); - return null; - } - protected GeneratorConfig getGeneratorConfig(EObject element) { GeneratorConfig result = (GeneratorConfig) getContext().get(GeneratorConfig.class); if (result == null) {