Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -20,6 +20,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

import org.eclipse.core.runtime.CoreException;
Expand All @@ -35,6 +36,8 @@
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.ParameterizedType;
Expand Down Expand Up @@ -82,6 +85,8 @@ public class NewCUProposal extends ChangeCorrectionProposalCore {
private int fTypeKind;
private IJavaElement fTypeContainer; // IType or IPackageFragment
private String fTypeNameWithParameters;
private List<Expression> fArguments;

/**
* Construct a new compilation unit proposal.
*
Expand Down Expand Up @@ -111,6 +116,36 @@ public NewCUProposal(ICompilationUnit cu, Name node, int typeKind, IJavaElement
setDisplayName();
}

/**
* Construct a new compilation unit proposal.
*
* @param cu
* current compilation unit.
* @param node
* {@link Name} corresponding to the compilation unit to be created.
* @param typeKind
* possible values: { K_CLASS, K_INTERFACE, K_ENUM, K_ANNOTATION }
* @param typeContainer
* enclosing {@link IJavaElement} of the target compilation unit, can
* be {@link IType} or {@link IPackageFragment}.
* @param relevance
* the relevance of this proposal
* @param arguments
* the list of {@link Expression} nodes
*/
public NewCUProposal(ICompilationUnit cu, Name node, int typeKind, IJavaElement typeContainer, int relevance, List<Expression> arguments) {
super("", null, relevance); //$NON-NLS-1$
fCompilationUnit = cu;
fNode = node;
fTypeKind = typeKind;
fTypeContainer = typeContainer;
if (fNode != null) {
fTypeNameWithParameters = getTypeName(typeKind, node);
}
fArguments = arguments;
setDisplayName();
}

private void setDisplayName() {
String containerName;
if (fNode != null) {
Expand Down Expand Up @@ -508,7 +543,22 @@ private String constructTypeStub(ICompilationUnit parentCU, String name, int mod
buf.append(name);

if (fTypeKind == K_RECORD) {
buf.append("()");
buf.append("(");
if (fArguments != null && !fArguments.isEmpty()) {
for (int i = 0; i < fArguments.size(); i++) {
if (i > 0) {
buf.append(", "); //$NON-NLS-1$
}
Expression arg = fArguments.get(i);
ITypeBinding typeBinding = arg.resolveTypeBinding();
String typeName = typeBinding != null && !typeBinding.isRecovered()
? typeBinding.getName()
: "Object"; //$NON-NLS-1$
String argName = "arg" + (i + 1); //$NON-NLS-1$
buf.append(typeName).append(' ').append(argName);
}
}
buf.append(")");
}

if (isPermitted) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2024 IBM Corporation and others.
* Copyright (c) 2000, 2026 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
Expand All @@ -24,12 +24,17 @@
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
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 All @@ -40,7 +45,6 @@
import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore;
import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.ls.core.internal.corrections.CorrectionMessages;
import org.eclipse.jdt.internal.ui.text.correction.ReorgCorrectionsBaseSubProcessor;
import org.eclipse.jdt.internal.ui.text.correction.TypeMismatchBaseSubProcessor;
import org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor;
Expand All @@ -58,6 +62,7 @@
import org.eclipse.jdt.internal.ui.text.correction.proposals.ReplaceCorrectionProposalCore;
import org.eclipse.jdt.ls.core.internal.JDTUtils;
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
import org.eclipse.jdt.ls.core.internal.corrections.CorrectionMessages;
import org.eclipse.jdt.ls.core.internal.corrections.ProposalKindWrapper;
import org.eclipse.jdt.ls.core.internal.handlers.CodeActionHandler;
import org.eclipse.jdt.ui.text.java.IInvocationContext;
Expand Down Expand Up @@ -111,13 +116,39 @@ public static void getAnnotationMemberProposals(IInvocationContext context, IPro
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.ui.text.correction.UnresolvedElementsBaseSubProcessor#addNewTypeProposalsInteractiveInnerLoop(org.eclipse.jdt.core.ICompilationUnit, org.eclipse.jdt.core.dom.Name, org.eclipse.jdt.core.IJavaElement, int, int, org.eclipse.jdt.core.dom.Name, java.util.Collection)
*/
@SuppressWarnings("unchecked")
@Override
protected void addNewTypeProposalsInteractiveInnerLoop(ICompilationUnit cu, Name node, IJavaElement enclosing, int rel, int kind, Name refNode, Collection<ProposalKindWrapper> proposals) throws CoreException {
if ((kind & TypeKinds.CLASSES) != 0) {
NewCUProposal proposal = new NewCUProposal(cu, node, NewCUProposal.K_CLASS, enclosing, rel + 3);
proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix));
if (canUseRecord(cu.getJavaProject(), refNode)) {
proposal = new NewCUProposal(cu, node, NewCUProposal.K_RECORD, enclosing, rel + 3);

List<Expression> arguments = null;
ASTNode parent = node.getParent();
if (parent instanceof SimpleType) {
parent = parent.getParent();
}
if (parent instanceof VariableDeclarationStatement stmt) {
for (Object o : stmt.fragments()) {
if (o instanceof VariableDeclarationFragment frag) {
Expression init = frag.getInitializer();
if (init instanceof ClassInstanceCreation creation) {
arguments = creation.arguments();
}
}

}
}
if (parent instanceof ClassInstanceCreation creation) {
arguments = creation.arguments();
}

if (arguments != null && arguments.isEmpty()) {
proposal = new NewCUProposal(cu, node, NewCUProposal.K_RECORD, enclosing, rel + 3);
} else {
proposal = new NewCUProposal(cu, node, NewCUProposal.K_RECORD, enclosing, rel + 3, arguments);
}
proposals.add(CodeActionHandler.wrap(proposal, CodeActionKind.QuickFix));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2013 IBM Corporation and others.
* Copyright (c) 2000, 2026 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
Expand Down Expand Up @@ -1632,4 +1632,34 @@ void foo() {
assertCodeActions(cu, e1);
}

@Test
public void testTypeInStatementCreateRecordWithComponents() throws Exception {
Map<String, String> options17 = new HashMap<>();
JavaModelUtil.setComplianceOptions(options17, JavaCore.VERSION_17);
fJProject1.setOptions(options17);

IPackageFragment pack1 = fSourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf = new StringBuilder();
buf.append("package test1;\n");
buf.append("public class E {\n");
buf.append(" void foo() {\n");
buf.append(" Re1 obj = new Re1(1, \"hello\");\n");
buf.append(" }\n");
buf.append("}\n");
ICompilationUnit cu = pack1.createCompilationUnit("E.java", buf.toString(), false, null);

buf = new StringBuilder();
buf.append("package test1;\n");
buf.append("\n");
buf.append("/**\n");
buf.append(" * Re1\n");
buf.append(" */\n");
buf.append("public record Re1(int arg1, String arg2) {\n");
buf.append("\n");
buf.append("}\n");
Expected e1 = new Expected("Create record 'Re1'", buf.toString());

assertCodeActionExists(cu, e1);
}

}
Loading