Skip to content

Commit

Permalink
Merge branch 'eclipse-jdt:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
carstenartur authored Aug 7, 2024
2 parents 0d4da9f + 1190120 commit e8b0193
Show file tree
Hide file tree
Showing 7 changed files with 482 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.stream.Stream;

import org.eclipse.core.runtime.CoreException;

Expand Down Expand Up @@ -381,12 +382,20 @@ public void collectIncompatibleReturnTypeProposals(IInvocationContext context, I
ICompilationUnit cu= context.getCompilationUnit();
IMethodBinding methodDecl= methodDeclBinding.getMethodDeclaration();
ITypeBinding overriddenReturnType= overridden.getReturnType();
if (! JavaModelUtil.is50OrHigher(context.getCompilationUnit().getJavaProject())) {
overriddenReturnType= overriddenReturnType.getErasure();
// propose erasure
if (decl.typeParameters().isEmpty() || overriddenReturnType.getTypeBounds().length == 0 || Stream.of(overriddenReturnType.getTypeBounds()).allMatch(bound -> bound.getTypeArguments().length == 0)) {
T p1= createChangeIncompatibleReturnTypeProposal(cu, methodDecl, astRoot, overriddenReturnType.getErasure(), false, IProposalRelevance.CHANGE_RETURN_TYPE);
if (p1 != null)
proposals.add(p1);
}

// propose using (and potentially introducing) the type variable
if (overriddenReturnType.isTypeVariable()) {
T p2 = createChangeIncompatibleReturnTypeProposal(cu, methodDecl, astRoot, overriddenReturnType, false, IProposalRelevance.CHANGE_RETURN_TYPE);
if (p2 != null) {
proposals.add(p2);
}
}
T p1= createChangeIncompatibleReturnTypeProposal(cu, methodDecl, astRoot, overriddenReturnType, false, IProposalRelevance.CHANGE_RETURN_TYPE);
if (p1 != null)
proposals.add(p1);

ICompilationUnit targetCu= cu;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ public static String getExecutionEnvironmentCompliance(IExecutionEnvironment exe
if(JavaCore.isJavaSourceVersionSupportedByCompiler(compliance)) {
return compliance;
}
return JavaCore.getFirstJavaSourceVersionSupportedByCompiler();
return JavaCore.getAllJavaSourceVersionsSupportedByCompiler().first();
}
}

Expand Down Expand Up @@ -1192,7 +1192,7 @@ public static String getExecutionEnvironmentCompliance(IExecutionEnvironment exe
} else if (desc.indexOf(JavaCore.VERSION_1_8) != -1) {
return JavaCore.VERSION_1_8;
}
return JavaCore.getFirstJavaSourceVersionSupportedByCompiler();
return JavaCore.getAllJavaSourceVersionsSupportedByCompiler().first();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
Expand Down Expand Up @@ -54,13 +57,17 @@
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.TextElement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeParameter;
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.WildcardType;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
Expand Down Expand Up @@ -273,9 +280,49 @@ protected ASTRewrite getRewrite() throws CoreException {
if (declNode instanceof MethodDeclaration) {
MethodDeclaration methodDecl= (MethodDeclaration) declNode;
Type origReturnType= methodDecl.getReturnType2();

if (fNewType.isTypeVariable()) {
IMethodBinding realMethodBinding= fNewType.getDeclaringMethod();
ITypeBinding[] typeParameters= realMethodBinding.getTypeParameters();

if (!methodDecl.typeParameters().isEmpty()) {
Map<String, String> typeParamNameMap= new HashMap<>();
for (int i = 0; i < methodDecl.typeParameters().size(); i++) {
typeParamNameMap.put(typeParameters[i].getName(), ((List<TypeParameter>) methodDecl.typeParameters()).get(i).getName().toString());
}
String existingTypeVarIdent= typeParamNameMap.get(fNewType.getName());
type= ast.newSimpleType(ast.newSimpleName(existingTypeVarIdent));
} else {
// add type parameters as they appear in the parent method
// notably, if you add the type variables, you must add ALL of them.
// eg. if you have <T, U> T myMethod(Class<U> clazz)
// you cannot override it with <T> T myMethod(Class<String> clazz)
ListRewrite typeParameterRewrite= rewrite.getListRewrite(methodDecl, MethodDeclaration.TYPE_PARAMETERS_PROPERTY);
for (ITypeBinding parameter : typeParameters) {
TypeParameter newTypeParameter= ast.newTypeParameter();
SimpleName newTypeParameterName= ast.newSimpleName(parameter.getName());
newTypeParameter.setName(newTypeParameterName);
Stream.of(parameter.getTypeBounds()) //
.forEach(bound -> {
newTypeParameter.typeBounds().add(getTypeNodeFromBinding(bound, ast, imports, context));
});
typeParameterRewrite.insertLast(newTypeParameter, null);
}

// Update the parameter types to match that of the resolved method.
// Some of the existing parameter types may be raw instead of containing the expected type parameters.
// Without inserting the type parameters in these cases, the signature will no longer match the overridden type.
for (int i = 0 ; i < methodDecl.parameters().size(); i++) {
SingleVariableDeclaration svd= (SingleVariableDeclaration)methodDecl.parameters().get(i);
rewrite.set(svd, SingleVariableDeclaration.TYPE_PROPERTY, getTypeNodeFromBinding(realMethodBinding.getParameterTypes()[i], ast, imports, context), null);
}
}
}

rewrite.set(methodDecl, MethodDeclaration.RETURN_TYPE2_PROPERTY, type, null);
DimensionRewrite.removeAllChildren(methodDecl, MethodDeclaration.EXTRA_DIMENSIONS2_PROPERTY, rewrite, null);
TypeAnnotationRewrite.removePureTypeAnnotations(methodDecl, MethodDeclaration.MODIFIERS2_PROPERTY, rewrite, null);

// add javadoc tag
Javadoc javadoc= methodDecl.getJavadoc();
if (javadoc != null && origReturnType != null && origReturnType.isPrimitiveType()
Expand Down Expand Up @@ -526,4 +573,43 @@ private void handledInferredParametrizedType(ASTNode node, ASTNode declaringNode
}
}

private Type getTypeNodeFromBinding(ITypeBinding typeBinding, AST ast, ImportRewrite importRewrite, ImportRewriteContext context) {

if (typeBinding.isWildcardType()) {
WildcardType wildcardType = ast.newWildcardType();
ITypeBinding bound = typeBinding.getBound();
if (bound != null) {
Type boundNode = getTypeNodeFromBinding(bound, ast, importRewrite, context);
wildcardType.setBound(boundNode);
wildcardType.setUpperBound(typeBinding.isUpperbound());
}
return wildcardType;
}

if (typeBinding.isArray()) {
Type elementTypeNode = getTypeNodeFromBinding(typeBinding.getElementType(), ast, importRewrite, context);
return ast.newArrayType(elementTypeNode, typeBinding.getDimensions());
}

if (typeBinding.isTypeVariable()) {
return ast.newSimpleType(ast.newSimpleName(typeBinding.getName()));
}

// import the simple/parameterized type if needed
importRewrite.addImport(typeBinding, ast, context, fTypeLocation);

// create the simple/parameterized
SimpleName simpleName = ast.newSimpleName(typeBinding.getErasure().getName());
SimpleType simpleType = ast.newSimpleType(simpleName);
if (typeBinding.isParameterizedType()) {
ParameterizedType parameterizedType = ast.newParameterizedType(simpleType);
for (ITypeBinding argument : typeBinding.getTypeArguments()) {
Type typeArgument = getTypeNodeFromBinding(argument, ast, importRewrite, context);
parameterizedType.typeArguments().add(typeArgument);
}
return parameterizedType;
}
return simpleType;
}

}
Loading

0 comments on commit e8b0193

Please sign in to comment.