diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacConverter.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacConverter.java index c442101e22f..55b639b2e13 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacConverter.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacConverter.java @@ -342,13 +342,14 @@ private ImportDeclaration convert(JCImport javac) { void commonSettings(ASTNode res, JCTree javac) { if( javac != null ) { - if (javac.getStartPosition() >= 0) { + int start = javac.getStartPosition(); + if (start >= 0) { int endPos = javac.getEndPosition(this.javacCompilationUnit.endPositions); if( endPos < 0 ) { - endPos = javac.getStartPosition() + javac.toString().length(); + endPos = start + javac.toString().length(); } - int length = endPos - javac.getStartPosition(); - res.setSourceRange(javac.getStartPosition(), Math.max(0, length)); + int length = endPos - start; + res.setSourceRange(start, Math.max(0, length)); } this.domToJavac.put(res, javac); setJavadocForNode(javac, res); @@ -551,7 +552,15 @@ private AbstractTypeDeclaration convertClassDecl(JCClassDecl javacClassDecl, AST } else if (res instanceof RecordDeclaration recordDecl) { for (JCTree node : javacClassDecl.getMembers()) { if (node instanceof JCVariableDecl vd) { - recordDecl.recordComponents().add(convertVariableDeclaration(vd)); + SingleVariableDeclaration vdd = (SingleVariableDeclaration)convertVariableDeclaration(vd); + // Records cannot have modifiers + vdd.modifiers().clear(); + recordDecl.recordComponents().add(vdd); + } else { + ASTNode converted = convertBodyDeclaration(node, res); + if( converted != null ) { + res.bodyDeclarations.add(converted); + } } } } @@ -666,8 +675,8 @@ private String getNodeName(ASTNode node) { } return null; } - - private String getMethodDeclName(JCMethodDecl javac, ASTNode parent) { + + private String getMethodDeclName(JCMethodDecl javac, ASTNode parent, boolean records) { String name = javac.getName().toString(); boolean javacIsConstructor = Objects.equals(javac.getName(), Names.instance(this.context).init); if( javacIsConstructor) { @@ -675,8 +684,16 @@ private String getMethodDeclName(JCMethodDecl javac, ASTNode parent) { String parentName = getNodeName(parent); String tmpString1 = this.rawText.substring(javac.pos); int openParen = tmpString1.indexOf("("); + int openBrack = tmpString1.indexOf("{"); + int endPos = -1; if( openParen != -1 ) { - String methodName = tmpString1.substring(0, openParen).trim(); + endPos = openParen; + } + if( records && openBrack != -1 ) { + endPos = endPos == -1 ? openBrack : Math.min(openBrack, endPos); + } + if( endPos != -1 ) { + String methodName = tmpString1.substring(0, endPos).trim(); if( !methodName.equals(parentName)) { return methodName; } @@ -696,13 +713,22 @@ private MethodDeclaration convertMethodDecl(JCMethodDecl javac, ASTNode parent) } String javacName = javac.getName().toString(); - String methodDeclName = getMethodDeclName(javac, parent); + String methodDeclName = getMethodDeclName(javac, parent, parent instanceof RecordDeclaration); boolean methodDeclNameMatchesInit = Objects.equals(methodDeclName, Names.instance(this.context).init.toString()); boolean javacNameMatchesInit = javacName.equals(""); boolean javacNameMatchesError = javacName.equals(""); boolean javacNameMatchesInitAndMethodNameMatchesTypeName = javacNameMatchesInit && methodDeclName.equals(getNodeName(parent)); boolean isConstructor = methodDeclNameMatchesInit || javacNameMatchesInitAndMethodNameMatchesTypeName; res.setConstructor(isConstructor); + boolean isCompactConstructor = false; + if(isConstructor && parent instanceof RecordDeclaration) { + String postName = this.rawText.substring(javac.pos + methodDeclName.length()).trim(); + String firstChar = postName != null && postName.length() > 0 ? postName.substring(0,1) : null; + isCompactConstructor = ("{".equals(firstChar)); + if( this.ast.apiLevel >= AST.JLS16_INTERNAL) { + res.setCompactConstructor(isCompactConstructor); + } + } boolean malformed = false; if(isConstructor && !javacNameMatchesInitAndMethodNameMatchesTypeName) { malformed = true; @@ -765,7 +791,10 @@ private MethodDeclaration convertMethodDecl(JCMethodDecl javac, ASTNode parent) } } - javac.getParameters().stream().map(this::convertVariableDeclaration).forEach(res.parameters()::add); + if( !isCompactConstructor) { + // Compact constructor does not show the parameters even though javac finds them + javac.getParameters().stream().map(this::convertVariableDeclaration).forEach(res.parameters()::add); + } if( javac.getTypeParameters() != null ) { Iterator i = javac.getTypeParameters().iterator(); @@ -844,7 +873,9 @@ private VariableDeclaration convertVariableDeclaration(JCVariableDecl javac) { if (convertName(javac.getName()) instanceof SimpleName simpleName) { int endPos = javac.getEndPosition(this.javacCompilationUnit.endPositions); int length = simpleName.toString().length(); - simpleName.setSourceRange(endPos - length, length); + if( endPos != -1 ) { + simpleName.setSourceRange(endPos - length, length); + } res.setName(simpleName); } if( this.ast.apiLevel != AST.JLS2_INTERNAL) { diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacTypeBinding.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacTypeBinding.java index 3a107d16e23..d8fd6a66ec2 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacTypeBinding.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacTypeBinding.java @@ -11,6 +11,8 @@ package org.eclipse.jdt.internal.javac.dom; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.stream.StreamSupport; @@ -22,6 +24,7 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.IAnnotationBinding; import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IMethodBinding; @@ -288,7 +291,13 @@ public IMethodBinding[] getDeclaredMethods() { if (this.typeSymbol.members() == null) { return new IMethodBinding[0]; } - return StreamSupport.stream(this.typeSymbol.members().getSymbols().spliterator(), false) + ArrayList l = new ArrayList<>(); + this.typeSymbol.members().getSymbols().forEach(l::add); + // This is very very questionable, but trying to find + // the order of these members in the file has been challenging + Collections.reverse(l); + + return StreamSupport.stream(l.spliterator(), false) .filter(MethodSymbol.class::isInstance) .map(MethodSymbol.class::cast) .map(sym -> this.resolver.bindings.getMethodBinding(sym.type.asMethodType(), sym))