Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xtend: put an error marker on each incompatible exception in overridden method #2913

Merged
merged 4 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -514,15 +514,24 @@ public void testClassMustBeAbstract_06() throws Exception {
}

/**
* Two incompatible exceptions; the marker is on the first one
* Three incompatible exceptions from different supertypes;
* the marker is set on the offending exception
*/
@Test public void testIncompatibleThrowsClause_06() throws Exception {
var source = "class Foo extends test.ExceptionThrowing { override nullPointerException() throws java.io.IOException, java.io.FileNotFoundException {} }";
var source = "class Foo extends test.ExceptionThrowing implements test.ExceptionThrowingInterface, test.ExceptionThrowingInterface2 {"
+ "override nullPointerException() throws NullPointerException, java.io.IOException, java.io.FileNotFoundException {} "
+ "}";
XtendClass xtendClass = clazz(source);
var expectedSuffix = " is not compatible with throws clause in "
LorenzoBettini marked this conversation as resolved.
Show resolved Hide resolved
+ "ExceptionThrowing.nullPointerException(), ExceptionThrowingInterface.nullPointerException() and ExceptionThrowingInterface2.nullPointerException()";
helper.assertError(xtendClass.getMembers().get(0), XTEND_FUNCTION, INCOMPATIBLE_THROWS_CLAUSE,
source.indexOf("java.io.IOException"), "java.io.IOException".length(),
"declared exceptions", "IOException", "FileNotFoundException",
"are not", "compatible", "throws", "clause");
"declared exception IOException",
expectedSuffix);
helper.assertError(xtendClass.getMembers().get(0), XTEND_FUNCTION, INCOMPATIBLE_THROWS_CLAUSE,
source.indexOf("java.io.FileNotFoundException"), "java.io.FileNotFoundException".length(),
"declared exception FileNotFoundException",
expectedSuffix);
}

@Test public void testCompatibleThrowsClause() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*******************************************************************************
* Copyright (c) 2024 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package test;

/**
* @author Lorenzo Bettini - Initial contribution and API
*/
interface ExceptionThrowingInterface2 {

void nullPointerException() throws NullPointerException ;

}
Original file line number Diff line number Diff line change
Expand Up @@ -872,14 +872,7 @@ else if(member instanceof XtendField)
else
return null;
}

protected EStructuralFeature exceptionsFeature(EObject member) {
if (member instanceof XtendExecutable)
return XTEND_EXECUTABLE__EXCEPTIONS;
else
return null;
}


protected EStructuralFeature returnTypeFeature(EObject member) {
if (member instanceof XtendFunction)
return XTEND_FUNCTION__RETURN_TYPE;
Expand Down Expand Up @@ -1155,40 +1148,35 @@ protected String getDeclaratorName(IResolvedOperation resolved) {
protected void createExceptionMismatchError(IResolvedOperation operation, EObject sourceElement,
List<IResolvedOperation> exceptionMismatch) {
List<LightweightTypeReference> 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 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<LightweightTypeReference> resolvedExceptions = operation.getResolvedExceptions();
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);
error(message.toString(),
sourceElement, XTEND_EXECUTABLE__EXCEPTIONS,
exceptionIndex, INCOMPATIBLE_THROWS_CLAUSE);
}
error(message.toString(), sourceElement, exceptionsFeature(sourceElement), INCOMPATIBLE_THROWS_CLAUSE);
}

protected EObject findPrimarySourceElement(IResolvedOperation operation) {
Expand Down